2010-07-19 32 views
5

Ok, por lo que la historia es así:detectar cuando los datos han cambiado

- Estoy teniendo un montón de archivos (bastante grande, alrededor de 25 GB) que se encuentran en un formato particular y necesita ser importada en un almacén de datos

- estos archivos se actualizan continuamente con los datos nuevos, a veces, a veces los mismos datos

- estoy tratando de averiguar un algoritmo sobre cómo podría detectar si algo ha cambiado para una línea particular en una archivo, para minimizar el tiempo dedicado a actualizar la base de datos

- la forma en que funciona actualmente es que elimino todos los datos en la base de datos cada vez y luego los vuelvo a importar, pero esto ya no funcionará, ya que necesitaré una marca de tiempo para cuando haya cambiado un elemento.

- contiene los archivos de cadenas y números (títulos, pedidos, precios, etc.)

Las únicas soluciones que podía pensar son:

- calcular un hash para cada fila de la base de datos, que se compara con el hash de la fila del archivo y si son diferentes, actualice la base de datos

- mantenga 2 copias de los archivos, los anteriores y los actuales y haga diffs en él (que probablemente son más rápidos que la actualización de la base de datos) y en base a esos actualizar el db.

Dado que la cantidad de datos es muy grande a enorme, estoy un poco fuera de opciones por ahora. A largo plazo, me desharé de los archivos y los datos se enviarán directamente a la base de datos, pero el problema persiste.

Cualquier consejo, será apreciado.

Respuesta

1

En lugar de calcular el hash para cada fila de la base de datos sobre la demanda, ¿por qué no almacenar el valor hash en su lugar?

entonces se podría simplemente calcular el valor hash del archivo en cuestión y compararla con las bases de datos almacenados.

actualización:

Otra opción que vino a la mente es la de almacenar la información de fecha/hora de última modificación en la base de datos y luego compararlo con el del archivo en cuestión. Esto debería funcionar, siempre que la información no pueda ser cambiada intencionalmente o por accidente.

+0

Si está diciendo que calcule el hash de todo el archivo en comparación con el hash de toda la base de datos, eso no me ayudará. Pero si está diciendo que almacene el hash por fila en la base de datos, sí, esa es una de las soluciones en las que pensé. Me pregunto si eso es más rápido que solo averiguar si los datos han cambiado simplemente comparando elemento con elemento. – hyperboreean

+0

+1 por sugerir que se guarde la última fecha y hora de modificación –

+0

No tengo ninguna marca de tiempo en ese archivo. – hyperboreean

1

Bueno, independientemente de lo que usted utiliza su peor de los casos va a ser O (n), que el n ~ 25 GB de datos no es tan bonito.

menos que se puede modificar el proceso que escribe en los ficheros.

Puesto que no se está actualizando todos los 25GBs todo el tiempo, que es su mayor potencial de ahorro de ciclos.

1. No escriba al azar
¿Por qué no hacer que el proceso que escribe los datos de sólo-añadir? De esta forma tendrá más datos, pero tendrá un historial completo y podrá rastrear qué datos ya procesó (lo que ya colocó en el almacén de datos).

2.Mantenga una lista de cambios si debe escribir aleatoriamente
Alternativamente, si realmente debe hacer las escrituras aleatorias, puede mantener una lista de filas actualizadas. Esta lista se puede procesar como en el n. ° 1, y usted puede rastrear los cambios que procesó. Si desea ahorrar algo de espacio, puede mantener una lista de bloques en los que los datos cambiaron (donde el bloque es una unidad que usted define).

Además, puede mantener las sumas de comprobación/hash de bloques/líneas modificados. Sin embargo, esto puede no ser muy interesante: no es tan barato de calcular y la comparación directa puede ser más económica (si tiene ciclos de CPU libres durante la escritura, puede ahorrarle tiempo de lectura más tarde, YMMV).

Nota (s)

  • Tanto # 1 y # 2 son sólo es interesante si se puede hacer un ajuste al proceso que escribe los datos en el disco
  • Si no puede modificar el proceso de que escribe en los datos de 25 GB, entonces no veo cómo las sumas de comprobación/hashes pueden ser útiles; tienes que leer todos los datos de todos modos para calcular los hashes (ya que no sabes qué cambio) para que puedas compararlos directamente mientras lees y proponer una lista de filas para actualizar/agregar (o actualizar/agregar directamente)
  • Usar algoritmos diff podría ser un algoritmo subóptimo, diff no solo buscará las líneas que cambiaron, sino que también buscará la distancia de edición mínima entre dos archivos de texto dadas ciertas opciones de formato. (en diff, esto se puede controlar con -H o - mínimo para trabajar más lento o más rápido, es decir, buscar una solución mínima exacta o usar algoritmo heurístico para el cual si iirc este algoritmo se convierte en O (n log n); lo cual no está mal, pero aún más lento que O (n), que está disponible para usted si lo hace línea de comparación directa por línea)
3

definición del problema como se entiende.

Digamos que su archivo contiene

ID,Name,Age 
1,Jim,20 
2,Tim,30 
3,Kim,40 

Como usted indicó fila se puede añadir/modificada, por lo tanto, el archivo se convierte en

ID,Name,Age 
1,Jim,20 -- to be discarded 
2,Tim,35 -- to be updated 
3,Kim,40 -- to be discarded 
4,Zim,30 -- to be inserted 

Ahora el requisito es para actualizar la base de datos mediante la inserción/actualización sólo se más de 2 registros en dos consultas sql o 1 consulta por lotes que contiene dos declaraciones sql.

estoy haciendo suposiciones siguientes aquí

  • No se puede modificar el proceso existente para crear archivos.
  • Está utilizando algunos procesos por lotes [Lectura desde archivo - Procesamiento en memoria - Escritura en BD] para cargar los datos en la base de datos.

Almacene los valores hash de Grabar [Nombre, Edad] contra ID en un mapa en memoria donde ID es la clave y Valor es hash [Si necesita escalabilidad, use hazelcast].

Your Batch Framework para cargar los datos [De nuevo suponiendo que trata una línea de archivo como un registro], necesita verificar el valor hash calculado contra la ID en el mapa en memoria. La primera creación de tiempo también se puede hacer usando su lote marco para leer archivos.

If (ID present) 
--- compare hash 
---found same then discard it 
—found different create an update sql 
In case ID not present in in-memory hash,create an insert sql and insert the hashvalue 

Usted puede ir para el procesamiento paralelo, el procesamiento trozo y la partición de datos en memoria usando la primavera-lote y Hazelcast.

http://www.hazelcast.com/

http://static.springframework.org/spring-batch/

Espero que esto ayude.

0

prácticamente es un tipo de problema que tiene que ser resuelto por el software de copia de seguridad, ¿por qué no utilizar algunas de sus soluciones estándar? lo mejor sería enganchar las llamadas de WriteFile para que reciba devoluciones de llamada en cada actualización. Esto funcionaría bastante bien con los registros binarios.

Algo que no puedo entender: ¿los archivos son en realidad archivos de texto que no solo se anexan, sino que se actualizan? esto es altamente ineficaz (junto con la idea de mantener 2 copias de archivos, porque hará que el almacenamiento en caché de archivos funcione aún peor).

Cuestiones relacionadas