Cassandraがカーディナリティの高い列にインデックスを作成しないことを推奨するのはなぜですか?


10

Cassandraのドキュメントには、

次の状況ではインデックスを使用しないでください。

  • カーディナリティの高い列では、大量のレコードに対して少数の結果をクエリするため。以下のカーディナリティの高い列インデックスの使用に関する問題を参照してください。

それは続きます、

カーディナリティの高い列にインデックスを作成すると、個別の値が多くなり、フィールド間のクエリでシークが多くなり、結果が非​​常に少なくなります。10億曲の表では、アーティストではなくライター(通常は各曲に固有の値)で曲を検索するのは、非常に非効率的です。Cassandraビルトインインデックスを使用する代わりに、テーブルをインデックスの形式として手動で維持する方が効率的です。一意のデータを含む列の場合、インデックス付きの列を持つテーブルへのクエリ量が中程度で一定の負荷がかかっていない限り、便宜上インデックスを使用するとパフォーマンスが向上することがあります。

しかし、実際には決して質問に答えることはできません。なぜ非効率なのでしょうか。「手動でテーブルをインデックスの形式として維持する」が何を意味するのか私にはわかりません。ただし、「...クエリの量が中程度である限り、便宜上インデックスを使用するとパフォーマンスが向上する場合があります...」とは多少矛盾します。

これは、PKをいつ、どこで使用できるかを教えようとしているだけですか?非効率とは何ですか?私の理解では、インデックスにヒットするクエリはクラスター内のすべてのノードをクエリする必要があり、各ノードはローカルインデックスでルックアップを実行し、結果が集計されます。ロットの最も遅いノードを待たなければならないため、ネットワークの遅延を支払うことを除いて、これは必ずしも高価ではありません(各インデックスの検索はかなり安価でなければなりません)。ここで何か不足していますか?

しかし、私が膨大な数のアイテムを含むコレクションを持っている場合-まれに-異なるがほとんど一意の属性で検索する必要がある…これは適切な用途ですよね?

veryみんな?IDKは、レプリケーションが3のレプリケーション係数でクラスタの1/3をヒットできるかどうかを意味しますか?

回答:


6

Cassandraインデックス(つまり、プライマリキーではなく「セカンダリインデックス」)では、クエリに応答するために各ノードが独自のローカルデータをクエリする必要があります(Cassandra セカンダリインデックスのFAQを参照)。これらのインデックスも、バックグラウンドプロセスを使用して作成されます。このバックグラウンド処理は、インデックスヒットに関して偽陰性(またはミスに関して偽陽性)を返す可能性があることを意味します。

これは、カーディナリティの高い列では、その列からの変化率(つまり、追加/削除)が非常に高くなる可能性があることを意味します。したがって、その変化率がバックグラウンドプロセスによるインデックスの更新より速い場合、インデックスの使用は「非効率的」です(インデックスは、アプリケーションが必要とするよりも多くの作業を実行しており、多くの場合、間違った答えが返される可能性があります)。 。

クエリの正確さに関して、より効率的なアプローチは、セカンダリインデックスではなく 2番目のテーブルを維持することです。インデックスとは対照的に、テーブルは他のテーブルと同じように扱われます。アプリケーションが期待するクエリ結果をアプリケーションに提供する可能性が高くなります。欠点は、テーブルを維持していることを指標として、これで、アプリケーションの制約が(、カサンドラ「セカンダリインデックス」に対して、されているすなわち、アプリケーションコードが今持っているために知っている「インデックス」テーブルから/削除行を挿入し、そして アプリケーションレベルの「調整」を介して2つのテーブルの同期を維持するため)。

お役に立てれば!


インデックスはバックグラウンドプロセスを使用して作成されるので、少し見苦しいです。誤検知はユーザーに表示されると思いますか?(私はそれらがどうなるかわかりません。)私がまだ質問する唯一の部分は、「これは、カーディナリティの高い列では、その列からの変化率(つまり、追加/削除)がかなり高くなります。」— BGインデックスの構築に関連して、変化率が悪い理由がわかりますが、それでも、カーディナリティの高さがそれとどのような関係があるのか​​わかりません。(確かに、カーディナリティの低い列でも同じ運命を
たどる

はい、カーディナリティの低い列も同じ運命をたどります。私の考えは少しあいまいだったと認めます。私がされたと仮定すると、高カーディナリティのインデックスが変更(したがって可能性が高い偽陽性/陰性の結果を示すように)の高い率を持っている可能性が高いだろうと。最も重要なのは、カーディナリティではなく、(バックグラウンドのインデックス作成プロセスに対する)変化率です。
カスタリア2016年

2

いくつかの用語:親テーブルは、インデックスが作成されるテーブルです。セカンダリインデックステーブルは、別のテーブルのインデックスを維持するために作成されるテーブルです。

セカンダリインデックステーブルのデータは、親テーブルのデータと同じノードに格納されます。Cassandraパーティショナーは、インデックステーブルデータを分割および配布しません。したがって、インデックス列でルックアップを実行する場合は、データを含むレプリカノードだけでなく、すべてのノードがクエリされます。(コーディネーターノードはデータの場所がわかりません)https://www.datastax.com/dev/blog/cassandra-native-secondary-index-deep-dive

ssnやその他の一意のIDなどのカーディナリティの高い列の場合、主キーとの1対1のマッピングがあります。そのような列にインデックスを作成すると、データはノードのレプリケーションファクタ数に存在しますが、ルックアップコールはすべてのノードで実行されます。最良の場合、コーディネーターはデータを含むノードに直接アクセスし、整合性レベルが満たされると結果が得られます。最悪の場合、探しているデータがインデックスに存在しない場合、すべてのノードが応答してデータが存在しないことがわかるまで待機します。そのため、セカンダリインデックステーブルに対するすべての検索呼び出しで、すべてのノードがヒットします。テーブルが通常のC *テーブルである場合は、すべての検索呼び出しでヒットするノードのレプリケーションファクター数のみと比較してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.