SOに関するCassandraに関するかなりの数の記事と多くの質問/回答を読みましたが、Cassandraがどのノードに移動するかを決定する方法がまだわかりません。データを読み込んでいるとき。
最初に、仮想クラスターに関するいくつかの仮定:
Datastaxのさまざまな記事や私が読んだ他のブログ投稿に基づいて、書き込みがどのように機能するかについての私の理解は次のとおりです。
データはcommit_logおよびmemtableに書き込まれ、4回伝播されます(RF = 5で)。
次に、リング内の次の4つのノードが選択され、データが保持されます。
ここまでは順調ですね。
ここで問題は、クライアントが読み取り要求(CL = 3など)をクラスターに送信するときに、Cassandraが取得するために接続する必要があるノード(最悪の場合は5つ)をどのように知るかですこのデータ?確かに、10個すべてのノードには効率的ではないため、これは行われません。
Cassandraが再び(要求の)プライマリキーのMD5ハッシュを行い、それに応じてノードを選択し、リングを歩くと仮定して正しいですか?
また、ネットワークトポロジのケースはどのように機能しますか?複数のデータセンターがある場合、Cassandraは各DC/Rackのどのノードにデータが含まれているかをどのように知るのですか?私が理解したことから、最初のノードのみが明らかです(主キーのハッシュがそのノードを明示的に生成したため)。
質問があまり明確でない場合は申し訳ありませんが、私の質問に関する詳細が必要な場合はコメントを追加してください。
どうもありがとう、
クライアントはデータをランダムノードに送信します
そのように見えるかもしれませんが、実際には、ドライバーが通信するノードを選択する非ランダムな方法があります。このノードは「コーディネーターノード」と呼ばれ、通常、最小(最も近い)「ネットワーク距離」に基づいて選択されます。クライアント要求は実際にはどのノードにも送信でき、最初はドライバーが知っているノードに送信されます。ただし、クラスターのトポロジーを接続して理解すると、「より近い」コーディネーターに変わる可能性があります。
クラスター内のノードは、 Gossip Protocol を使用して相互にトポロジー情報を交換します。 gossiperは毎秒実行され、すべてのノードが最新の状態に保たれるようにします Snitch 設定したもの。スニッチは、各ノードが属するデータセンターとラックを追跡します。
このように、コーディネーターノードには、各ノードが各トークン範囲を担当するデータもあります。コマンドラインからnodetool ring
を実行すると、この情報を表示できます。ただし、vnodeを使用している場合、256(デフォルト)のすべての仮想ノード上のデータが画面上ですぐにフラッシュするため、確認するのは難しくなります。
そこで、船の乗組員の名前を追跡するために使用しているテーブルがあり、マルコムレイノルズを調べたいと仮定します。このクエリの実行:
SELECT token(firstname),firstname, id, lastname
FROM usersbyfirstname WHERE firstname='Mal';
...この行を返します:
token(firstname) | firstname | id | lastname
----------------------+-----------+----+-----------
4016264465811926804 | Mal | 2 | Reynolds
nodetool ring
を実行することで、このトークンを担当するノードを確認できます。
192.168.1.22 rack1 Up Normal 348.31 KB 3976595151390728557
192.168.1.22 rack1 Up Normal 348.31 KB 4142666302960897745
またはさらに簡単に、nodetool getendpoints
を使用してこのデータを表示できます。
$ nodetool getendpoints stackoverflow usersbyfirstname Mal
Picked up Java_TOOL_OPTIONS: -javaagent:/usr/share/Java/jayatanaag.jar
192.168.1.22
詳細については、上記のリンクされたアイテムの一部を確認するか、nodetool gossipinfo
を実行してください。
Cassandraは一貫したハッシュを使用して、各パーティションキーをトークン値にマップします。各ノードはトークン値の範囲をprimary範囲として所有しているため、可能なすべてのハッシュ値が1つのノードにマップされます。その後、追加のレプリカは体系的な方法で保持され(リング内の次のノードなど)、ノードにセカンダリ範囲として保存されます。
クラスター内のすべてのノードは、どのノードがどのデータセンターにあるか、リング内にあるか、各ノードが所有するトークン範囲など、クラスター全体のトポロジを認識しています。ノードは、ゴシッププロトコルを使用してこの情報を取得および維持します。
読み取り要求が着信すると、接続されたノードが読み取りのコーディネーターになります。要求されたパーティションのレプリカを持つノードを計算し、整合性レベルを満たすために必要な数のノードを選択します。次に、それらのノードにリクエストを送信し、それらの応答を待機し、列のタイムスタンプに基づいて結果をマージしてから、結果をクライアントに送り返します。
Cassandraは、partitionerによってトークン値にマッピングされるpartition keyに基づいてデータを検索します。トークンは有限トークンリング値の範囲の一部であり、リングの各部分はクラスター内のノードによって所有されます。特定のトークンの範囲を所有するノードは、そのトークンのプライマリと呼ばれます。レプリカは、データ複製戦略によって選択されます。基本的に、これはトークンリング内を時計回りに進み、プライマリから開始し、必要なレプリカの数に応じて停止することで機能します。
実現することが重要なのは、クラスター内の各ノードが上記のロジックに基づいて特定のキーを担当するノードを識別できることです。クラスターに値が書き込まれるたびに、要求を受け入れるノード(コーディネーターノード)は、書き込みを実行する必要があるノードをすぐに認識します。
複数のデータセンターの場合、すべてのキーはすべてのDCでパーティショナーによって決定されたまったく同じトークンにマップされます。 Cassandraは、各DCおよび各DCのレプリカに書き込みを試みます。