Stiamo costruendo un sistema in cui accumuliamo i dati da molti dei nostri servizi interni, li elaboriamo e generiamo un insieme di dati chiamati lavori salvati nel database. La nostra applicazione client in esecuzione sui sistemi client richiede periodicamente questi lavori e nella risposta vengono inviati i lavori idonei per il cliente richiesto. Per ogni richiesta del cliente è necessario cercare lavori qualificati dalla tabella dei lavori in base ai parametri della richiesta del cliente.
Esempio:
Lavoro:
#1
{
"id": "1",
"searchFields":{
"key1":"value1",
"key2":"value2",
"key3":"value3"
},
"job": <SOME COMMAND>
}
#2
{
"id": "2",
"searchFields":{
"key3":"value3",
"key4":"value4",
},
"job": <SOME COMMAND>
}
#3
{
"id": "3",
"searchFields":{
"key5":"value5",
"key6":"value6",
},
"job": <SOME COMMAND>
}
Come dovrebbe funzionare la ricerca?
Abbiamo un set di attributi nella richiesta del client, i valori di questi attributi dovrebbero corrispondere ai valori degli attributi nel campo di ricerca di lavoro "searchField". Se la richiesta del cliente ha attributi "key1", "key2" e "key3" e searchField del lavoro ha "key1" e "key2", questo job è qualificato solo se il valore di "key1" e "key2" di entrambe le richieste del client e Job corrispondenze searchField.
Richieste client:
# 1
{
"key1":"value1",
"key2":"value2",
"key3":"value3"
}
Job #1 is qualified. Job #2 is not qualified because request input does not have "key4".
# 2
{
"key1":"value1",
"key2":"some_different_value",
"key3":"value3"
}
No jobs are qualified because value of key2 doesn't match with any job
# 3
{
"key1":"value1",
"key2":"value2",
"key3":"value3",
"key4":"value4"
}
Job #1 and #2 are qualified.
# 3
{
"key2":"value2",
"key3":"value3",
"key4":"value4",
"key5":"value5",
"key6":"value6",
}
Job #2 and #3 are qualified. Job #1 is not qualified because "key1" does not exists in input data
Abbiamo già realizzato un prototipo per questo sistema utilizzando il database MySQL, ma riteniamo che MySQL non sia adatto per questo tipo di sistemi. La tabella dei lavori è molto ampia e continua a crescere (più di 1.000.000 di record aggiunti ogni giorno) e la ricerca di lavori basati su più attributi solo utilizzando query SQL standard (senza campi indicizzati) non è efficiente. Inoltre, gli attributi nella richiesta del cliente e nel campo di ricerca di Job sono dinamici. Non abbiamo un set fisso di attributi su cui lavorare. Nuovi attributi possono essere aggiunti o rimossi in qualsiasi momento, quindi se utilizziamo query SQL piuttosto che gestire gli attributi dinamici sarebbe ingombrante.
Cosa abbiamo provato?
Abbiamo creato combinazioneKey e hashKey di tutti gli attributi di valori-chiave in searchField per ogni Job e salvati nel database insieme al lavoro.
Come vengono generati combinazioneKey e hashkey,
Job:
{
"id": "1",
"searchFields":{
"key1":"value1",
"key2":"value2",
"key3":"value3"
},
"job": <SOME COMMAND>
}
combinationKey="key1 :: :: key2 key3" HashKey = sha256Of ( "chiave1 = valore1 :: chiave2 = valore2 :: key3 = value3")
E salva lavoro come,
{
"id": "1",
"combinationKey": "key1::key2::key3",
"hashKey":<Hash_Key>,
"searchFields":{
"key1":"value1",
"key2":"value2",
"key3":"value3"
},
"job": <SOME COMMAND>
}
Quando riceviamo la richiesta del cliente, recuperiamo le chiavi di combinazione univoche dalla tabella dei lavori (scansione completa della tabella o cache) e generiamo hash per gli attributi delle richieste in entrata,
Chiavi di combinazione uniche dalla tabella dei lavori: "key1 :: key2 :: key3", "key4 :: key5" ... ecc.
Richiesta cliente:
{
"key1":"value1",
"key2":"value2",
"key3":"value3",
"key4":"value4"
}
Scorrere tra tutte le chiavi di combinazione e generare l'elenco di hashKey per gli attributi di richiesta in entrata e una volta generate le hashKeys, cercare Lavori nella tabella Lavori che corrisponde a questi hashKeys.
Questo approccio sembra funzionare bene nel nostro prototipo, ma ritengo che non sia abbastanza efficiente, poiché con la crescita dei dati di Jobs esiste la possibilità che il conteggio di combinazioni uniche possa crescere in modo esponenziale e per ogni richiesta client, calcolando hashkey per tutte le combinazioni sarebbe intensivo di calcolo.
Di cosa abbiamo bisogno?
- Il modo più efficiente e facile per cercare la tabella dei lavori basata sugli attributi della richiesta del client in entrata secondo i nostri requisiti.
- Ricerca coerente e accurata. Non vogliamo usare motori di ricerca come Elasticsearch perché abbiamo bisogno di dati accurati e non di analisi.
- Il miglior database adatto a questo tipo di sistemi.
- Qualsiasi azienda (come facebook, google) utilizza già questo tipo di sistemi, quindi possiamo analizzare il loro approccio.
Qualsiasi aiuto sarebbe apprezzato.