Vorrei ricevere feedback e suggerimenti su due approcci che sto considerando di implementare gli indici ricercabili utilizzando i set ordinati di Redis.Indicizzazione utilizzando i set ordinati Redis
Situazione e obiettivo
Al momento hanno alcune tabelle di valori-chiave stiamo memorizzazione in Cassandra, e che noi vorrebbero avere indici per. Ad esempio, una tabella conterrà record di persone e la tabella di Cassandra avrà come chiave primaria id e l'oggetto serializzato come valore. L'oggetto avrebbe campi come first_name, last_name, last_updated e altri.
Quello che vogliamo è essere in grado di fare ricerche come "last_name = 'Smith' AND first_name> 'Joel'", "last_name < 'Aaronson'", "last_name = 'Smith' AND first_name = 'Winston' " e così via. Le ricerche dovrebbero restituire gli ID delle partite in modo da poter recuperare gli oggetti da Cassandra. Sto pensando che le ricerche di cui sopra potrebbero essere fatte con un singolo indice, ordinato lessicograficamente da last_name, first_name e last_updated. Se abbiamo bisogno di alcune ricerche usando un ordine diverso (ad esempio "first_name = 'Zeus'") possiamo avere un indice simile che permetterebbe loro (ad es. First_name, last_updated).
Stiamo cercando di utilizzare Redis per questo, perché dobbiamo essere in grado di gestire un numero elevato di scritture al minuto. Ho letto su alcuni modi comuni Redis ordinata set sono utilizzati, e venire con due possibili implementazioni:
Opzione 1: un unico insieme ordinato per indice
Per il nostro indice cognome, first_name, last_updated, avremmo un insieme ordinato in Redis sotto gli indici chiave: people: last_name: first_name: last_updated, che conterrebbe stringhe con il formato last_name: first_name: last_updated: id. Per esempio:
Smith: joel: 1372761839,444: 0azbjZRHTQ6U8enBw6BJBw
(Per il separatore potrei usare '::', piuttosto che ':' o qualcos'altro per lavorare meglio con l'ordinamento lessicografico, ma cerchiamo di ignorare che, per ora)
A tutti gli elementi viene assegnato un punteggio 0 in modo che il set ordinato venga ordinato in ordine lessicografico dalle stringhe stesse. Se poi voglio fare una query come "last_name = 'smith' AND first_name < 'bob'", avrei bisogno di ottenere tutti gli elementi nella lista che precede 'smith: bob'.
Per quanto posso dire, vi sono le seguenti svantaggi di questo approccio:
- Non esiste una funzione Redis per selezionare un intervallo in base al valore della stringa. Questa funzione, chiamata ZRANGEBYLEX, è stata proposta da Salvatore Sanfilippo allo https://github.com/antirez/redis/issues/324, ma non è implementata, quindi dovrei trovare gli endpoint usando le ricerche binarie e ottenere l'intervallo da solo (magari usando Lua, o al livello dell'applicazione con Python che è la lingua che stiamo usando per accedere a Redis).
- Se vogliamo includere un time-to-live per le voci di indice, sembra che il modo più semplice per farlo sarebbe avere un'attività pianificata regolarmente che attraversa l'intero indice e rimuove gli elementi scaduti.
Opzione 2: piccoli insiemi ordinati, ordinati per LAST_UPDATED
Questo approccio sarebbe simile, tranne che avremmo molti, più piccolo, insiemi allineati, con ciascuno che ha un valore di tempo simile, come LAST_UPDATED per i punteggi. Ad esempio, per lo stesso cognome, first_name, ultimo indice aggiornato, avremmo un insieme ordinato per ogni combinazione last_name, first_name. Ad esempio, la chiave potrebbe essere indici: people: last_name = smith: first_name = joel, e avrebbe una voce per ogni persona che abbiamo chiamato Joel Smith. Ogni voce avrebbe come nome l'id e il suo punteggio il valore last_updated. Es .:
valore: 0azbjZRHTQ6U8enBw6BJBw; Punteggio: 1372761839.444
I principali vantaggi di questo sono (a) le ricerche in cui sappiamo tutti i campi tranne LAST_UPDATED sarebbe molto facile, e (b) l'attuazione di un time-to-live sarebbe molto semplice, utilizzando lo ZREMRANGEBYSCORE.
L'inconveniente, che sembra molto grande per me è:
- Sembra che ci sia molto di più di complessità nella gestione e la ricerca in questo modo. Ad esempio, avremmo bisogno dell'indice per tenere traccia di tutte le sue chiavi (nel caso, ad esempio, vogliamo pulire in un punto) e farlo in modo gerarchico. Una ricerca come "last_name < 'smith'" richiederebbe prima di tutto l'elenco di tutti i cognomi per trovare quelli che vengono prima di smith, quindi per ognuno di quelli che guardano tutti i nomi che contiene, quindi per ognuno di quelli ottenere tutti gli elementi dal set ordinato. In altre parole, un sacco di componenti da costruire e preoccuparsi.
avvolgendo
così sembra a me la prima opzione sarebbe meglio, nonostante i suoi svantaggi. Apprezzerei molto qualsiasi feedback riguardante queste due o altre possibili soluzioni (anche se dovessero usare qualcosa di diverso da Redis).
Il [aiuto su come non essere uno spammer] (http://stackoverflow.com/help/promotion) è chiaro che "è necessario rivelare la propria affiliazione nelle vostre risposte." Ho modificato la tua risposta di conseguenza. – Louis