ザ-バッド : パーティショニング
最初に慣れるのは難しいことの1つは、行にまたがるインデックスクエリがないと(非常に)悪いことになる可能性があることです。 しかし、私たちのストレージモデルに戻って考えると、それは驚くべきことではありません。 Cassandraがホスト間で行を分散するために使用する戦略は、パーティション分割と呼ばれます。
パーティショニングは、行キーの範囲を”トークンリング”に割り当て、行キーの範囲のセグメント(つまりパーティション)の責任を各ホストに割り当てる行為です。 クラスターを”トークン”で初期化したときに、おそらくこれを見たことがあります。 トークンはホストにトークンリングに沿った場所を与え、トークン範囲のセクションの責任を割り当てます。 パーティショニングは、rowkeyをトークン範囲にマッピングする行為です。
プライマリパーティショナーには、ランダムと順序保存の2つがあります。 彼らは適切に命名されています。 RandomPartitionerはrowkeysをトークンにハッシュします。 RandomPartitionerを使用すると、トークンはrowkeyのハッシュになります。 これは、一連のノードにデータを均等に分散させるのに適していますが、rowkeyスペースの範囲を照会することは非常に困難です。 「Start rowkey」値と「end rowkey」値のみから、Cassandraは必要なトークンスペースの範囲を判断できません。 本質的には、クエリに答えるために「テーブルスキャン」を実行する必要があり、Cassandraの「テーブルスキャン」は、クエリに答えるために各マシン(適切なハッシュ関数
良い:セカンダリインデックス
Cassandraは、セカンダリインデックスにネイティブなインデックス作成メカニズムを提供します。 セカンダリインデックスは、列の値から機能します。 列ファミリにセカンダリインデックスを宣言するとします。 Datastaxには、使用法に関する優れた文書があります。 内部では、Cassandraはインデックスとして”隠された列ファミリ”を維持しています。 (詳細についてはEd Anuffのプレゼンテーションを参照してください)Cassandraはいずれかのノードで列値情報を維持せず、セカンダリインデックスは(rowkeysではなく)columns valueに さらに、セカンダリインデックスは、基数の高いセットには推奨されません。 私はまだ見ていませんが、これは”隠し列ファミリ”内で使用されているデータモデルのためだと思います。 非表示の列ファミリが一意の値ごとに行を格納する場合(rowkeysを列として)、行をスキャンしてクエリの範囲内にあるかどうかを判断することを意味し
エドさんのプレゼンから:
- 高い基数値(タイムスタンプ、誕生日、キーワードなど)にはお勧めしません。)
- は、クエリ内で少なくとも一つの等価比較を必要とします-より小さい/より大きい/範囲のクエリには適していません
- ソートされていない-結果は、クエリ値の順ではなく、トークン順になります
- データ型の検索に限定され、Cassandraはネイティブに理解しています
すべてのことを言って、セカンダリインデックスは箱から出して動作し、我々は単純な値でそれらを使用して良い成功を収めてきました。
醜い:日曜大工(DIY)/ワイド行
今、美しさは見る人の目にあります。 NoSQLの素晴らしい点の1つは、シンプルさです。 構造は単純です:キースペース、列ファミリ、行と列。 しかしそれを簡単に保つことは時々あなた自身の手に事を取る必要があることを意味する。
これは、ワイド行インデックスの場合に当てはまります。 Cassandraのストレージモデルを利用すると、各行キーがインデックス内の列になる独自のインデックスを簡単に構築できます。 これはあなたの頭を動かすのが難しいことがありますが、郵便番号のすべてのユーザーを選択するケースがあると想像してみましょう。 メインのユーザー列ファミリはuseridでキー設定され、郵便番号は各ユーザー行の列です。 二次索引を使用できますが、かなりの数の郵便番号があります。 代わりに、”idx_zipcode”と呼ばれる単一の行を持つ列ファミリを維持することができます。 次に、”zipcode_userid”という形式のこの行に列を書き込むことができます。 列はソートされた順序で格納されるため、「18964」で始まるすべての列をクエリするのが高速です(たとえば、18964_と18964_ZZZZZZを開始値と終了値として使用できます)。
このアプローチの明らかな欠点の1つは、行がホスト上で自己完結型であることです。 (レプリカを除く)これは、すべてのクエリが単一のノードにヒットすることを意味します。 私はまだこれのための良い答えを見つけていません。