Come creare ID di incremento automatico in Cassandra

Sappiamo che è facile creare ID di incremento automatico nei database SQL, c’è una buona soluzione per questo in Cassandra? Gli ID dovrebbero essere per il nome della chiave o della colonna.

    Creare una sequenza sequenziale globale di numeri non ha alcun senso in un sistema distribuito. Usa UUID .

    (Perché dovresti rendere tutti i partecipanti d’accordo e accettare l’evoluzione della sequenza – con un’implementazione ingenua)

    Che ne dici di quanto segue, utilizzando le transazioni leggere di Cassandra

    1 – Crea tabella ID:

    CREATE TABLE ids ( id_name varchar, next_id int, PRIMARY KEY (id_name) ) 

    2 – Inserisci ogni ID con cui desideri utilizzare una sequenza globale

    Per esempio:

     INSERT INTO ids (id_name, next_id) VALUES ('person_id', 1) 

    3 – Quindi, quando si inserisce una tabella in cui si desidera utilizzare una chiave auto-incrementata, effettuare le seguenti operazioni:

    3.1 – Ottieni il next_id dalla tabella ids:

     SELECT next_id FROM ids WHERE id_name = 'person_id' 

    Diciamo che il risultato è next_id = 1

    3.2 – Incremento next_id, nel seguente modo:

     UPDATE ids SET next_id = 2 WHERE id_name = 'person_id' IF next_id = 1 

    Il risultato dovrebbe essere simile a questo:

     [{[applied]: True}] 

    Se è stato aggiornato correttamente, OR

     [{[applied]: False, next_id: 2}] 

    Se qualcun altro l’ha già aggiornato.

    Quindi, se hai True, usa id ‘1’ – è tuo. Altrimenti, incrementa next_id (o usa semplicemente restituito next_id) e ripeti il ​​processo.

    Non c’è una buona soluzione.

    1. Crea una colonna con un numero, aumenta il numero e salvalo su tutte le repliche insieme a un id temporaneo, leggi tutte le repliche e verifica se l’ID temporaneo è “tuo”, altrimenti fallo di nuovo .. non è una soluzione eccezionale e non lo farà scala.

    o

    1. Crea il tuo servizio di identificazione personale in cui recuperi il tuo prossimo ID. Questo servizio verrà eseguito solo in una singola istanza e sarà un fattore spaventoso non scalabile.

    Non appena qualcosa va oltre una singola istanza, il sequenziamento degli ID diventa complicato, almeno se lo si vuole ridimensionare. Ciò include i database relazionali.

    c’è un tipo di contatore che può essere utilizzato. Considera l’esempio seguente.

     CREATE KEYSPACE counterks WITH REPLICATION = { 'class' : 'NetworkTopologyStrategy', 'datacenter1' : 3 }; 

    Crea una tabella per la colonna contatore.

     CREATE TABLE counterks.page_view_counts (counter_value counter, url_name varchar, page_name varchar, PRIMARY KEY (url_name, page_name) ); 

    Carica i dati nella colonna contatore.

     UPDATE counterks.page_view_counts SET counter_value = counter_value + 1 WHERE url_name='www.datastax.com' AND page_name='home'; 

    Dai un’occhiata al valore del contatore.

     SELECT * FROM counterks.page_view_counts; 

    L’output è:

      url_name | page_name | counter_value ------------------+-----------+--------------- www.datastax.com | home | 1 

    Aumentare il valore del contatore.

      UPDATE counterks.page_view_counts SET counter_value = counter_value + 2 WHERE url_name='www.datastax.com' AND page_name='home'; 

    Dai un’occhiata al valore del contatore.

      url_name | page_name | counter_value ------------------+-----------+--------------- www.datastax.com | home | 3 

    Riferiscilo per maggiori dettagli: http://docs.datastax.com/en/cql/3.1/cql/cql_using/use_counter_t.html

    Questa domanda è piuttosto vecchia, ma mi piacerebbe completarla con un’altra soluzione.

    Qualsiasi soluzione che si basi sulla sincronizzazione dei nodes è irragionevole. È piuttosto sicuro di romperlo bloccando la generazione di ID o creando ID duplicati.

    Modo MySQL

    È ansible riprodurre il modo in cui è stato eseguito con la replica master-master mysql con i parametri auto_increment_increment e auto_increment_offset .

    Per riprodurlo, è necessario conoscere il numero di nodes o il numero massimo di nodes previsti ed è necessario creare un contatore (non cassandra) (un file per esempio) su ciascun nodo.

    Ogni volta che si desidera generare un nuovo numero, si trova il valore corrente, aggiungere l’incremento e salvarlo. Se non esiste ancora, è l’offset.

    Quindi per 10 nodes avresti un incremento di 10 e un offset di 1 per il primo nodo, 2 per il secondo nodo, ecc. Il nodo 1 creerebbe gli ID 1, 11, 21. Il nodo 2 creerebbe gli ID 2, 21, 22.

    Se vuoi che i tuoi ID siano (approssimativamente) ordinati tra i nodes, devi mantenere un contatore condiviso e assicurarti che ciascun ID generato sia superiore al contatore condiviso. In questo modo, a meno che i tuoi nodes / datacenter non siano sincronizzati per molto tempo, non dovresti notare molta differenza.

    anteponendo

    Puoi fare praticamente la stessa cosa prefiggendo l’ID (se è una soluzione accettabile) con il numero del nodo (o il nome). E non devi sapere il numero di nodes. Il nodo 1 creerebbe 1_1, 1_2, 1_3. Il nodo 2 creerebbe 2_1, 2_2, 2_3.

    Modifica: questa soluzione non è corretta. Vedi il primo commento.

    La mia soluzione:

    1 – Crea tabella ID:

     CREATE TABLE ids ( id_name varchar, next_id counter, PRIMARY KEY (id_name) ) 

    2 – Quando si inserisce in una tabella in cui si desidera utilizzare una chiave auto-incrementata, effettuare le seguenti operazioni:

    2.1 – Contatore incrementale (verrà creato se non esiste), utilizzando il livello di coerenza più alto

     UPDATE ids SET next_id = next_id + 1 WHERE id_name = $AUTO_INCREMENTED_ID USING CONSISTENCY ALL 

    2.2 – Ottieni il nuovo valore id:

     SELECT next_id FROM ids WHERE id_name = $AUTO_INCREMENTED_ID 

    2.3 – Inserisci il valore con l’ID auto-incrementato

     INSERT INTO some_table ($AUTO_INCREMENTED_ID, ...) VALUES ($RESULT_FROM_PREVIOUS_QUERY, ...) 

    Le parole che iniziano con ‘$’ nella mia risposta sono autoesplicative (spero) segnaposto …

    Ovviamente questo non è un metodo raccomandato. Usalo solo se devi.

    Hanno davvero bisogno di essere sequenziali, o hai semplicemente bisogno di contare numeri che sono molto più piccoli di un UUID che sono facilmente inseriti da una persona?

    Se hai davvero bisogno di numeri sequenziali, dovrai eseguire una delle seguenti azioni.

    • Avere una tabella in cassandra in cui la chiave / id è un campo per il generatore, e il valore è un numero … fare aggiornamenti condizionali in un ciclo fino a quando non si incrementa con successo il conteggio. (ctriggers idea)

    • Avere un servizio di generatore che ti darà il prossimo numero. Questo può essere eseguito solo su un singolo sistema ed essere un singolo punto di errore, ma a seconda delle esigenze questo potrebbe essere il migliore.

    In alternativa … Simile al primo, ma ottieni gruppi di 100 o più numeri alla volta, e distribuiscili all’interno del tuo processo / thread … Questo avrà meno contese, ma nessuna garanzia di ordine sequenziale, solo unicità .. Se si desidera solo numeri più brevi che sono unici per la visualizzazione, questa potrebbe essere la soluzione migliore.

    Penso che IMHO si aspetta che Cassandra fornisca un campo di auto-incremento è SBAGLIATO

    Cassandra è un elegante database decentralizzato, quindi aspettarsi che fornisca un campo autoincrescente è, tassando e sconfigge lo scopo originale, perché questo valore deve essere quindi mantenuto in un posto centrale

    Quindi, non creare alcuna soluzione basata su DB per ottenere un numero a incremento automatico

    Invece genera l’ID nel codice o nel servizio nella tua app, che può continuare a generare ID univoci casuali e usarli per applicare sul tuo modello di dati, in questo modo l’objective e il vantaggio di Cassandra non saranno sconfitti