notas - manejo de archivos binarios c#
Ordenando archivos binarios gigantescos con C# (4)
Tengo un archivo grande de aproximadamente 400 GB de tamaño. Generado diariamente por un sistema cerrado externo. Es un archivo binario con el siguiente formato:
byte[8]byte[4]byte[n]
Donde n es igual al valor int32 del byte [4].
Este archivo no tiene delimitadores y para leer todo el archivo, simplemente repetiría hasta EOF. Con cada "elemento" representado como byte [8] byte [4] byte [n].
El archivo se ve como
byte[8]byte[4]byte[n]byte[8]byte[4]byte[n]...EOF
byte [8] es un número de 64 bits que representa un período de tiempo representado por .NET Ticks. Necesito ordenar este archivo pero parece que no puedo encontrar la forma más rápida de hacerlo.
Actualmente, cargo los Ticks en una estructura y las posiciones de inicio y fin de byte [n] y leo hasta el final del archivo. Después de esto, clasifico la Lista en memoria por la propiedad Ticks y luego abro un BinaryReader y busco cada posición en orden Ticks, leo el valor byte [n] y escribo en un archivo externo.
Al final del proceso, termino con un archivo binario ordenado, pero toma PARA SIEMPRE. Estoy usando C # .NET y un servidor bastante pesado, pero el disco IO parece ser un problema.
Especificaciones del servidor:
- 2x 2.6 GHz Intel Xeon (Hex-Core con HT) (24 hilos)
- 32 GB de RAM
- 500GB RAID 1 + 0
- 2TB RAID 5
He buscado en Internet y solo puedo encontrar ejemplos donde un archivo enorme es de 1GB (me hace reír entre dientes).
¿Alguien tiene algún consejo?
Si puedes aprender Erlang o Go, podrían ser muy potentes y escalar extremadamente bien, ya que tienes 24 hilos. Utilizar Async I / O. Fusionar Ordenar Y como tiene 32 GB de RAM, intente cargar todo lo que pueda en la memoria RAM y ordene allí y luego vuelva a escribir en el disco.
Una forma excelente de acelerar este tipo de acceso a archivos es hacer un mapa de memoria de todo el archivo en el espacio de direcciones y dejar que el sistema operativo se encargue de leer los bits del archivo que necesita. Haga lo mismo que está haciendo en este momento, excepto leer de memoria en lugar de usar un BinaryReader
/ seek / read.
Tienes mucha memoria principal, por lo que debería proporcionar un rendimiento bastante bueno (siempre que uses un sistema operativo de 64 bits).
Usa el tipo de combinación. Está en línea y se paraleliza bien.
Haría esto en varios pases. En la primera pasada, crearía una lista de tics, luego los distribuiría en forma pareja en muchos (¿cientos?) Cubos. Si sabe de antemano que las garrapatas están distribuidas uniformemente, puede omitir este pase inicial. En una segunda pasada, dividiría los registros en estos pocos cientos de archivos separados de aproximadamente el mismo tamaño (estos archivos mucho más pequeños representan grupos de ticks en el orden que desee). Luego ordenaría cada archivo por separado en la memoria. Luego concatenar los archivos.
Es algo similar al hashsort (creo).