0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Cassandra】バージョン4.0~5.0で追加された機能の紹介

Last updated at Posted at 2024-09-10

はじめに

Apache Cassandraの最新メジャーバージョンである5.0.0が2024/09/05にめでたくリリースされました。
メジャーバージョンアップによって多くの新機能が追加されており、その中からいくつかピックアップして紹介していきたいと思います。

また、5.0.0のリリースに伴い3.0.xと3.11.xのバージョンがEOLを迎えることになりました。(Apache-Cassandra-3.0.x-and-3.11.x-End-of-Life-Announcement)
2015年に3.0.x、2017年に3.11.xがリリースされてから長期に渡り利用されてきたバージョンとなりますが、今後はバージョンアップを考えていく必要があります。
3.0.x/3.11.xからのバージョンアップの際には一度4.0.x/4.1.xを経由する形になると思いますので、今回は4.0.x/4.1.xで追加された機能もあわせて紹介していきたいと思います。

4.0.x での新機能

4.0.xでの新機能にはノード間のメッセージング通信の改善やZero Copy StreamingによるStreamingの改善などがありますが、今回はロギング機能の強化を紹介します。

Audit Logging

Audit LoggingではCassandraへのログイン試行やCQLリクエストを成功と失敗を含めてログに出力することができます。
Audit LogにはCQLに関係する操作は記録されますがサーバー上の設定ファイル(cassandra.yamlなど)の変更やCassandra運用ツールであるnodetoolコマンドによる操作は記録されないため注意が必要です。

Audit Loggingの設定

cassandra.yamlにAudit Loggingに関する設定項目があります。
デフォルトでは以下のようにenabled: falseとなっているため無効になっております。
こちらの設定項目でkeyspaceやユーザー、操作カテゴリをロギング対象に含めるか除外するかを設定することができます。

# Audit logging - Logs every incoming CQL command request, authentication to a node. See the docs
# on audit_logging for full details about the various configuration options.
audit_logging_options:
    enabled: false
    logger:
      - class_name: BinAuditLogger
    # audit_logs_dir:
    # included_keyspaces:
    # excluded_keyspaces: system, system_schema, system_virtual_schema
    # included_categories:
    # excluded_categories:
    # included_users:
    # excluded_users:
    # roll_cycle: HOURLY
    # block: true
    # max_queue_weight: 268435456 # 256 MiB
    # max_log_size: 17179869184 # 16 GiB
    ## archive command is "/path/to/script.sh %path" where %path is replaced with the file being rolled:
    # archive_command:
    # max_archive_retries: 10

Audit Loggingを有効/無効にする

先ほどの設定ファイルでenabled: falseと設定するとCassandra起動時にAudit Loggingが有効となります。
また、nodetool enableauditlogコマンドを使用することでノードを再起動せずにAudit Loggingを有効化することも可能です。

無効にする場合はnodetool disableauditlogコマンドを使用します。
Audit Loggingはそれぞれのノードごとに設定されるためクラスタ全体で設定する場合は全台で有効化する必要があります。

Audit Logの確認

デフォルトのロガーであるBinAuditLoggerを設定した場合は、Audit Logを表示するためのauditlogviewerというツールを利用してAudit Logを確認します。
FileAuditLoggerを設定した場合はAudit Logがそのまま確認できる形式となっております。

出力されるAudit Logの例は以下のようになります。
(ログイン->SELECTクエリ->ログアウト->ログイン失敗)

Type: audit
LogMessage: user:cassandra|host:<hostname>/<IPアドレス>:7000|source:/<IPアドレス>|port:35114|timestamp:1725778217547|type:LOGIN_SUCCESS|category:AUTH|operation:LOGIN SUCCESSFUL
Type: audit
LogMessage: user:cassandra|host:<hostname>/<IPアドレス>:7000|source:/<IPアドレス>|port:35114|timestamp:1725778244932|type:SELECT|category:QUERY|ks:sample|scope:t|operation:SELECT * FROM sample.t WHERE id=0;
Type: audit
LogMessage: user:null|host:<hostname>/<IPアドレス>:7000|source:/<IPアドレス>|port:37664|timestamp:1725778258798|type:LOGIN_ERROR|category:AUTH|operation:LOGIN FAILURE; Provided username cassandra and/or password *******

Full Query Logging

Full Query Loggingでは成功したCQLリクエストを記録し、ログからクエリを再実行することができます。
Audit Loggingと異なり失敗したクエリなどは記録されませんが、デバッグやパフォーマンステストなどで活用できます。

Full Query Loggingの設定

cassandra.yamlにFull Query Loggingに関する設定項目があります。
デフォルトでは以下のようにコメントアウトされ無効の状態になっております。
ノードの起動時に有効化する場合はコメントアウトを外し、最低限log_dirを指定する必要があります。

# default options for full query logging - these can be overridden from command line
# when executing nodetool enablefullquerylog
#full_query_logging_options:
   # log_dir:
   # roll_cycle: HOURLY
   # block: true
   # max_queue_weight: 268435456 # 256 MiB
   # max_log_size: 17179869184 # 16 GiB
   # archive command is "/path/to/script.sh %path" where %path is replaced with the file being rolled:
   # archive_command:
   # max_archive_retries: 10

Full Query Loggingを有効/無効にする

Audit Loggingと同様にこちらもnodetool enablefullquerylogコマンドを使用することでノードを再起動せずにFull Query Loggingを有効にできます。
ノード起動時にcassandra.yamlでlog_dirを指定していない場合は--path <cassandraが操作可能な権限を持つディレクトリ>オプションを指定する必要があります。

無効にする場合はnodetool disablefullquerylogコマンドを使用します。
Full Query Loggingもそれぞれのノードごとに設定されるためクラスタ全体で設定する場合は全台で有効化する必要があります。

Full Query Logの確認

Query Logを確認する際にはfqltoolコマンドを利用します。
こちらには以下のコマンドが用意されています

  • fqltool dump
    • 取得したQuery Logを表示する
  • fqltool replay
    • 取得したQuery Logを元にクエリをリプレイする
  • fqltool compare
    • replay コマンドで生成された結果を比較する

出力されるQuery Logは以下のようになります。
※ log_dir: /var/log/cassandra/fql で設定しています

fqltool dump /var/log/cassandra/fql/

...

Type: single-query
Query start time: 1725865322651
Protocol version: 4
Generated timestamp:-9223372036854775808
Generated nowInSeconds:-2147483648
Query: CREATE KEYSPACE querylogkeyspace WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};
Values:

Type: single-query
Query start time: 1725865332220
Protocol version: 4
Generated timestamp:-9223372036854775808
Generated nowInSeconds:-2147483648
Query: CREATE TABLE querylogkeyspace.t (id int,k int,v text,PRIMARY KEY (id));
Values:

Type: single-query
Query start time: 1725865340952
Protocol version: 4
Generated timestamp:-9223372036854775808
Generated nowInSeconds:1725865340
Query: INSERT INTO querylogkeyspace.t (id, k, v) VALUES (0, 0, 'val0');
Values:

Type: single-query
Query start time: 1725865348750
Protocol version: 4
Generated timestamp:-9223372036854775808
Generated nowInSeconds:1725865348
Query: INSERT INTO querylogkeyspace.t (id, k, v) VALUES (0, 1, 'val1');
Values:

Type: single-query
Query start time: 1725865367722
Protocol version: 4
Generated timestamp:-9223372036854775808
Generated nowInSeconds:1725865367
Query: SELECT * FROM querylogkeyspace.t;
Values:

Query Logからのリプレイ

※ 私の環境ではKeyspaceとTable作成のリプレイがうまくできなかったため、Tableを再作成しデータはない状態からリプレイしました

一度KeyspaceとTableを作り直す

DROP KEYSPACE querylogkeyspace;
CREATE KEYSPACE querylogkeyspace WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};
CREATE TABLE querylogkeyspace.t (id int,k int,v text,PRIMARY KEY (id));
SELECT * FROM querylogkeyspace.t;
 id | k | v
----+---+---

リプレイコマンド用のディレクトリを作成する

mkdir -p /var/log/cassandra/fql/results
mkdir -p /var/log/cassandra/fql/queries
chown -R cassandra:cassandra /var/log/cassandra/fql/

上記で生成されたログを使いリプレイを実施する

fqltool replay --keyspace querylogkeyspace --results /var/log/cassandra/fql/results --store-queries /var/log/cassandra/fql/queries --target <user>:<password>@<hostname>:9042 /var/log/cassandra/queryLog/

データを確認する

SELECT * FROM querylogkeyspace.t;

 id | k | v
----+---+------
  0 | 1 | val1

4.1.x での新機能

次に4.1.xでの新機能としてクラスタの安全性をサポートするGuardrailsについて紹介します。

Guardrails

Cassandraにはいくつかアンチパターンとなる利用法があります。

アンチパターン例

  • 大量のSecondary Indexが作成されリソース不足となる
  • ALLOW FILTERINGを使用して巨大なデータを取得しクラスタ全体が高負荷となる
  • 意図せず低いConsistency Levelを使用してしまいデータの不整合が発生する

Guardrailsによって運用者側でCassandraの機能を制限し、アンチパターンを抑止することが可能となります。

Guardrailsの設定

cassandra.yamlでGuardrailsに関する設定を行うことができます。
設定を有効化する際はcassandra.yamlを修正し、ノードの再起動を行います。
将来的には動的に設定を更新する機能もサポートされる予定のようです。

Guradrailsの対象となるユーザーは通常のユーザーの操作のみとなっており、Super Userの操作や内部クエリはチェックの対象外となります。
また、Guradrailsでは機能を無効にするだけでなく、警告メッセージを表示する設定も可能です。

Guardrailsによる制限の多くはCQLクエリに関連しており実行時などにチェックされますが、直接クエリに関連しない要素もバックグラウンドでチェックすることができます。
バックグラウンドでチェックされる例としてはcollection型データのサイズやディスク使用率などがあります。

以下にGuardrailsの設定項目の一部を紹介します。

  • テーブル毎のSecondary Indexの数
  • Secondary Indexの作成
  • ALLOW FILTERINGの使用
  • Readで使用可能なConsistency Level
  • Writeで使用可能なConsistency Level
  • ディスク使用量

※ 他にもGuardrailsで設定可能な項目はたくさんあります

# Guardrail to warn or fail when creating more secondary indexes per table than threshold.
# The two thresholds default to -1 to disable.
# secondary_indexes_per_table_warn_threshold: -1
# secondary_indexes_per_table_fail_threshold: -1

# Guardrail to enable or disable the creation of secondary indexes
# secondary_indexes_enabled: true

# Guardrail to allow/disallow querying with ALLOW FILTERING. Defaults to true.
# allow_filtering_enabled: true

# Guardrail to warn about or reject read consistency levels. By default, all consistency levels are allowed.
# read_consistency_levels_warned: []
# read_consistency_levels_disallowed: []

# Guardrail to warn about or reject write consistency levels. By default, all consistency levels are allowed.
# write_consistency_levels_warned: []
# write_consistency_levels_disallowed: []

# Guardrail to warn or fail when local data disk usage percentage exceeds threshold. Valid values are in [1, 100].
# This is only used for the disks storing data directories, so it won't count any separate disks used for storing
# the commitlog, hints nor saved caches. The disk usage is the ratio between the amount of space used by the data
# directories and the addition of that same space and the remaining free space on disk. The main purpose of this
# guardrail is rejecting user writes when the disks are over the defined usage percentage, so the writes done by
# background processes such as compaction and streaming don't fail due to a full disk. The limits should be defined
# accordingly to the expected data growth due to those background processes, so for example a compaction strategy
# doubling the size of the data would require to keep the disk usage under 50%.
# The two thresholds default to -1 to disable.
# data_disk_usage_percentage_warn_threshold: -1
# data_disk_usage_percentage_fail_threshold: -1
# Min unit: B
# data_disk_usage_max_disk_size:

Guardrailsの使用例

以下の設定を行い、いくつかのクエリを試してみます。

secondary_indexes_per_table_warn_threshold: 1
secondary_indexes_per_table_fail_threshold: 2
read_consistency_levels_warned: [ONE]
read_consistency_levels_disallowed: [ALL]
write_consistency_levels_warned: [ONE]
write_consistency_levels_disallowed: [ALL]
allow_filtering_enabled: false
data_disk_usage_percentage_warn_threshold: 20
data_disk_usage_percentage_fail_threshold: 40

Secondary Indexの作成
-> 2つめのインデックスを作成した際にWarningが表示され、3つめのインデックスの作成に失敗

CREATE INDEX v_idx ON querylogkeyspace.t ( v );
CREATE INDEX k_idx ON querylogkeyspace.t ( k );

Warnings :
Guardrail secondary_indexes_per_table violated: Creating secondary index k_idx on table t, current number of indexes 2 exceeds warning threshold of 1.

CREATE INDEX k_idx2 ON querylogkeyspace.t ( k );
InvalidRequest: Error from server: code=2200 [Invalid query] message="Guardrail secondary_indexes_per_table violated: Tables cannot have more than 2 secondary indexes, aborting the creation of secondary index k_idx2 on table t"

ConsistencyLevel: ONEでのRead/Write
-> Warningが表示されるがクエリには成功

SELECT * FROM querylogkeyspace.t;

 id | k | v
----+---+------
  1 | 1 | val2
  0 | 1 | val1
  2 | 2 | val1

(3 rows)

Warnings :
Guardrail read_consistency_levels violated: Provided values [ONE] are not recommended for read consistency levels (warned values are: [ONE])

INSERT INTO querylogkeyspace.t (id, k, v) VALUES (3, 2, 'val3');

Warnings :
Guardrail write_consistency_levels violated: Provided values [ONE] are not recommended for write consistency levels (warned values are: [ONE])

ConsistencyLevel: ALLでのRead/Write
-> クエリに失敗する

CONSISTENCY ALL;
Consistency level set to ALL.

SELECT * FROM querylogkeyspace.t;
InvalidRequest: Error from server: code=2200 [Invalid query] message="Guardrail read_consistency_levels violated: Provided values [ALL] are not allowed for read consistency levels (disallowed values are: [ALL])"

INSERT INTO querylogkeyspace.t (id, k, v) VALUES (4, 3, 'val2');
InvalidRequest: Error from server: code=2200 [Invalid query] message="Guardrail write_consistency_levels violated: Provided values [ALL] are not allowed for write consistency levels (disallowed values are: [ALL])"

ALLOW FILTERINGを使用したクエリ
-> クエリに失敗する

SELECT * FROM querylogkeyspace.t WHERE v = 'val1' ALLOW FILTERING;
InvalidRequest: Error from server: code=2200 [Invalid query] message="Guardrail allow_filtering violated: Querying with ALLOW FILTERING is not allowed"

データディレクトリのディスク使用量が20%以上となった場合
-> cassandraのログにWARNメッセージが出力される

WARN  [ScheduledTasks:1] 2024-09-09 20:42:33,449 NoSpamLogger.java:108 - Guardrail local_data_disk_usage violated: Local data disk usage 24%(Stuffed) exceeds warning threshold of 20%

この状態で書き込みを行う
-> ディスク使用率が高いノードにレプリカが書き込まれる際に、Warningが表示されるがクエリには成功

INSERT INTO querylogkeyspace.t (id, k, v) VALUES (8, 4, 'val3');

Warnings :
Guardrail replica_disk_usage violated: Replica disk usage exceeds warning threshold

データディレクトリのディスク使用量が40%以上となった場合
-> cassandraのログにERRORメッセージが出力される

ERROR [ScheduledTasks:1] 2024-09-09 20:46:33,444 NoSpamLogger.java:111 - Guardrail local_data_disk_usage violated: Local data disk usage 55%(Full) exceeds failure threshold of 40%, will stop accepting writes

この状態で書き込みを行う
-> ディスク使用率が高いノードにレプリカが書き込まれる際に、クエリに失敗

INSERT INTO querylogkeyspace.t (id, k, v) VALUES (8, 4, 'val4');
InvalidRequest: Error from server: code=2200 [Invalid query] message="Guardrail replica_disk_usage violated: Write request failed because disk usage exceeds failure threshold"

5.0.x での新機能

5.0.xの新機能からピックアップして新しいインデックスであるStorage Attached Indexとそれを利用したVector Search、さらにUnified Compaction Strategyについて紹介します。

Vector Search & Storage Attached Indexes(SAI)

近年AI技術が注目されており、Cassandraにもベクトルデータの類似性を比較するVector SearchとVector型が追加されました。

Vector Searchは以下の流れで行います。
(Storage Attached Indexについては後で紹介しますが、5.0.xで新しく追加されたインデックスです)

  1. ベクトルデータを保存するテーブルの作成
  2. ベクトルデータのカラムにインデックス(Storage Attached Index)を作成する
  3. データを書き込む
  4. インデックスを利用しベクトルを検索する

Vector Searchの例

KeyspaceとTableの作成

ここでカラムvがVector型のデータとなっており浮動小数点型の固定長の配列となります。

CREATE KEYSPACE sample WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};

CREATE TABLE sample.t(
   id INT PRIMARY KEY, 
   name text,
   v VECTOR<float, 3>
);

インデックスの作成

saiを指定することでStorage Attached Indexを使用できます。

CREATE INDEX IF NOT EXISTS ann_index ON sample.t(v) USING 'sai';

データの書き込み

INSERT INTO sample.t (id, name, v) VALUES (1, 'Sato', [8, 2.3, 58]); 
INSERT INTO sample.t (id, name, v) VALUES (2, 'Tanaka', [1.2, 3.4, 5.6]);
INSERT INTO sample.t (id, name, v) VALUES (5, 'Sasaki', [23, 18, 3.9]); 

データの検索

以下のクエリでVector Searchができます。

SELECT * FROM sample.t ORDER BY v ANN OF [3.4, 7.8, 9.1] LIMIT 1;

 id | name   | v
----+--------+-----------------
  2 | Tanaka | [1.2, 3.4, 5.6]

また、類似度を計算する以下の新たな関数が追加されております

  • similarity_dot_product
  • similarity_cosine
  • similarity_euclidean

類似度を使用してみた例が以下になります。

SELECT id, name, similarity_dot_product(v, [1.1, 3.8, 6.0]) FROM sample.t ORDER BY v ANN OF [3.4, 7.8, 9.1] LIMIT 2;

 id | name   | system.similarity_dot_product(v, [1.1, 3.8, 6.0])
----+--------+---------------------------------------------------
  2 | Tanaka |                                             24.42
  1 |   Sato |                                            183.27

SELECT id, name, similarity_cosine(v, [1.1, 3.8, 6.0]) FROM sample.t ORDER BY v ANN OF [3.4, 7.8, 9.1] LIMIT 2;

 id | name   | system.similarity_cosine(v, [1.1, 3.8, 6.0])
----+--------+----------------------------------------------
  2 | Tanaka |                                     0.999724
  1 |   Sato |                                     0.934025

SELECT id, name, similarity_euclidean(v, [1.1, 3.8, 6.0]) FROM sample.t ORDER BY v ANN OF [3.4, 7.8, 9.1] LIMIT 2;

 id | name   | system.similarity_euclidean(v, [1.1, 3.8, 6.0])
----+--------+-------------------------------------------------
  2 | Tanaka |                                         0.75188
  1 |   Sato |                                        0.000363

Storage Attached Index

先ほどのVector Searchの中で使用されておりましたが、このStorage Attached Index(SAI)が新しく追加されたインデックスになります。
SAIは以下のような特徴があり既存のインデックスよりもパフォーマンスが向上しているようです。

  • AIアプリケーションでのベクトル検索が可能
  • 同じテーブル上の複数のインデックス間でインデックスデータを共有
  • 書き込み時のスケーラビリティの問題を軽減
  • ディスク使用量が大幅に削減
  • インデックスのゼロコピーストリーミングが可能

従来のSecondary Indexの使用の際にはインデックスの肥大化やクラスタへの負荷など注意する点が多かったため、こちらの新しいインデックスは期待したいです。

Unified Compaction Strategy

従来のCassandraでは以下のCompaction Strategyがありワークロードごとに向き不向きがありました。

Compaction Strategy 動作 特徴
SizeTierdCompactionStrategy(STCS) 同程度のサイズのSSTableが一定数集まるとコンパクションが行われます。 デフォルトのCompactionStrategyとなります。
他のCompactionStrategyが最適とならないケースでベターとなる場合が多いです。
LeveledCompactionStrategy(LCS) 階層(レベル)ごとにSSTableが管理され、同じレベルには重複するSSTableが存在しないようにコンパクションされます。
各階層には上限サイズがあり、それ超えると次の階層へ移行していきます。
データは各階層ごとに1つのSSTableにまとまっていることが保証されるため、読み取るSSTableの数が少なくてすみ、読み込みが多いワークローで有効となりやすいです。
TimeWindowCompactionStrategy(TWCS) ある期間内のデータを1つのSSTableにまとめるようにコンパクションが行われます。 時系列データでTTLを利用している場合、期限が切れたデータが他のCompactionStrategyより削除されやすく、ディスクスペースを活用しやすいです。

新しく追加される Unified Compaction Strategy(UCS)は以下の特徴があります。

  • パラメータを調整することで従来のCompaction Strategyを再現することが可能
  • これまでは別のCompaction Strategyへ切り替える場合、すべてのデータを再度Compactionする必要がありましたが、UCSではパラメータの変更のみで戦略を切り替えることが可能
  • SSTableをトークンレンジごとにソートしたり、サイズだけでなく密度で分割することも可能になり柔軟なコンパクションが可能
    • 例:トークンレンジごとに並列でコンパクションするなど

これまでは各Compaction Strategyでクラスタを長期間運用していると問題となる場合がありましたが、UCSによってある程度チューニングできるようになると非常に嬉しいです。

問題の例

  • STCSで一度大きなSSTableが生成されると次のコンパクション対象になりにくく、上書きされたデータや削除されたデータが圧迫しやすい
    こちらを解消するため常にメジャーコンパクションを行う運用が必要となる
  • LCSで上位の階層にあるSSTableはコンパクションされにくく不要なデータが残り続けやすい
    garbagecollect などの対応が必要
  • 後からCompactionStrategyを変更するのが難しい

UCSの詳細な内容や各パラメータの説明は以下のドキュメントをご参照ください。
Unified Compaction Strategy (UCS) | Apache Cassandra Documentation

おわりに

今回はバージョン4.0~5.0で追加された機能の一部を紹介させていただきました。
こちらで紹介したもの以外でも性能面での向上やセキュリティ面でのオプションの追加など多くの改善が行われております。
また、今後のバージョンで追加や修正が予定されている機能も多数存在し、以下のページやJiraなどから確認することができます。
Cassandra Enhancement Proposals (CEP) - CASSANDRA - Apache Software Foundation
最新のCassandraの機能に興味がある方、Cassandraのバージョンアップを検討している方などの参考になれば幸いです。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?