SAIに関するよくある質問
このFAQを使用して、よくある質問への回答を見つけ、Storage-Attached Indexing(SAI)のヘルプを入手してください。
SAIとは何ですか?
Storage-Attached Indexing(SAI)は、Cassandraデータベース向けのスケーラブルでグローバルに分散されたインデックスです。SAIは、
-
オープンソースのSSTable Attached Secondary Indexes(SASI)のストレージ接続アーキテクチャと、
-
高度に最適化された多数のオンディスクインデックス構造を組み合わせています。
どのデータベースがサポートされていますか?
現在、サポートされているデータベースはCassandra 5.0のみです。
データベース、キースペース、および1つ以上のテーブルを作成した後、`CREATE INDEX ... USING 'sai'`を使用して、テーブルに1つ以上のSAIインデックスを定義します。 Cassandraデータベースの場合は、`cqlsh`を使用します。 どちらも同じ`CREATE INDEX ... USING 'sai'`コマンドを使用できます。 SAIクイックスタートを参照してください。
SAIで使用する必要がある構成設定は何ですか?
ほとんどのインデックス環境と比較して、SAIの構成と関連設定ははるかに簡単です。要点
-
`--XX:MaxDirectMemorySize`を増やし、OSやその他のメモリ内構造用に約15〜20%のメモリを残します。
-
cassandra.yamlで、`file_cache_size_in_mb`をその値の75%に明示的に設定します。
-
読み取り/書き込みの混在した負荷の高いワークロードでは、
-
`range_request_timeout_in_ms`を減らし、
-
`write_request_timeout_in_ms`を増やすことができます。
-
-
`memtable_flush_writers`の値が低すぎると、書き込みが停止することがあります。 環境でこれが発生した場合は、`memtable_flush_writers`を増やしてください。
メモリ以外に、SAIはコンパクションスループットやコンパクションエグゼキュータなど、Cassandraと同じ調整可能なパラメータを使用します。 これは書き込みパフォーマンスに影響します。 読み取りパフォーマンスに関しては、チャンクキャッシュの使用を最大限にすることでSAIの読み取りが向上します。これは、すべてのオンディスクインデックスコンポーネントがこのメカニズムを介してアクセスされるためです。 SAIインデックスの設定を参照してください。
SAIはどのようなコンピューティングの課題を解決しますか?
開発者はしばしば、「Apache Cassandraのパーティションキー以外の追加フィールドをどのようにクエリできますか?」と質問します。
SAIは、複合パーティションキーの一部など、テーブルの列に基づいて効率的なインデックスを実装します。 SAI以前は、クラスタリングキーにインデックスを付けることはできましたが、複合パーティションの一部にインデックスを付けることはできませんでした。 SAIの開発は、セカンダリインデックスの作成によって効率的でシンプルなフィルタリングを実現するというSASIの目標に触発されました。
SAIは、特定のクエリパターンに対応するためだけにカスタムテーブルを作成する必要がないため、データモデリングも容易にします。 最も自然なテーブルを作成し、そのテーブルにのみ書き込み、好きな方法でクエリを実行できます。
SAIを使用する利点は何ですか?
SAIを使用すると、同じデータベーステーブルに複数のインデックスを定義できます。 各SAIインデックスは、テーブルの任意の列に基づ seます。例外:パーティションキーが1つの列のみで構成されている場合は、パーティションキーに基づいてSAIインデックスを定義する必要はありません。 この場合、SAIは `invalid query`メッセージを発行します。 また、テーブルの複合パーティションキーの単一の列を使用してSAIインデックスを定義することもできます。 複合パーティションキーとは、パーティションが2つ以上の列に基づいていることを意味します。 この場合、SAIインデックスでは、複合パーティションキーを構成する列の1つだけを指定します。
開発者にとって、SAIは、非PrimaryKey列をクエリするために非正規化データを複製する必要があるなど、以前のいくつかの問題点を解消します。
運用者にとって、SAIには、インデックスに必要なディスク容量が大幅に少ないこと、障害点が少ないこと、SAIの簡素化されたアーキテクチャによる稼働時間の容易さ、保護するデータのコピーが少ないことなど、いくつかの利点があります。
SAIは完全な検索ソリューションですか?
SAIはエンタープライズ検索エンジンではありません。 SAIは同じ機能の一部を提供しますが、テキストベースの検索の完全な代替ではありません。 SAIは本質的にフィルタリングエンジンであり、クエリ固有の複数のテーブルの保守に大きく依存するデータモデリングとクライアントアプリケーションを簡素化します。
SAIとテキストベース検索のスキーマ管理はどのように比較されますか?
SAIはインデックスであり、検索エンジンではありません。 テキストベースの検索とは異なり、SAIはスキーマ管理を必要としません。 SAIの構成はよりシンプルであり、cassandra.yamlなどの既存のデータベースパラメータで調整されます。 SAIでは、ブートストラップ中に書き込みを受け入れるコミットログはありません。 SAIは、データベース構成を読み取るためにブートストラップを待つ必要はありません。 SAIでは、スキーマ/インデックスオプションはインデックスメタデータに存在し、ネイティブデータベーススキーマ管理によって処理されます。
SAI機能の使用方法を教えてください。
Storage-Attached Indexingは、クエリが完全にCQLベースです。 機能は、意図的にシンプルで使いやすく設計されています。
概要レベルでは、SAIインデックスは
-
CQL `CREATE INDEX ... USING 'sai'`コマンドと`DROP INDEX`コマンドを使用して、列ごとに作成および削除されます。 SAIクイックスタートから始めます。
-
nodetoolを介して再構築およびバックアップされます。 nodetoolを参照してください。
-
nodetool、CQL仮想テーブル、システムメトリック、およびJMXの組み合わせによって監視されます。 SAIインデックスの監視を参照してください。
データベーステーブルのどの列にSAIインデックスを基づ seますか?
各SAIインデックスは、任意のテーブル列に定義します。 例外:パーティションキーが1つの列のみで構成されている場合は、パーティションキーに基づいてSAIインデックスを定義する必要はありません。 この場合、SAIは`invalid query`メッセージを発行します。
テーブルの複合パーティションキーにある単一の列を使用してSAIインデックスを定義することもできます。 複合パーティションキーは、パーティションが2つ以上の列に基づいていることを意味します。 この場合、SAIインデックスとともに、複合パーティションキーを構成する列の1つだけを指定します。
コレクションマップを使用すると、`keys`、`values`、および`entries`をマップタイプとして指定することで、同じ列に1つ以上のSAIインデックスを定義できます。 SAIは、`list`および`set`コレクションもサポートしています。
SAIインデックスを持つデータベーステーブルのCQLクエリでは、`CONTAINS`句は以下でサポートされ、以下に固有です。
|
同じ列でSAIインデックスを`DROP`して再作成すると、読み取り操作がブロックされますか? また、インデックスステータスを確認する方法はありますか?
SAIインデックスを`DROP` /再作成する場合、インデックスを使用しないクエリの入力がブロックされることはありません。 ただし、ビルドが完了してクエリ可能になるまで、(同じ列に基づく)そのSAIインデックスを使用することはできません。 特定のインデックスの現在の状態を判断するには、`system_views.indexes`仮想テーブルにクエリを実行します。 例
SELECT is_queryable,is_building FROM system_views.indexes WHERE keyspace_name='keyspace'
AND table_name='table' AND index_name='index';
仮想テーブルおよびSAIインデックスとSSTableの仮想テーブルを参照してください。
SAIインデックスで使用される書き込みパスと読み取りパスは何ですか?
SAIは、書き込まれたときにMemtableとSSTableにインデックスを付け、読み取り時にそれらのインデックス間の違いを解決します。 SAI書き込みパスと読み取りパスを参照してください。
SAIはどのオンディスクインデックス形式をサポートしていますか?
SAIは、以下に最適化された2つのオンディスクインデックス形式をサポートしています。
-
**文字列**の完全一致とあいまい一致。
-
文字列は、ポスティング(用語/行のペア)リストと組み合わせて、トライ木データ構造を使用してディスク上でインデックス化されます。トライ木はヒープフレンドリーであり、用語の文字列プレフィックス圧縮を提供し、決定性有限オートマトンとして表現できる任意のクエリと一致させることができます。この機能は、ディスク上のフットプリントを最小限に抑え、単純なトークンスキップをサポートします。
-
-
数値型および非リテラル型に対する等価および範囲クエリ。
-
数値とその他の非リテラルCQL型(
timestamp
、date
、UUID
)は、k次元木を使用してディスク上でインデックス化されます。k次元木は、1つ以上の次元で高速なルックアップと、値とポスティングの両方の圧縮を提供するバランスの取れた構造です。
-
SAIインデックスのディスクフットプリントのオーバーヘッドは何ですか?
SAIは、他のネイティブまたはボルトオンのCassandraインデックスソリューションと比較して、ディスク使用量が大幅に少なくなります。SAIは、インデックスされていないデータと比較して、追加の20〜35%のディスク使用量を生成します。SAIのディスク使用量は、基礎となるデータモデルとインデックス化される列の数に大きく依存します。
SAIインデックスでサポートされている列データ型は何ですか?
サポートされている型は、ASCII, BIGINT, DATE, DECIMAL, DOUBLE, FLOAT, INET, INT, SMALLINT, TEXT, TIME, TIMESTAMP, TIMEUUID, TINYINT, UUID, VARCHAR, VARINT
です。
|
SAIはコレクション列のインデックスをサポートしていますか?
はい。SAIは、map
、list
、set
タイプのコレクションをサポートしています。次のトピックを参照してください。
SAIインデックスを持つデータベーステーブルのCQLクエリでは、`CONTAINS`句は以下でサポートされ、以下に固有です。
|
サポートされているクエリ演算子は何ですか?
SAIインデックスを持つテーブルに対するクエリの場合
-
数値:
=
、<
、>
、⇐
、>=
、AND
、OR
、IN
-
文字列:
=
、CONTAINS
、CONTAINS KEY
、AND
、OR
、IN
サポートされていないクエリ演算子は次のとおりです。
-
文字列または数値:
LIKE
例
SELECT * FROM cycling.cyclist_semi_pro WHERE registration > '2010-01-01' AND registration < '2015-12-31' LIMIT 10;
SELECT * FROM audit WHERE text_map CONTAINS KEY 'Giovani';
SAIコレクションのマップ、リスト、およびセットを利用する |
SAIのCREATE INDEX
コマンドでは、どのようなオプションが使用できますか?
WITH OPTIONS
句を使用して、SAIがインデックスの大文字と小文字の区別と特殊文字をどのように処理するかを指定します。たとえば、文字列列lastname
が与えられた場合
CREATE INDEX lastname_sai_idx ON cycling.cyclist_semi_pro (lastname)
USING 'sai' WITH OPTIONS =
{'case_sensitive': 'false', 'normalize': 'true', 'ascii': 'true'};
SAIには CREATE CUSTOM INDEXとSAIクイックスタートトピックの例を参照してください。 |
SAIは複合インデックスをサポートしていますか?つまり、複数の列に単一のインデックスを作成できますか?
いいえ。SAIインデックスと列は1対1でマッピングされます。ただし、特定のテーブルの各列に個別のインデックスを作成できます。また、SAIは単一の読み取りクエリ内で複数の定義済みインデックスを使用できます。
SAIメモリ使用量メトリックを表示するにはどうすればよいですか?
SAIのメモリフットプリントは、JVMヒープとチャンクキャッシュに分割されます。ヒープはmemtableインデックスを格納し、チャンクキャッシュは最近アクセスされたディスク上のインデックスコンポーネントと他のSSTableコンポーネントを格納します。SAIは、ヒープとチャンクキャッシュの両方のメトリックを提供します。各インデックスについて、SAIは、ディスク上のデータ構造で使用されるメモリのバイト単位のサイズとディスク使用量を決定するためのメトリックも提供します。インデックスグループメトリックを参照してください。SAIは、ディスク使用量、基本テーブルのディスク使用量の割合、進行中のインデックスビルド、および関連メトリックを可視化するテーブル状態メトリックも提供します。テーブル状態メトリックを参照してください。
読み取りクエリにSAI列を追加することのパフォーマンスへの影響は何ですか?いくつのAND
句を追加できますか?
1つのクエリで使用できるインデックス列の数に制限はありません。 cassandra.yamlのsai_indexes_per_table_failure_threshold
設定は、単一のテーブルで許可されるSAIインデックスの最大数を制御します(デフォルトでは10)。ただし、複数のインデックス付き列に対してクエリを実行すると、処理されるインデックスコンポーネントの数が増加することに関連するコストが発生します。クエリで複数のインデックス付き列を評価する場合、SAIはワークフロー(1:トラバース。2:マージ。3:インターセクト)を実行し、最終的に複数のmemtableとSSTableからデータを統合します。
クエリでは、ANDクエリは最大2つのSAIインデックスを処理します。クエリで3つ以上のSAIインデックスが使用されている場合、SAIは残りの句に対してポストフィルタリングを実行します。 |
関連情報については、一致ストリーミングとポストフィルタリングの例を参照してください。
SAI書き込み操作は非同期ですか、それともSAIはユーザーに書き込みを認識するまで待機しますか?
SAIの書き込みパスは実際には非常にシンプルです。インデックスは、memtableとSSTableの両方でデータと共存します。書き込みがクライアントに認識されると、データはすでにインデックス化されています。これは**同期**プロセスです。 memtableがフラッシュされると、インデックスもフラッシュされます。SAI書き込みパスと読み取りパスを参照してください。
ディスク上のインデックスコンポーネントは、SSTableごとのインデックスファイルと列ごとのインデックスファイルに分割されます。列インデックスは、プライマリキーまたはトークンを格納しません。代わりに、圧縮可能な行IDを格納します。 SSTableごとのインデックスファイルは、列インデックスの行IDをバッキングSSTableにリンクします。このSAI設計により、単一のSSTable内のすべての列インデックスがSSTableごとのインデックスファイルを共有できるため、ディスクフットプリントをさらに削減できます。
SAIインデックスを使用した列カーディナリティに関するガイドラインは何ですか?
列のカーディナリティは、レプリカ間の範囲クエリに関して読み取りパフォーマンスに影響を与える可能性があります。クレジットカード番号などのカーディナリティの高い列の値に一致する行の数は、非常に少数のノード(または1つのノードに限定される)に隔離される可能性が高く、カーディナリティの低い列の値に一致する行は、多数のノードに存在する可能性が高くなります。クエリがパーティションキーを指定しない場合、Cassandraコーディネーターはトークンリングをスキャンし、エンドポイント(ノード)ごとにトークン範囲をグループ化します。次に、コーディネーターは、参加しているすべてのエンドポイントに対して読み取りコマンドを同時に実行します。インデックス付き列のカーディナリティが非常に高い最悪のケースでは、一致が見つかる前にクラスター全体のスキャンが必要になる場合があります。カーディナリティの低い列の場合、LIMIT
がターゲット列の値の数よりも大きい場合、CassandraはLIMIT
を満たすことができないと判断する前に、すべてのレプリカを再度検索する必要があることに注意してください。この場合、Cassandraは一致する結果の数のみを返します。
SAIがポストフィルタリングを適用する状況は何ですか?
SAIは、さまざまなシナリオでポストフィルタリングを適用します。たとえば、単純なテーブルと、2つの非PK列のうちの1つだけのSAIインデックスを考えてみます。
CREATE KEYSPACE test WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': 1};
CREATE TABLE test.mytable (id int PRIMARY KEY,
col1 text,
col2 timestamp);
CREATE CUSTOM INDEX mytable_col1_idx ON test.mytable (col1) USING 'StorageAttachedIndex';
次のようなクエリが与えられた場合
SELECT * FROM test.mytable WHERE col1 = 'hello world' and col2 < toTimestamp(now()) ALLOW FILTERING;
このクエリの場合、Cassandraは最初にインデックス付き列(col1
)で検索を絞り込み、次にcol2
でポストフィルタリングを適用します。(ALLOW FILTERING
句は注意して使用してください。)このシナリオでは、追加のレプリカラウンドトリップは必要ありません。 col2
のポストフィルタリングはレプリカ自体で実行されます。
ポストフィルタリングが関係するもう1つのケースは、3つ以上のSAIインデックスを含むクエリを構築する場合です。 AND
クエリに関する関連FAQを参照してください。
静的列に基づいてSAIインデックスを作成できますか?
はい。たとえば、プライマリキーcustomer_id
と、各顧客のaddress
、phone_number
、date_of_birth
を含む静的列を持つtransaction_by_customer
テーブルを考えてみます。次のようなクエリが与えられた場合
SELECT * from transaction_by_customer where customer_id = 'xyz123';
100,000個のtransaction_by_customer
行がある場合、これらの3つの静的フィールドを定義したため、このクエリは、書き込みによって顧客ごとの値(address
、date_of_birth
)がすべての行に挿入された環境と比較して、ディスク容量が大幅に少ないテーブルに対して実行されます。
SAIは、静的列に基づいてインデックスを作成するオプションと利点を提供すると同時に、テーブルスペースを節約するという利点も実現します。 |
インデックス付き文字列の場合、SAIは列データのUnicode文字をどのように処理しますか?
文字列列に基づいてSAIインデックスを作成する場合、SAIに列データでUnicode正規化を実行させる場合は、normalize
オプションをtrue
に設定します。SAIは、Normalization Form C(NFC)Unicodeをサポートしています。 true
に設定すると、SAIは、特定のUnicode文字の異なるバージョンを単一のバージョンに正規化し、インデックス内のすべてのマークと記号を保持します。たとえば、SAIは文字Å(U + 212B)をÅ(U + 00C5)に変更します。CREATE CUSTOM INDEXを参照してください。