2010-01-08 7 views
6

He estado tratando de encontrar la forma más rápida de codificar una rutina de copia de archivos para copiar un archivo grande en un hardware RAID 5.¿Mejora la velocidad de escritura para la copia de archivos de alta velocidad?

El tamaño promedio del archivo es de alrededor de 2 GB.

Hay 2 ventanas (ambos ejecutan win2k3). El primer cuadro es la fuente, donde se encuentra el archivo grande. Y la segunda caja tiene un almacenamiento RAID 5.

http://blogs.technet.com/askperf/archive/2007/05/08/slow-large-file-copy-issues.aspx

El enlace anterior explica claramente por qué copiar ventanas, robocopy y otras utilidades de copia común sufren en el rendimiento de escritura. Por lo tanto, he escrito un programa C/C++ que utiliza CreateFile, ReadFile & WriteFile API's con NO_BUFFERING & WRITE_THROUGH flags. El programa simula ESEUTIL.exe, en el sentido de que usa 2 hilos, uno para leer y otro para escribir. El hilo del lector lee 256 KB de la fuente y llena un búfer. Una vez que se llenan 16 de esos bloques de 256 KB, el hilo del escritor escribe los contenidos en el búfer en el archivo de destino. Como puede ver, el hilo del escritor escribe 8 MB de datos en 1 foto. El programa asigna 32 bloques de 8MB ... por lo tanto, la escritura y la lectura pueden ocurrir en paralelo. Los detalles de ESEUtil.exe se pueden encontrar en el enlace de arriba. Nota: Me ocupo de los problemas de alineación de datos cuando utilizo NO_BUFFERING.

Utilicé herramientas de marcación de bancos como ATTO y descubrí que nuestro hardware RAID 5 tiene una velocidad de escritura de 44MB por segundo cuando se escriben fragmentos de datos de 8MB. Que es alrededor de 2.57 GB por minuto.

Pero mi programa solo puede lograr 1,4 GB por minuto.

¿Alguien puede ayudarme a identificar cuál es el problema? ¿Hay otros API más rápidos que CreateFile, ReadFile, WriteFile disponibles?

+0

Es posible que desee publicar algún código para convertirlo en una pregunta de programación; de lo contrario, es probable que se mueva a serverfault.com. – RickNZ

+0

Espera, 44MB por segundo? ¿No es ese el tipo de rendimiento sostenido que se supone que debes obtener para un solo disco hoy en día? –

+1

@Pascal: RAID 5 no está optimizado para la velocidad de escritura. Me sorprende que incluso obtengas 44 MB/s. Me esperaba más bajo. – jalf

Respuesta

0

¿Qué tan rápido puede leer el archivo fuente si no escribe el destino?

¿El archivo fuente está fragmentado? Las lecturas fragmentadas pueden ser un orden de magnitud más lentas que las lecturas contiguas. Puede utilizar la utilidad "contig" para que sea contigua:

http://technet.microsoft.com/en-us/sysinternals/bb897428.aspx

¿Qué tan rápido es la red que conecta las dos máquinas?

¿Ha intentado solo escribir datos ficticios, sin leerlo primero, como lo hace ATTO?

¿Tiene más de una solicitud de lectura o escritura en vuelo a la vez?

¿Cuál es el tamaño de franja de su matriz RAID-5? Escribir una raya completa a la vez es la forma más rápida de escribir en RAID-5.

0

Solo recuerde que un disco duro almacena los datos provenientes de los platos y va a los platos. La mayoría de las unidades de disco intentarán optimizar las solicitudes de lectura para mantener los platos giratorios y minimizar el movimiento del cabezal. Las unidades intentan absorber la mayor cantidad de datos del host antes de escribir en los platos para que el host pueda desconectarse lo antes posible.

Su rendimiento también depende del tráfico del bus de E/S en la PC, así como del tráfico entre el disco y el host. Hay otros factores alternativos a considerar, como las tareas del sistema y los programas que se ejecutan "al mismo tiempo". Es posible que no pueda alcanzar el rendimiento exacto como herramienta de medición. Y recuerde que estos tiempos tienen un factor de error debido a los gastos generales mencionados anteriormente.

Si su plataforma tiene controladores DMA, intente utilizarlos.

0

Si la velocidad de escritura es tan importante, ¿por qué no considerar RAID 0 para la configuración de su hardware?

  • el cliente quiere RAID 5.
  • preferidos sobre RAID 0 debido a una mejor tolerancia a fallos.
  • El cliente está satisfecho con lo que RAID 5 puede ofrecer. La pregunta aquí es una evaluación comparativa del hardware que usa ATTO muestra una velocidad de escritura de 2.57 GB por minuto (8MB escritura de fragmentos), ¿por qué no se puede lograr una herramienta de copia cerca de ella? Algo así como 2 GB por min es lo que estamos viendo. Hasta ahora, hemos logrado solo ~ 1.5 GB por minuto.
0

La forma correcta de hacerlo es con E/S totalmente asféricas sin buffer. Querrá emitir varias E/S para mantener activa la cola. Esto permite que el sistema de archivos, el controlador y el subsistema Raid-5 gestionen mejor las E/S.

También puede abrir varios archivos y emitir lecturas y avisos a varios archivos.

NOTA! La cantidad óptima de E/S pendientes y la forma de intercalar las lecturas y escrituras dependerá en gran medida del propio subsistema de almacenamiento. Su programa deberá estar altamente parametrizado para que pueda sintonizarlo.

Nota - Creo que Robocopy se ha mejorado, ¿lo has probado? I

+0

Uno de los objetivos es minimizar el movimiento de la cabeza del disco. Si abre varios archivos o tiene solicitudes de E/S no secuenciales en vuelo, las búsquedas de cabezales de disco pueden hacer que el rendimiento de E/S caiga en un orden de magnitud o más. – RickNZ

+1

En realidad eso no es cierto en absoluto. La apertura de varios archivos primero saca esa E/S del camino. también permite que el sistema de archivos cargue las entidades de directorio de manera más eficiente. En general, el sistema operativo funciona mejor cuando tiene una cola de solicitudes de E/S para trabajar. – Foredecker

6

Debe utilizar async IO para obtener el mejor rendimiento. Es abrir el archivo con FILE_FLAG_OVERLAPPED y usar el argumento LPOVERLAPPED de WriteFile. Puede o no obtener un mejor rendimiento con FILE_FLAG_NO_BUFFERING. Tendrás que probar para ver.

FILE_FLAG_NO_BUFFERING generalmente le dará velocidades más constantes y un mejor comportamiento de transmisión, y evita contaminar su caché de disco con datos que puede que no necesite nuevamente, pero no es necesariamente más rápido en general.

También debe probar para ver cuál es el mejor tamaño para cada bloque de IO. En mi experiencia Hay una gran diferencia de rendimiento entre copiar un archivo de 4k a la vez y copiarlo de 1Mb a la vez.

En mis pruebas pasadas de esto (hace algunos años) encontré que los tamaños de bloques inferiores a 64kB estaban dominados por sobrecarga, y el rendimiento total continuaba mejorando con tamaños de bloques mayores de hasta aproximadamente 512KB. No me sorprendería que con las unidades de disco de hoy en día necesitaras usar tamaños de bloques mayores de 1MB para obtener el máximo rendimiento.

Los números que está utilizando actualmente parecen ser razonables, pero pueden no ser óptimos. También estoy bastante seguro de que FILE_FLAG_WRITE_THROUGH impide el uso de la memoria caché en disco y, por lo tanto, le costará un poco de rendimiento.

También debe tener en cuenta que copiar archivos utilizando CreateFile/WriteFile no copiará los metadatos, como las marcas de tiempo o las secuencias de datos alternativas en NTFS. Tendrá que lidiar con estas cosas por su cuenta.

En realidad reemplazar CopyFile con su propio código es bastante trabajo.

Adición:

Probablemente debería mencionar que cuando he intentado esto con el software RAID 0 en Windows NT 3.0 (hace unos 10 años). La velocidad era MUY sensible a la alineación en la memoria de los búferes. Resultó que en ese momento, los controladores SCSI tenían que usar un algoritmo especial para hacer DMA desde una lista de dispersión/recopilación, cuando el DMA era más de 16 regiones físicas de memoria (64Kb). Para obtener un rendimiento óptimo garantizado se requieren asignaciones físicamente contiguas, que es algo que solo los conductores pueden solicitar. Esto fue básicamente una solución para un error en el controlador DMA de un chipset popular en ese entonces, y es poco probable que siga siendo un problema.

PERO - Aún así, le sugiero que pruebe TODA la potencia de 2 bloques de 32kb a 32Mb para ver cuál es más rápido. Y podría considerar probar para ver si algunos almacenamientos intermedios son consistentemente más rápidos que otros, no es algo inaudito.

+0

+1. Para E/S asíncrona. – wj32

+0

Aún no he probado el IO asíncrono. Tengo que intentarlo. BTW, después de algunas pruebas de lectura/escritura, descubrí que las lecturas de 256 KB y las escrituras de 8 MB daban un rendimiento máximo. Escribí un programa de lectura para verificar la velocidad de lectura y usé ATTO y otro programa escrito personalizado para probar el rendimiento de escritura. – ring0

2

Hace un tiempo escribí un blog publicando sobre la E/S de archivos asíncronos y cómo a menudo tiende a ser realmente sincrónico a menos que haga todo correctamente (http://www.lenholgate.com/blog/2008/02/when-are-asynchronous-file-writes-not-asynchronous.html).

Los puntos clave son que incluso cuando usa FILE_FLAG_OVERLAPPED y FILE_FLAG_NO_BUFFERING, aún necesita extender previamente el archivo para que las escrituras asíncronas no tengan que extender el archivo a medida que avanzan; por razones de seguridad, la extensión del archivo siempre es sincrónica. Para preextender, debe hacer lo siguiente:

  • Habilite el privilegio SE_MANAGE_VOLUME_NAME.
  • Abra el archivo.
  • Busque la longitud deseada del archivo con SetFilePointerEx().
  • Establezca el final del archivo con SetEndOfFile().
  • Establezca el final de los datos válidos dentro del archivo SetFileValidData().
  • Cierra el archivo.

Entonces ...

  • Abrir el archivo para escribir.
  • Emisión las escrituras
+0

En realidad estoy pre-extendiendo el archivo. Como estoy usando NO_BUFFERING, me ocupo de los problemas de alineación de datos. Por ejemplo, para copiar un archivo de 1027 KB. 1) Creo un archivo de destino con 1024 KB. Usando SetFilePointerEx y SetEndOfFile. 1024 KB debido a consideraciones de alineación. 2) Comience la copia. 3) Después de que se copian 1024 KB, cierro el manejador del archivo de destino, lo vuelvo a abrir sin usar el indicador NO_BUFFERING, busco el offset apropiado usando SetFilePointerEx y luego elaboro el WriteFile que automáticamente hace crecer el archivo a 1027KB. No he leído aún tu blog. Haré eso y te llamaré. – ring0

0

Hice algunas pruebas y tener algunos resultados. Las pruebas se realizaron en 100 Mbps & 1Gbps NIC. La máquina de origen es el servidor Win2K3 (SATA) y la máquina de destino es el servidor Win2k3 (RAID 5).

me corrieron 3 pruebas:

1) red de lectores -> Este programa simplemente lee archivos en la red. El propósito del programa es encontrar la velocidad máxima de lectura n/w. Estoy realizando una lectura NON BUFFERED utilizando CreateFile & ReadFile.

2) Escritor de disco -> Este programa compara la velocidad RAID 5 escribiendo datos. Las escrituras NO BÚFER se realizan con CreateFile & WriteFile.

3) Blitz Copy -> Este programa es el motor de copia de archivos. Copia archivos a través de la red. La lógica de este programa se discutió en la pregunta inicial. Estoy usando E/S síncrona con NO_BUFFERING Lee & Escribe. Las API utilizadas son CreateFile, ReadFile & WriteFile.


A continuación se presentan los resultados:

red de lectores: -

100 Mbps NIC

Llevé a 148344 ms para leer 768 MB con tamaño del fragmento 8 KB.

Tomó 89359 ms para leer 768 MB con tamaño del trozo 64 KB

Tomó 82625 ms para leer 768 MB con tamaño de fragmento 128 KB

Tomó 79594 ms para leer 768 MB con tamaño del fragmento de 256 KB

Tomó 78687 ms para leer 768 MB con tamaño de fragmento 512 KB

Tomó 79078 ms para leer 768 MB con tamaño de fragmento 1024 KB

Tomó 78594 ms para leer 768 MB con tamaño de fragmento 2048 KB

Tomó 78406 ms para leer 768 MB con tamaño de fragmento 4096 KB

Tomó 78281 ms para leer 768 MB con tamaño de fragmento 8192 KB

1 Gbps NIC

Tomó 206203 ms para leer 5120 MB (5GB) con tamaño de fragmento 8 KB

Tomó 77860 ms para leer 5120 MB con tamaño de fragmento 64 KB

Tomó 74531 ms para leer 5120 MB con tamaño de fragmento 128 KB

Tomó 68656 ms para leer 5120 MB con tamaño de fragmento 256 KB

Tomó 64922 ms para leer 5120 MB con tamaño de fragmento 512 KB

Tomó 66312 ms para leer 5120 MB con el tamaño del trozo 1024 KB

Tomó 68688 ms para leer 5120 MB con tamaño del trozo 2048 KB

Tomó 64922 ms para leer 5120 MB con tamaño de fragmento 4096 KB

Tomó 66047 ms para leer 5120 MB con tamaño de fragmento 8192 KB

DISCO DE ESCRITURA: -

Comentario realizado sobre RAID 5 Con NO_BUFFERING & WRITE_THROUGH

escritura 2048MB (2GB) de datos con un tamaño de fragmento de 4MB tomó 68328ms.

Escribir 2048MB de datos con un tamaño de fragmento de 8MB tomó 55985ms.

Escribir 2048MB de datos con un tamaño de fragmento de 16MB tomó 49569ms.

Escribir 2048MB de datos con un tamaño de fragmento de 32MB tomó 47281ms.

Escribir realiza en RAID 5 Con NO_BUFFERING única

escritura 2048 MB (2 GB) de datos con el tamaño del fragmento de 4 MB tomó 57484ms.

Escribir 2048MB de datos con un tamaño de fragmento de 8MB tomó 52594ms.

Escribir 2048MB de datos con un tamaño de fragmento de 16MB tomó 49125ms.

Escribir 2048MB de datos con un tamaño de fragmento de 32MB tomó 46360ms.

El rendimiento de escritura se degrada linealmente a medida que se reduce el tamaño del fragmento. Y la bandera WRITE_THROUGH introduce algo de rendimiento golpeó

BLITZ Copia: -

1 Gbps NIC, Copia de 60 GB de archivos con NO_BUFFERING

tiempo necesario para completar la copia: 2236735 ms. Es decir, 37.2 minutos. La velocidad es ~ 97 GB/por.

100 Mbps NIC, la copia de 60 GB de archivos con NO_BUFFERING

tiempo necesario para completar la copia: 7337219 ms. Es decir, 122 minutos. La velocidad es ~ 30 GB/por.

Intenté utilizar el programa 10-FileCopy de Jeffrey Ritcher que usa Async-IO con NO_BUFFERING. Pero, los resultados fueron pobres. Supongo que la razón podría ser que el tamaño del fragmento es de 256 KB ... 256 KB de escritura en RAID 5 es terriblemente lento.

Comparando con robocopy:

100 Mbps NIC: Blitz Copia y robocopy realizan @ ~ 30 GB por hora.

1 GBps NIC: La copia Blitz va a ~ 97 GB por hora mientras robocopy @ ~ 50 GB por hora.

Cuestiones relacionadas