2008-09-26 10 views
9

Tengo un problema que me obliga a analizar varios archivos de registro desde una máquina remota. Hay algunas complicaciones: 1) El archivo puede estar en uso 2) Los archivos pueden ser bastante grandes (100mb +) 3) Cada entrada puede ser de varias líneas¿Cuál es la mejor manera de leer y analizar un archivo de texto grande a través de la red?

para resolver el problema en uso, Necesito copiarlo primero. Actualmente estoy copiando directamente de la máquina remota a la máquina local y analizándolo allí. Eso lleva al problema 2. Dado que los archivos son bastante grandes, copiarlo localmente puede llevar bastante tiempo.

Para mejorar el tiempo de análisis, me gustaría hacer el analizador de subprocesos múltiples, pero eso hace que tratar con entradas de múltiples líneas sea un poco más complicado.

Los dos problemas principales son:? 1) ¿Cómo puedo acelerar la transferencia de archivos (compresión ?, está transfiriendo a nivel local, incluso lo necesite ?, ¿Puedo leer un archivo en el uso de alguna otra manera) 2) ¿Cómo puedo tratar con las entradas de varias líneas al dividir las líneas entre los hilos?

ACTUALIZACIÓN: La razón por la que no hice el análisis obvio en el motivo del servidor es que quiero tener el menor impacto de la CPU posible. No quiero afectar el rendimiento de la prueba de sistema del sistema.

Respuesta

2

Si está leyendo un archivo secuencial, quiere leerlo línea por línea en la red. Necesitas un método de transferencia capaz de transmitir. Tendrá que revisar su tecnología de transmisión IO para resolver esto.

Las operaciones de IO grandes como esta no se beneficiarán mucho con el multihilo, ya que probablemente pueda procesar los elementos tan rápido como pueda leerlos en la red.

Su otra gran opción es poner el analizador de registro en el servidor y descargar los resultados.

+0

Si copiar un archivo de texto de 100mb directamente a través de la red tarda x segundos, y tener un cliente remoto comprime y envía el archivo y luego desinflar/leer lleva x/4 segundos, ¿no vale la pena? (Tenga en cuenta que en realidad no sé cuánto tiempo llevaría comprimir/enviar/descomprimir/leer) – midas06

+0

Por supuesto, puede (y debería) usar algo de compresión en la red. Como dije, revise sus opciones de transmisión IO: algunos chicos sugirieron algunas bibliotecas zip. OTOH si puedes poner un programa en el extremo remoto, ¡haz el procesamiento allí! –

1

La manera más fácil considerando que ya está copiando el archivo sería comprimirlo antes de copiarlo y descomprimirlo una vez que se haya completado la copia. Obtendrá grandes ganancias al comprimir archivos de texto porque los algoritmos zip generalmente funcionan muy bien en ellos. Además, su lógica de análisis existente podría mantenerse intacta en lugar de tener que conectarla a un lector de texto de red remoto.

La desventaja de este método es que no podrá obtener actualizaciones línea por línea de manera muy eficiente, que es bueno tener para un analizador de registros.

+0

Me encantaría comprimirlo, pero si mi código se ejecuta en la máquina local, se comprimiría después de ser transferido, lo cual es contrario al propósito. Estoy pensando en terminar escribiendo un cliente que no hace más que comprimir y enviar. – midas06

0

He usado SharpZipLib para comprimir archivos de gran tamaño antes de transferirlos por Internet. Entonces esa es una opción.

Otra idea para 1) sería crear un conjunto que se ejecute en la máquina remota y realice el análisis allí. Puede acceder al ensamblaje desde la máquina local utilizando .NET remoto. El ensamblaje remoto debería ser un servicio de Windows o alojarse en IIS. Eso le permitiría conservar sus copias de los archivos de registro en la misma máquina y, en teoría, tomaría menos tiempo procesarlas.

0

creo que el uso de la compresión (desinflar/gzip) ayudaría

1

supongo que depende de la "distancia" que es. 100MB en una LAN de 100Mb sería de aproximadamente 8 segundos ... hasta Gigabit, y lo tendrías en alrededor de 1 segundo. $ 50 * 2 para las tarjetas, y $ 100 para un cambio sería una actualización muy barata que podría hacer.

Pero, suponiendo que esté más alejado, debería poder abrirlo con el modo de solo lectura (como lo está leyendo cuando lo está copiando). SMB/CIFS es compatible con la lectura de bloque de archivos, por lo que debe transmitir el archivo en ese momento (por supuesto, no dijo realmente cómo estaba accediendo al archivo, estoy asumiendo SMB).

El subprocesamiento múltiple no ayudará, ya que de todos modos estará vinculado a la red o al disco.

1

Use la compresión para la transferencia.

Si su análisis sintáctico realmente está desacelerando, y tiene múltiples procesadores, puede interrumpir el análisis sintáctico, solo tiene que hacerlo de una manera inteligente: tener un algoritmo determinista para el cual los trabajadores son responsables de tratar con registros incompletos. Asumiendo que puede determinar que una línea es parte de la mitad de un registro, por ejemplo, puede dividir el archivo en segmentos N/M, cada uno responsable de M líneas; cuando uno de los trabajos determina que su registro no está terminado, solo tiene que seguir leyendo hasta que llegue al final del registro. Cuando uno de los trabajos determina que está leyendo un registro para el que no tiene un comienzo, debe omitir el registro.

1

La mejor opción, desde la perspectiva del rendimiento, será realizar su análisis en el servidor remoto. Además de las circunstancias excepcionales, la velocidad de su red siempre será el cuello de botella, por lo que limitar la cantidad de datos que envía a través de su red mejorará enormemente el rendimiento.

Esta es una de las razones por las que muchas bases de datos usan procedimientos almacenados que se ejecutan en el extremo del servidor.

Las mejoras en la velocidad de análisis (si existen) mediante el uso de subprocesamiento múltiple se verán inundadas por la velocidad comparativa de la transferencia de red.

Si se ha comprometido a transferir sus archivos antes de analizarlos, una opción que podría considerar es el uso de compresión sobre la marcha mientras realiza la transferencia de archivos. Hay, por ejemplo, servidores sftp disponibles que realizarán la compresión sobre la marcha. En el extremo local, puede usar algo como libcurl para hacer el lado del cliente de la transferencia, que también es compatible con la descompresión sobre la marcha.

1

Si puede copiar el archivo, puede leerlo. Entonces no hay necesidad de copiarlo en primer lugar.

EDIT: utilice FileStream class para tener más control sobre los modos de acceso y uso compartido.

new FileStream("logfile", FileMode.Open, FileAccess.Read, FileShare.ReadWrite) 

deberían hacer el truco.

+0

Disiento allí. Según mi experiencia, la copia en uso funcionará cuando intentar analizar a través de ella en una transmisión no lo hará. Mi teoría es que copy usa alguna otra aplicación de Windows que lo permita. – midas06

+0

Tu teoría es incorrecta, yo. Windows Explorer usa la misma API que utiliza .NET (y FileStream). ¿Lo intentaste? – VVS

Cuestiones relacionadas