web-dev-qa-db-ja.com

Cassandraで自動インクリメントIDを作成する方法

SQLデータベースで自動インクリメントIDを簡単に作成できることはわかっていますが、Cassandraでそれを解決する良い方法はありますか? IDは、キーまたは列の名前用である必要があります。

44
Andy Wan

数値のグローバルな連続したシーケンスを作成することは、分散システムでは実際には意味がありません。 ID を使用します。

(すべての参加者に同意し、単純な実装の下でシーケンスの進化を受け入れる必要があるため)

34
Luis Matta

Cassandraの 軽量トランザクション を使用して、次のことはどうですか

1-IDテーブルを作成します。

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

2-グローバルシーケンスを使用するすべてのIDを挿入します

例えば:

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

3-その後、自動増分キーを使用するテーブルに挿入する場合、次の手順を実行します。

3.1-idsテーブルからnext_idを取得します。

SELECT next_id FROM ids WHERE id_name = 'person_id'

結果がnext_id = 1だとしましょう

3.2-次の方法でnext_idをインクリメントします。

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

結果は次のようになります。

[{[applied]: True}]

正常に更新された場合、または

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

他の誰かがすでに更新している場合。

したがって、Trueを取得した場合は、ID '1'を使用します-それはあなたのものです。それ以外の場合は、next_idをインクリメント(または、返されたnext_idを使用)して、プロセスを繰り返します。

33
AlonL

良い解決策はありません。

  1. 番号付きの列を作成し、番号を増やして、一時IDとともにすべてのレプリカに保存し、すべてのレプリカを読み取り、一時IDが「自分のもの」であるかどうかを確認します。規模。

または

  1. 次のIDを取得する独自のIDサービスを構築します。このサービスは単一のインスタンスでのみ実行され、スケーリングのない怖い要素になります。

少なくとも1つのインスタンスを超えると、IDの順序付けが複雑になります(少なくともスケーリングする場合)。これには、リレーショナルデータベースが含まれます。

15
Simon

使用できるカウンタデータ型があります。以下の例を考えてください。

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

カウンター列のテーブルを作成します。

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

カウンター列にデータをロードします。

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

カウンター値を見てください。

SELECT * FROM counterks.page_view_counts;

出力は次のとおりです。

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

カウンターの値を増やします。

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

カウンター値を見てください。

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

詳細については、こちらを参照してください: http://docs.datastax.com/en/cql/3.1/cql/cql_using/use_counter_t.html

5
mateenk

この質問はかなり古いですが、他の解決策で完成させたいと思います。

ノードの同期に依存するソリューションは不合理です。 IDの生成をブロックするか、重複したIDを作成することにより、確実にブレークします。

MySQLの方法

auto_increment_incrementおよびauto_increment_offsetパラメーターを使用して、mysqlマスター/マスターレプリケーションで行われた方法を再現できます。

それを再現するには、ノードの数または予想されるノードの最大数を知る必要があり、各ノードで(非Cassandra)カウンター(例ごとにファイル)を作成する必要があります。

新しい数値を生成するたびに、現在の値を見つけ、増分を追加して保存します。まだ存在しない場合は、オフセットです。

したがって、10個のノードの場合、最初のノードの増分は10、オフセットは1、2番目のノードの場合は2などとなります。Node 1はID 1、11、21を作成します。Node 2はID 2、21、22を作成します。

IDを(おおよそ)ノード間で順序付けする場合は、共有カウンターを維持し、生成された各IDが共有カウンターよりも高いことを確認する必要があります。そうすれば、ノード/データセンターが長時間同期されない限り、大きな違いに気付かないはずです。

接頭辞

ID(受け入れ可能なソリューションである場合)の前にノード番号(または名前)を付けることで、基本的に同じことを行うことができます。また、ノードの数を知る必要はありません。 Node 1は1_1、1_2、1_3を作成します。Node 2は2_1、2_2、2_3を作成します。

3
Florent

私は、Cassandraが自動インクリメントフィールドを提供することを期待しているのは間違っていると思います

Cassandraはエレガントな分散型データベースであるため、自動インクリメントフィールドを提供することを期待しているため、この値は中央の場所で維持する必要があるため、元の目的に負担をかけ、無効にします。

したがって、DBが自動インクリメント数を取得するためのベースとなるソリューションを作成しないでください。

代わりに、アプリ内のコードまたはサービスでIDを生成します。これにより、ランダムな一意のIDを生成し続け、それを使用してデータモデルに適用できます。この方法では、Cassandra負けた

2
Basav

編集:この解決策は適切ではありません。最初のコメントを参照してください。

私の解決策:

1-IDテーブルを作成します。

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

2-自動増分キーを使用するテーブルに挿入する場合、次の手順を実行します。

2.1-最高の整合性レベルを使用して、増分カウンター(存在しない場合は作成されます)

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

2.2-新しいid値を取得します。

SELECT next_id
  FROM ids
  WHERE id_name = $AUTO_INCREMENTED_ID

2.3-自動インクリメントされたIDで値を挿入

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

私の答えで「$」で始まる言葉は、一目瞭然の(希望する)プレースホルダーです...

もちろん、これは推奨される方法ではありません。必要な場合にのみ使用してください。

2
AlonL

それらは本当に連続している必要がありますか、それとも、人が簡単に入力できるUUIDよりもはるかに小さい数を数えるだけですか?

連番が本当に必要な場合は、次のいずれかを実行する必要があります。

  • cassandraのキー/ IDはジェネレーターのフィールドで、値は数値です...にテーブルがあります...カウントが正常に増加するまでループで条件付き更新を行います。考え)

  • 次の番号を提供するジェネレーターサービスを用意してください。これは単一のシステムでのみ実行でき、単一障害点になる可能性がありますが、ニーズによってはこれが最適な場合があります。

あるいは...最初と同様ですが、一度に100個程度の数のバッチを取得し、それらをプロセス/スレッド内で処理します。これにより、競合が少なくなりますが、順序の保証はなく、一意性のみです。 。表示用に一意の短い数字のみが必要な場合は、これが最善の方法です。

1
Tracker1