Trovare la differenza in un grande database live (quasi identico)

4

Ho un database replicato (non SQL, un triplo store, ma le specifiche non dovrebbero importare troppo) in esecuzione su diversi host. Ciascuno di essi contiene una copia del database che viene aggiornata alimentando da una certa fonte esterna e le copie devono essere identiche. Tuttavia, risulta che non sono esattamente identici - c'è una varianza nel conteggio dei record tra i database. Ogni database ha circa 2 miliardi di voci, e la differenza è relativamente piccola - circa lo 0,05% - ma ciò significa che ci sono circa un milione di record che sono in qualche modo sbagliati. Probabilmente a causa di qualche bug nel processo di aggiornamento, ma ho difficoltà a trovare cosa sia esattamente sbagliato. Il cambiamento non è dovuto al ritardo di replica, poiché il ritardo è piccolo (secondi) e il numero di record aggiornati al secondo (~ decine, forse un paio di centinaia se le cose si attivano) è molto più piccolo della differenza di dimensione.

Sarebbe molto utile sapere quali record non corrispondono, ma non sono esattamente sicuro di come si confrontino 2 miliardi di record in un DB di produzione che cambiano ogni secondo. Se faccio solo un dump - che può richiedere molto tempo, almeno ore - e lo confronta con un altro DB - che richiederà anche del tempo - la differenza potrebbe essere dovuta al fatto che i DB sono cambiati da allora.

Quindi, sto cercando idee su come trovare quei record diversi. Non ho bisogno di tutti loro - avere anche una sola istanza sarebbe già utile - ma non sono sicuro di come trovarne una anche in modo efficiente.

    
posta StasM 26.04.2017 - 23:21
fonte

3 risposte

2

C'è più di un modo per farlo, e ci sono probabilmente dei limiti pratici per farlo che non hai menzionato. Date le piccole informazioni, ecco come lo farei.

Iniziamo con alcune ipotesi:

  • Questo database ha un utilizzo moderatamente elevato, l'aggiunta di un carico è accettabile, ma non è un carico pesante sul sistema.
  • Ti interessa che tu trovi rapidamente qualsiasi record effettivamente richiesto che non corrisponde.
  • I record sono solo normali, il che significa che puoi confrontare i record di entrambi i negozi senza ulteriore lavoro.
  • Puoi trovare un numero di sequenza di ogni record quando lo leggi, ad esempio "questo è record 1,242,423,231 o 3,234,422,413". Molti, ma non tutti, i database supporteranno questo.
  • Questa è una cosa da fare una sola volta ed è importante.

Quindi, ecco una soluzione:

  • Ci sono solo pochi miliardi di voci, quindi possiamo adattare un set di bit di tutti i record controllati in un bit impostato nella RAM. 4 miliardi di bit sono circa mezzo gigabyte di RAM. Inizialmente impostati su zero, questi saranno impostati su uno se i record sono mai stati confrontati.
  • Ogni volta che recuperi un record, recupera il record equivalente dall'altro datastore, li confronta e, se tutto va bene, imposta il bit 'checked this one' su uno. Nel tempo, sarà necessario controllare in questo modo un numero inferiore di record comuni.
  • Ogni volta che il carico è "inferiore", inizia a estrarre dal database i record non selezionati casuali o sequenziali. Se il tuo negozio ha un fine settimana non utilizzato, dovrai controllare molti record.

Ecco un'altra soluzione senza numeri di record:

  • Innanzitutto, attiva il confronto ogni volta che chiedi un record dal vivo. Ciò mantiene l'integrità dei tuoi dati.
  • In secondo luogo, avvia la scansione lenta su qualsiasi indice completo.

Finalmente, ecco la mia soluzione raccomandata.

  • Stop. Vai a prendere un caffè. Pensa bene a come potrebbe essere successo. Annota le ipotesi che potrebbero essere sbagliate. Pensa ai log per i record modificati durante la replica. Vedi se riesci a risolverlo.
  • Fai il back-of-the-envelop di tempo che questo richiederà. Leggere l'intero contenuto di un disco, sulla tua rete, anche per un paio di terabyte può richiedere per sempre. Puoi creare reti ad hoc e controllare rack per rack? Quanto è grave?
risposta data 27.04.2017 - 02:56
fonte
1

Sembra che forse tutto quello che hai come altri metadati sia il numero di record in ogni database?

Usando proprio questo, forse è possibile, in ogni round di aggiornamenti da fonti esterne, vedere se i conteggi dei record divergono (più di quelli che già sono). Se lo fanno, almeno hai un set di record sospetto (aggiornamento) che dovrebbe essere esaminato attentamente in ogni database per vedere se quei record lo hanno fatto in entrambi. Se necessario, potrebbe essere necessario rallentare gli aggiornamenti in modo da poter ottenere il conteggio dei record da ciascun set di aggiornamento, per limitare un aggiornamento errato.

    
risposta data 27.04.2017 - 02:02
fonte
0

non puoi caricarli in memoria, 2 miliardi di record di 100 byte esach sarebbero quasi 200GB di ram.

Il modo in cui normalmente si confrontano set come questo è guardandoli in pagine basate su un certo ordinamento. Ad esempio, se avessi una rubrica, potrei ordinarli in base al numero di telefono (o al cognome non importa quale tipo di ordinamento si prende)

Database 1         | Database 2
555- 1234 anderson | 555 - 1234 anderson
555  1235 smith    | 555 - 1235 johnson
555  1236 miller   | 555 - 1236 miller

Ora carica una pagina (ad esempio 1000 record o qualcosa di abbastanza ragionevole) e poi passa attraverso di essi in modo lineare. Basta tenere un puntatore e confrontare 1 numero di telefono contro l'altro.

Nota: non basta guardare l'indice del puntatore perché potrebbe esserci un inserimento, se il ydiffer stampa semplicemente la differenza e incrementa il puntatore a sinistra & a destra.

Nota: hai detto che i tuoi record non hanno un ID univoco. è ancora necessario determinare quando parlano dello stesso record. Ad esempio cognome + data di nascita potrebbe essere considerata l'identificazione di una persona e stai cercando di cambiare gli indirizzi che non sono stati elaborati correttamente.

    
risposta data 27.04.2017 - 07:13
fonte

Leggi altre domande sui tag