1. 概要

Cassandra NoSQLデータベースのデータ分散とデータモデリングは、従来のリレーショナルデータベースのものとは異なります。

この記事では、パーティションキー、複合キー、およびクラスタリングキーがどのように主キーを形成するかを学習します。 また、それらがどのように異なるかについても見ていきます。 その結果、Cassandraのデータ分散アーキテクチャとデータモデリングのトピックに触れます。

2. ApacheCassandraアーキテクチャ

Apache Cassandra は、パフォーマンスを損なうことなく高可用性と線形スケーラビリティを実現するために構築されたオープンソースのNoSQL分散データベースです。

高レベルのCassandraアーキテクチャは次のとおりです。

Cassandraでは、データはクラスター全体に分散されます。 さらに、クラスターは、地理的地域全体のデータセンターに設置されたラックに配置されたノードのリングで構成されている場合があります。

より詳細なレベルでは、 vnodes と呼ばれる仮想ノードが、データの所有権を物理マシンに割り当てます。 Vnodeを使用すると、コンシステントハッシュと呼ばれる手法を使用してデータを分散することにより、各ノードが複数の小さなパーティション範囲を所有できるようになります。

パーティショナーは、パーティションキーをハッシュしてトークンを生成する関数です。 このトークン値は行を表し、ノード内で行が属するパーティション範囲を識別するために使用されます。

ただし、Cassandraクライアントは、クラスターを統合されたデータベース全体と見なし、Cassandraドライバーライブラリを使用してクラスターと通信します。

3. Cassandraデータモデリング

一般に、データモデリングは、アプリケーション要件の分析、エンティティとその関係の特定、データの整理などのプロセスです。 リレーショナルデータモデリングでは、クエリはデータモデリングプロセス全体で後から付け加えられることがよくあります。

ただし、Cassandraでは、データアクセスクエリがデータモデリングを駆動します。 次に、クエリはアプリケーションワークフローによって駆動されます。

さらに、Cassandraデータモデルにはテーブル結合がありません。これは、クエリで必要なすべてのデータが単一のテーブルから取得される必要があることを意味します。 その結果、テーブル内のデータは非正規化された形式になります。

次に、論理データモデリングのステップで、キースペース、テーブル、さらにはテーブル列を定義することにより、実際のデータベーススキーマを指定します。 次に、物理データモデリングのステップで、Cassandraクエリ言語(CQL)を使用して、物理キースペース(クラスター内のすべてのデータ型を持つテーブル)を作成します。

4. 主キー

Cassandraで主キーがどのように機能するかは、把握するための重要な概念です。

Cassandra の主キーは、1つ以上のパーティションキーと0個以上のクラスタリングキーコンポーネントで構成されます。 これらのコンポーネントの順序は、常にパーティションキーを最初に配置し、次にクラスタリングキーを配置します。

データを一意にすることとは別に、主キーのパーティションキーコンポーネントは、データの配置において追加の重要な役割を果たします。 その結果、クラスター内の複数のノードに分散されたデータの読み取りと書き込みのパフォーマンスが向上します。

それでは、主キーのこれらの各コンポーネントを見てみましょう。

4.1. パーティションキー

パーティションキーの主な目的は、データをクラスター全体に均等に分散し、データを効率的にクエリすることです。

パーティションキーは、データを一意に識別することとは別にデータを配置するためのものであり、常に主キー定義の最初の値です。

例を使用して理解してみましょう—1つの主キーを持つアプリケーションログを含む単純なテーブル:

CREATE TABLE application_logs (
  id                    INT,
  app_name              VARCHAR,
  hostname              VARCHAR,
  log_datetime          TIMESTAMP,
  env                   VARCHAR,
  log_level             VARCHAR,
  log_message           TEXT,
  PRIMARY KEY (app_name)
);

上記の表のサンプルデータは次のとおりです。

前に学習したように、Cassandraはコンシステントハッシュ法を使用してパーティションキー( app_name )のハッシュ値を生成し、ノード内のパーティション範囲に行データを割り当てます。

可能なデータストレージを見てみましょう。

上の図は、 app1 app2 、および app3 のハッシュ値により、各行が3つの異なるノード()に格納される可能性のあるシナリオです。 Node1 Node2 、およびNode3

すべてのapp1ログはNode1に移動し、app2ログはNode2に移動し、app3ログはに移動します]Node3

where 句にパーティションキーがないデータフェッチクエリでは、非効率的なフルクラスタースキャンが発生します。

一方、 where 句にパーティションキーがある場合、Cassandraはコンシステントハッシュ法を使用して、クラスター内のノード内の正確なノードと正確なパーティション範囲を識別します。 その結果、データのフェッチクエリは高速かつ効率的です。

select * application_logs where app_name = 'app1';

4.2. 複合パーティションキー

複数の列値を組み合わせて単一のパーティションキーを形成する必要がある場合は、複合パーティションキーを使用します。

ここでも、複合パーティションキーの目的は、データを一意に識別することに加えて、データを配置することです。 その結果、データの保存と取得が効率的になります。

次に、app_name列とenv列を組み合わせて複合パーティションキーを形成するテーブル定義の例を示します。

CREATE TABLE application_logs (
  id                    INT,
  app_name              VARCHAR,
  hostname              VARCHAR,
  log_datetime          TIMESTAMP,
  env                   VARCHAR,
  log_level             VARCHAR,
  log_message           TEXT,
  PRIMARY KEY ((app_name, env))
);

上記の定義で注意すべき重要なことは、app_nameとenvの主キー定義を囲む括弧です。 この内側の括弧は、app_nameenvがパーティションキーの一部であり、クラスタリングキーではないことを示しています。

内側の括弧を削除し、括弧が1つしかない場合、app_nameはパーティションキーになり、envはクラスタリングキーコンポーネントになります

上記の表のサンプルデータは次のとおりです。

上記のサンプルデータの可能なデータ分布を見てみましょう。 注意:Cassandraは、app_name列とenv列の組み合わせのハッシュ値を生成します。

上記のように、 app1:prod、app1:dev、app1:qa のハッシュ値により、これらの3つの行が3つの別々のノードに格納される可能性のあるシナリオ— Node1 Node2 、およびNode3

prod環境からのすべてのapp1ログは、 Node1 に移動し、 app1 ログは、dev環境から移動します。 Node2およびapp1ログはqa環境からNode3に移動します。

最も重要なことは、データを効率的に取得するには、フェッチクエリのwhere句に、主キー定義で指定されたのと同じ順序ですべての複合パーティションキーが含まれている必要があります。

select * application_logs where app_name = 'app1' and env = 'prod';

4.3. クラスタリングキー

上で述べたように、パーティショニングは、データが配置されるノード内のパーティション範囲を識別するプロセスです。 対照的に、クラスタリングは、パーティション内のデータを並べ替えるストレージエンジンプロセスであり、クラスタリングキーとして定義された列に基づいています。

さらに、クラスタリングキー列の識別は事前に行う必要があります。これは、クラスタリングキー列の選択が、アプリケーションでデータをどのように使用するかによって異なるためです。

パーティション内のすべてのデータは、クラスタリングキー列で並べ替えられた連続ストレージに保存されます。 その結果、目的のソートされたデータの取得は非常に効率的です。

クラスタリングキーと複合パーティションキーを含むテーブル定義の例を見てみましょう。

CREATE TABLE application_logs (
  id                    INT,
  app_name              VARCHAR,
  hostname              VARCHAR,
  log_datetime          TIMESTAMP,
  env                   VARCHAR,
  log_level             VARCHAR,
  log_message           TEXT,
  PRIMARY KEY ((app_name, env), hostname, log_datetime)
);

そして、いくつかのサンプルデータを見てみましょう。

上記のテーブル定義からわかるように、クラスタリングキー列としてhostnamelog_datetimeが含まれています。 app1およびprod環境からのすべてのログがNode1に格納されていると仮定すると、Cassandraストレージエンジンはこれらのログをホスト名およびパーティション内のlog_datetime

デフォルトでは、Cassandraストレージエンジンはクラスタリングキー列の昇順でデータを並べ替えますが、テーブル定義のWITH CLUSTERING ORDER BY句を使用して、クラスタリング列の並べ替え順序を制御できます。

CREATE TABLE application_logs (
  id                    INT,
  app_name              VARCHAR,
  hostname              VARCHAR,
  log_datetime          TIMESTAMP,
  env                   VARCHAR,
  log_level             VARCHAR,
  log_message           TEXT,
  PRIMARY KEY ((app_name,env), hostname, log_datetime)
) 
WITH CLUSTERING ORDER BY (hostname ASC, log_datetime DESC);

上記の定義によれば、パーティション内では、Cassandraストレージエンジンはすべてのログを hostname の字句の昇順で保存しますが、各hostname[内のlog_datetimeの降順で保存します。 X221X]グループ。

次に、where句にクラスタリング列を含むデータフェッチクエリの例を見てみましょう。

select * application_logs 
where 
app_name = 'app1' and env = 'prod' 
and hostname = 'host1' and log_datetime > '2021-08-13T00:00:00';

ここで重要なのは、 where 句には、主キー句で定義されているのと同じ順序で列が含まれている必要があるということです。

5. 結論

この記事では、Cassandraがパーティションキーまたは複合パーティションキーを使用して、クラスター内のデータの配置を決定することを学びました。 クラスタリングキーは、パーティション内に格納されているデータの並べ替え順序を提供します。 これらのキーはすべて、データを一意に識別します。

また、Cassandraアーキテクチャとデータモデリングのトピックにも触れました。

Cassandraの詳細については、DataStaxおよびApacheCassandraのドキュメントにアクセスしてください。