目次


基本的な Apache Cassandra アーキテクチャーをセットアップする

Comments

ビッグデータと NoSQL データベースについて知ったのはかなり前のことであっても、まだ実際に取り掛かる機会は訪れていないという方もいるでしょう。あるいは、取り組んでいるプロジェクトの中に、NoSQL データベースが役立ちそうなものがあっても、実際に導入する自信がないという場合もあるかもしれません。このチュートリアルは、そのような方のためにあります。

このチュートリアルでは、現在利用できるビッグデータ・ストアのうち、最も巧妙であり、最も回復力のあるストアの 1 つとして挙げられる Apache Cassandra のセットアップ方法を案内します。リレーショナル・データベースの基礎知識を持つ開発者とデータベース管理者を対象に、この実践的なチュートリアルでは Cassandra の主要な側面を詳しく説明し、追加情報の参照先を記載します。

環境のセットアップをテストするために、Cassandra のユーティリティーと Python スクリプトを使用して Cassandra 内に保管されたデータを使用しますが、これらのツールを熟知している必要はありません。これらはセットアップに必要となるツールではなく、構成を検証するためだけに使用する、追加リソースとしての役割を果たします。

基本概念

このセクションでは、分散型データベースとしての Cassandra に備わっている特徴の一部を取り上げて詳しく説明します。ここで説明する概念についてすでにある程度の知識がある場合、または今のところ理論には興味ないという場合は、「計画」のセクションに進んで構いません。

CAP 定理

CAP は「Consistency, Aavailability, and Partition tolerance (整合性、可用性、分断耐性)」を意味します。2000 年にエリック・ブリュワーによって初めて定式化された CAP 定理では、どの共有データ・システムにあっても、整合性、可用性、分断耐性という 3 つの特性のうち、同時に満たせることができるのは最大 2 つに限られると述べています。つまり、3 つすべての特性を保証することはできないため、いずれか 1 つを諦めなければならないということです。この定理の詳細を学ぶための参照先はチュートリアルの最後にある「関連トピック」に記載されていますが、その概要を説明しておきます。

CAP 定理は Cassandra に関係するため、理解しておくことが重要です。例えば、この定理を踏まえると、取り組んでいる NoSQL データベース・ソリューションには Cassandra が最適とは言えないという結論に至る可能性もあります。いずれにしても、ソリューションの制約事項は、最初に整合性と可用性という観点から考えると明らかになってくるはずです。

この定理によると、あらゆる分散型システムは、その特定のシステムに最も重要となる 2 つの保証の選択に迫られます (図 1 を参照)。Cassandra ではこの 3 つの保証のそれぞれを満たすことはできますが、すべてを同時に満たすことはできません。例えば、ダウンタイムのない、可用性に優れたデータベースが必要であり、時折発生するハードウェア障害にサービスを中断されたくないという場合があります。そのような可用性と分断耐性を重視するソリューションには、Cassandra は最適な選択肢です。

Cassandra とは対照的に、MySQL、DB2、Oracle、Sybase などの従来型のリレーショナル・データベース管理システム (RDBMS) に備わっているのは、ACID (Atomicity, Consistency, Isolation, Durability (アトミック性、整合性、独立性、永続性)) の特性です。断っておきますが、Cassandra ではアトミック処理に対応できない、あるいは Cassandra データには独立性も永続性もないと言っているわけではありません。単に、ACID は Cassandra の主要な関心事ではないと言いたいだけです。Cassandra は元から分散型データベースとして誕生し、その関心事は、データとアプリケーションのトランザクションが増えるにつれ簡単にスケーリングできるようにすることにあります。

図 1. CAP 定義の保証と Cassandra
CAP 定義の保証と Cassandra を示す図

分散型データベース

Cassandra は分散型データベースとして誕生しました。つまり、各コンポーネントがそれぞれ異なるマシン上で実行されるコンピューター・ノードのネットワーク内で、サーバーとして稼働するように設計されているということです。特定のハードウェアやソフトウェアでこれらのノードを管理または調整することはありません。ノードの調整とデータの配布はすべて、独自のアーキテクチャー内で行われます。これが、Cassandra ネットワークが他の一般的なリレーショナル・データベース・システムよりも水平スケーリングに容易に対応できて、しかも安価である理由の 1 つとなっています。

標準的な Cassandra ネットワーク・トポロジーは、異なる物理サーバー上でそれぞれに固有のネットワーク・アドレスを持って稼働するノードのクラスター (別名、Cassandra リング) からなります。

図 2. さまざまなネットワーク・ホスト内のノードからなる Cassandra クラスター
Cassandra のノード・クラスターを示す図

このような特徴を持つトポロジーでは、ノードで障害が発生したとしても、ネットワークは優れた可用性を発揮します。このトポロジーにはマスター・ノードはありません。各ノードがクライアントのリクエストを調整できるため、単一障害は排除されます。また、それぞれのノードに個別の構成ストラテジーをセットアップして、特定のノードの位置を意識したデータにすることもできるため、さらにシステムの可用性が高まることになります。

図 3. クライアント接続を受け入れて、レプリケーション係数 3 で構成されたキースペースにデータを書き込む 8 つのノードからなる Cassandra クラスター
8 ノードの Cassandra クラスターを示す図
8 ノードの Cassandra クラスターを示す図

Cassandra リング (複数のノード) 全体ですべてのデータを均等に配布するために、ハッシュ・アルゴリズムを使用して必要な数のデータのコピー (レプリカ) が作成されます。このクラスター構成の重要な側面は、レプリケーション係数です。レプリケーション係数はキースペースまたはスキーマ構成によって定義されます。

ノード間では、一種のピア・ツー・ピア・プロトコルであるゴシップ・プロトコルを使用して、クラスターのデータ、トポロジー、ノードの可用性、そしてパフォーマンスに関するすべての情報が交換されます。この情報は、クライアントの接続に対し、その時点でデータの書き込みまたは読み取りを処理するのに最良のノードを伝える重要な役割を果たします。

Cassandra クライアントはサーバーとの通信で、CQL バイナリー・プロトコルと、Thrift と呼ばれる RPC プロトコルのいずれかを使用できます。この 2 つのうち、CQL バイナリー・プロトコルのほうが新しく、Thrift よりも優先されます。CQL (Cassandra Query Language) は SQL に似た言語です。Cassandra ではこの言語を使用して、自身のスキーマ構造とデータ (DDL および DML) を処理するコマンドを作成します。

基本的なデータ構造とモデリング

重要な側面であり、場合によっては扱いにくい側面となるのが、Cassandra のデータをどのようにモデリングするかという点です。まず、Cassandra のアーキテクチャー内でデータがどのように編成されるのかを理解してから、それぞれのアプリケーションで最大のパフォーマンスを引き出すデータ構造をモデリングする方法を把握する必要があります。

Cassandra 内では、すべてのデータはパーティション別に編成され、各パーティションに割り当てられた主キー (行キー) を使用して、キーと値のペアを格納する列のすべて、またはその一部にアクセスできるようになっています。

図 4. Cassandra のデータ構造のパーティション
Cassandra のデータ構造のパーティションを示す図

Cassandra 内の主キーには、パーティション・キーと (必要に応じて) クラスター化キーという 2 つの特殊なキーを含めることができます。パーティション・キーの目的は、データをクラスター全体で均等に分散させることです。クラスター化キー (クラスター化カラムとも呼ばれます) は、クエリーを効率化できるよう、パーティション内のデータをクラスター化して編成する役割を持ちます。具体的な例で説明しましょう。

Cassandra 内にテーブルを作成するには、以下のような CQL コマンドを使用します。

CREATE TABLE movie_catalog (category text, year int, title text,
PRIMARY KEY (category));

最初の列は、暗黙的に movie_catalog テーブルのパーティション・キーになると見なされます。上記の例にクラスター化キーはありませんが、主キーの中に、以下のように year 列を追加するものとします。

CREATE TABLE movie_catalog (category text, year int, title text,
PRIMARY KEY (category,year))

この場合、パーティション・キーとなるのは引き続き category であり、year 列はクラスター化キーになります。両方の列が、主キーを構成します。

紛らわしい仕組みだと感じるとしたら、考えすぎないようにしてください!重要な点は、クラスター内で該当するデータが置かれているノードを特定するために、Cassandra のすべてのテーブルには主キーが必要であるということを認識しておくことです。主キーには少なくもパーティション・キーが含まれます。上記に示されているように、主キーには、ノード内のデータの位置 (パーティション) を特定するために使用するクラスター化キーも含めることができます。

テーブルをモデリングする際は、Cassandra がデータを適切にノードに配布できるよう、慎重にパーティション・キーを選ぶ必要があります。アプリケーション・データ (行) のすべてを 1 つのパーティションにだけ格納するのは賢明なことではありません。同様に、あまりにも多くのパーティションを使用してしまう可能性もあります。したがって、データをグループ化する際は、アプリケーションの要件を満たす、適切なバランスを見つける必要があります。

Cassandra 内でのモデリングに最もよく使われている手法は、クエリー・ベース・モデリングと呼ばれる手法です。この手法は、まず始めに、アプリケーション・ユーザー・インターフェースで実行するクエリーについて考えて、それらのクエリーに応じてテーブルをモデリングするというものです。このトピックについては、今後のチュートリアルで取り上げる可能性があります。

計画の策定

例えば、大病院向けの極めて重要なアプリケーション・アーキテクチャーのために、患者の診察情報を保管するデータベース層の設計を頼まれたとします。このシステムは毎日 24 時間、稼働中の状態を維持する必要があります。また、システムで対応するユーザーもかなりの数にのぼります。この場合、まず懸念事項となるのは、データベースに高可用性と耐障害性を持たせ、ユーザーや病院の運営に支障をきたさないようにすることです。次のセクションで、考えられるソリューションについて説明します。

ソリューションの概要

最初にテスト (UAT) 環境として、3 つのノードからなる基本的なテスト用クラスターをセットアップすることにしました。後で本番に移る際に、これら 3 つのノードのそれぞれを、本番環境の病院データ・センター内にある 3 つの異なるサーバー・マシン上にデプロイするという計画です。

図 5. 3 ノードの Cassandra クラスターを実行するサーバーのデータベース層にアクセスする病院向けアプリケーション
病院向けアプリケーションを示す図

1 つのノードだけではなく、3 つのノードからなるクラスターを使用するという考えには、データベース・システムの可用性を高めるという意図があります。3 ノードのクラスターであれば、あるノードで障害が発生したとしても、稼働中の他の 2 つのノードでアプリケーションのリクエストのすべてに対応できます。また、負荷が大きくなった場合、複数のノードがあれば、リクエストのロード・バランシングを行えるため、アプリケーションでのデータ読み取り/書き込みのレイテンシーを縮小できます。

Cassandra クライアント・ドライバーは、使用可能なすべてのノードを自動検出し、データのすべてのコピー、つまりレプリカの書き込み処理を行うのに最良のコーディネーター・ノードを選択します。このような機能を可能にしているのは、ピア・ノードの間でノードの正常性情報が交換する Cassandra のゴシップ・プロトコル実装です。

レプリケーション係数

計画の次のステップでは、アプリケーションに適用するレプリケーション係数と整合性レベルを決定します。その後は、データベース・ランタイム環境をインストールして構成し、アプリケーションのスキーマとテーブルを作成する作業を開始できます。

スキーマ定義では、レプリケーション係数を 3 に設定します。これは、3 つのノード内でデータの 3 つのコピーを作成するようにデータベース・スキーマ (キースペース) を構成することを意味します。つまり、アプリケーションがあるノードに接続して 1 つのデータ項目をテーブルに挿入するたびに、そのデータのレプリカが他の 2 つのノードに自動的に作成されます。この仕組みにより、より確実に、データが安全に保管されるようになります。

CREATE KEYSPACE patient WITH replication = {'class': 'SimpleStrategy',
    'replication_factor' : 3};

整合性レベル

クライアントに接続して読み取り/書き込みセッションを行っている間、アプリケーションに適用する整合性レベルも定義する必要があります。整合性レベルを定義することで、どれほど厳密にクエリーとデータの状態を一貫させるかを決定できます。例えば、データの書き込み/読み取りの整合性レベルとして QUORUM を設定することにした場合、Cassandra はリクエストを返す前に、ノードの過半数 (2 つのノード) でデータの読み取り/書き込み処理を行うことになります。

整合性レベルはクライアント・セッションごとに定義され、随時変更することができます。一例として、以下に示す cqlsh クライアント・シェル内で、ほとんどの Cassandra ドライバーで使用できる方法と同じ方法を使用して、クエリーを行う前に、いつでも整合性レベルをテストすることができます。

cqlsh:patient> consistency QUORUM ;
Consistency level set to QUORUM.
cqlsh:patient>

整合性とレイテンシー・パフォーマンスの間にはトレードオフがあります。つまり、整合性が高くなればなるほど、読み取り/書き込み処理にかかる時間は長くなります。この例での基本的なクラスターのセットアップでは、時間の差はそれほど大きくなりませんが、大規模な Cassandra クラスターを作成する場合は重要な概念として考えに入れてください。大量のデータを処理する一方で、応答時間も高速でなければならない場合はあります。

必要なもの

Cassandra データベースは Java プラットフォームに基づくため、Java テクノロジーをサポートしている多くのオペレーティング・システムのうち、任意のオペレーティング・システムを選んで実行できます。また、最初に必要なディスク・スペースとメモリーもわずかです。このチュートリアルで説明するアプリケーションに推奨される要件は以下のとおりです。

  • 空き容量が 2 GB 以上の RAM: Cassandra データベース・インスタンスをインストールして実行するには、4 GB の RAM を搭載し、そのうち少なくとも 2 GB を利用できるマシンを使用することをお勧めします。8GB の RAM を搭載したマシンであれば、言うことはありません。Cassandra インスタンスを Docker 上で実行する場合は、コンテナーごとに各 Cassandra ノードを実行するために少なくとも 1 GB の RAM が利用可能になっている必要があります。
  • Java 8: Apache Cassandra V3 リリース以降、Cassandra は Java 仮想マシン (JVM) 上で稼働するようになっているため、使用するマシンに Java Standard Edition 8 がインストールされていなければなりません。それよりも古いバージョン (V2.2 など) の Cassandra は、Java 7 で稼働できます。使用している Java のバージョンを調べるには、OS プロンプト・シェルで以下のコマンドを入力します。
    java -version
  • Python 2.7: Cassandra のノード管理ツール nodetool とシェル・ユーティリティー cqlsh を使用するには、Python がインストールされていなければなりません。これらのツールは、Cassandra インスタンスとそのデータベースの情報を取得したり、管理したりするのに重宝します。インストール済みの Python のバージョンを調べるには、以下のコマンドを入力します。
    python --version
  • Docker CE: すべての Cassandra ノードを 1 台のマシン上で稼働するコンテナー内で構成する場合は、Docker CE が必要です。テスト用クラスター環境を作成するには、Docker CE を使用することをお勧めします。Docker コンテナーを使うのは初めてだとしても、心配は無用です。以下の手順で、Cassandra クラスターをセットアップするために必要なコマンドを説明します。このリンク先の Docker Web サイトから、ご使用のフォームに対応する最新バージョンの Docker CE をダウンロードしてください。

インストール

Cassandra は、Cassandra Web サイトから手作業でインストールすることも、Docker コンテナーを使用して自動的にインストールすることもできます。Docker コンテナーを使用して Cassandra クラスターを作成する方法を選ぶ場合は、以下の「パッケージをダウンロードする」のセクションはスキップして構いません。

パッケージをダウンロードする

Linux を使用しているとしたら、その Linux インストール済み環境に固有のパッケージが見つかる場合もありますが、ほとんどの場合は、使用可能な最新バージョンから圧縮形式の tar.gz ファイルをダウンロードすることになります (このチュートリアルを作成している時点での最新バージョンは V3.11 です)。

  1. パッケージをダウンロードした後、TAR ユーティリティー (または同様のツール) を使って圧縮解除します。
    $ tar -xvf apache-cassandra-3.11.0-bin.tar.gz
  2. パッケージ内のファイルを任意の場所に抽出します。ファイルを抽出したら、apache-cassandra-3.11.0 という名前のディレクトリーを作成し、そのディレクトリーに、以下のようなコマンドを使用して Cassandra のバイナリー、構成ファイル、ドキュメンテーション・ファイル、ライブラリー、ユーティリティー・ツールのすべてを格納します。
    $ ls
    CHANGES.txt  LICENSE.txt  NEWS.txt  NOTICE.txt  bin  conf  doc  interface  javadoc  lib  pylib  tools

構成

このセクションでは、手作業で最初の Cassandra ノードをセットアップする方法を説明します。Docker を使用するとしても、Cassandra の主要な構成パラメーターを理解するために、このセクションを読むことをお勧めします。それでもこのセクションを省略するとしたら、「Docker を使用してテスト用クラスターをセットアップする」にスキップしてください。

Cassandra の主要な構成はすべて、conf ディレクトリー内にある cassandra.yaml ファイルに格納されます。

構成パラメーター

cassandra.yaml ファイルを編集して、以下の基本的なパラメーターを変更します。

  • cluster_name: このパラメーターは、3 ノードの Cassandra クラスターの名前を識別します。重要な点として、すべてのノードの構成で同じ名前を使用してください。

    cluster_name: 'Hospital Test Cluster'

  • seeds: クラスターを構成する主要なノードの IP ネットワーク・アドレスまたはホスト名のリストです。テスト用クラスターには、最初のノードの IP アドレスを設定します。

    seeds: "127.0.0.1"

  • listen_address: クライアントや他のノードがこのノードに接続するために使用する、ノードのホスト名です。(以下に示されているように) localhost を使用するのではなく、ネットワーク上のマシンが使用する実際のホスト名を設定してください。

    listen_address: localhost

  • native_transport_port: クライアントがこのノードに接続するために使用する、ノードの TCP ポート番号です。必ず、ファイアウォールでブロックされていないポートを使用してください。デフォルトは 9042 です。

    native_transport_port: 9042

このインスタンスに基本的な認証・許可をセットアップするには、以下の任意指定のパラメーターも変更する必要があります。

  • authenticator: ユーザーの認証を有効にします。クラスターに接続しようとするユーザーに対してユーザー名とパスワードの入力を要求するには、このパラメーターを以下のように変更する必要があります。

    authenticator: PasswordAuthenticator

  • authorizer: ユーザーへの権限付与を有効にするとともに、権限を制限します。このパラメーターを変更するとしたら、ノードが利用不可になった場合に他のノード内で許可データのコピーが作成されるよう、system_auth キースペースのレプリケーション係数を増やす必要があります。

    authorizer: CassandraRoleManager

最初のノードを手作業で起動する

すべての構成を設定した後は、以下のコマンドを使用して、bin ディレクトリー内にある Cassandra スクリプトを実行できます。-f オプションを指定すると、すべてのブートストラップ・ログがフォアグラウンドで出力されます。Cassandra を初めて起動するときは、このオプションがエラーの有無を調べるのに役立ちます。

$ bin/cassandra -f

初期化が完了して数秒後に、以下のログ情報が表示されたら、Cassandra ノードが稼働中になり、クライアント接続を受け入れられる状態になったことを意味します。

INFO  [main] 2017-08-20 18:04:58,329 Server.java:156 - Starting listening for CQL
    clients on localhost/127.0.0.1:9042 (unencrypted)...

ノードのステータスをダブルチェックするには、bin ディレクトリー内にある nodetool ユーティリティーを利用できます。このユーティリティーは、Cassandra クラスターおよびノードの情報を出力します。以下のコマンドを実行するだけで、クラスターのステータスを確認できます。

$ nodetool status

このコマンドが出力するクラスター情報には、クラスターが稼働しているデータ・センターの名前 (この例の場合はデフォルトの構成) と、クラスターの各ノード・メンバーのステータスが含まれます。

Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address	Load   	Tokens   	Owns (effective)  Host ID                           	Rack
UN  127.0.0.1  103.67 KiB  256      	100.0%        	6aae6c1f-cf06-4874-9507-a43025c312d1  rack1

IP アドレスの前にある UN の文字は、ノードが Up (U) 状態で Normal (N) であることを意味します。初めての起動時には、すべてのキースペース/テーブルのデータおよびログを保管する場所として、それぞれ data ディレクトリー、logs ディレクトリーが作成されます。

Docker コンテナーを使用しない場合、上記の手順を繰り返して他のノードを作成できます。他のノードの seeds 構成としては、必ず最初のノードの IP アドレスを使用してください。Docker コンテナーを使用する場合は、以下のセクションで説明する手順に従います。

Docker を使用してテスト用クラスターをセットアップする

Docker コンテナーを使用すると、個々の物理サーバー・マシンに Cassandra をインストールして構成するのではなく、同じテスト用サーバー・マシン内で稼働する 3 つのノードからなるクラスターを作成できます。3 つの Cassandra インスタンスを実行できるだけの十分な RAM があることを確認してください。十分な RAM がない場合は、ノードの数を 2 つに減らすことも可能です。

テスト用マシンに Docker がインストールされている場合、Docker Hub から入手できる公式イメージを使用できます。以下の Docker コマンドを入力することで、Cassandra 3.11 のダウンロード、インストール、起動のすべてを実行できます。

docker run --name node1 -d cassandra:3.11

このコマンドは、インターネットの Docker Hub レジトリー上で、3.11 のバージョン・タグが付けられた cassandra という名前のイメージを検索します。イメージが見つかると、それをダウンロードして、node1 という名前のコンテナーを作成し、起動します。このコンテナーはデフォルトの Cassandra 構成内であらかじめ設定されているもので、上述の構成と同様です。

新しく作成されたコンテナーが稼働中であることを確認するには、docker ps コマンドを使用します。

$ docker ps
CONTAINER ID    	IMAGE           	COMMAND              	CREATED          	STATUS          	PORTS                                     	NAMES
803135731d1a    	cassandra:3.11  	"/docker-entrypoint.s"   About a minute ago   Up About a minute   7000-7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp   node1

これで、他のインスタンスを起動して、最初のノードの位置を新しいノードのそれぞれに通知することができます。それには、CASSANDRA_SEEDS 環境変数を使用して、新しいノードのシード・ノードの IP アドレスを変更します。この環境変数を変更することにより、cassandra.yaml ファイル内で、コンテナー内部に作成された新しいノードの seeds 構成が自動的に変更されます。2 番目のノード・コンテナー (node2) を作成して起動するには、以下のコマンドを入力します。

$ docker run --name node2 -d -e CASSANDRA_SEEDS="$(docker inspect --format='{{
    .NetworkSettings.IPAddress }}' node1)" cassandra:3.11

クラスター内にあるノードの数を確認するには、node1 コンテナー内で nodetool ユーティリティーを実行します。

$ docker exec -it node1 nodetool status

このコマンドにより、これまでに構成されているクラスター内の各ノードのステータスが出力されます。したがって、以下のような出力結果になることが見込まれます。

Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address 	Load   	Tokens   	Owns (effective)  Host ID                           	Rack
UN  172.17.0.3  103.25 KiB  256      	100.0%        	f1bbd4d1-8930-45a3-ba43-4a2416617c7f  rack1
UN  172.17.0.2  108.64 KiB  256      	100.0%        	bec1b022-a397-4401-bd42-676c60397fe1  rack

node2 が正常に起動した後は、同じようにして 3 番目のノード (node3) を作成できます。3 つすべてのノードが稼働中になったら、次の「テスト」セクションに進んでください。何らかの理由で node2 が起動に失敗した場合は、以下のトラブルシューティング手順に従います。

Docker 上のクラスターをトラブルシューティングする

いずれかのノードが正常に起動しない場合は、以下のコマンドを実行して Cassandra ログを表示し、その内容を確認してください。

$ docker logs node2

Unable to gossip with any seeds (シードと通信できません)」というようなエラー・メッセージが記録されているとしたら、以下の手順に従ってパラメーターを追加する必要があります。記録されていなければ、「テスト」セクションに進みます。

  1. 必要なパラメーターを追加するには、まず始めに、Docker の inspect コマンドを使用して node1 の IP アドレスを取得します。
    $ docker inspect --format='{{ .NetworkSettings.IPAddress }}' node1
  2. 172.17.0.2 という IP アドレスが返されたという前提で、以下のコマンドを実行して node1 コンテナーを停止し、削除してから、公開されているゴシップ・ブロードキャスト・アドレスとポートの各パラメーターを指定してコンテナーを再作成します。
    $ docker stop node1
    $ docker rm node1
    $ docker run --name node1 -d -e CASSANDRA_BROADCAST_ADDRESS=172.17.0.2 -p 7000:7000 cassandra:3.11
  3. 続いて、シード・ノードとして node 1 のアドレスを再利用して、ブロードキャスト IP アドレス 172.17.0.3 の node2 を作成します。
    $ docker run --name node2 -d -e CASSANDRA_BROADCAST_ADDRESS=172.17.0.3 -p 7001:7000 -e CASSANDRA_SEEDS=172.17.0.2 cassandra:3.11

    この構成により、2 つのノードがポート 7000 に構成されたゴシップ・プロトコル情報を、7000 および 7001 のコンテナー・ポートを介して互いにブロードキャストできるようになります。
  4. 次に、docker ps を使用して、2 つの Docker プロセスが実行中であることを確認します。その後、再び nodetool ユーティリティーを使用してクラスターのステータスを確認します。
    $ docker exec -it node1 nodetool status
    Datacenter: datacenter1
    =======================
    Status=Up/Down
    |/ State=Normal/Leaving/Joining/Moving
    --  Address 	Load   	Tokens   	Owns (effective)  Host ID                           	Rack
    UN  172.17.0.3  108.29 KiB  256      	100.0%        	fd135375-711a-471a-b4e5-409199bbaaa5  rack1
    UN  172.17.0.2  108.66 KiB  256      	100.0%
        5db97fc3-70e9-48e5-b63b-0be67e35daea  rack1

コンテナー環境変数

Docker コンテナー内でのデフォルトの Cassandra クラスター名の構成を変更するには、コンテナー環境変数を使用できます。

Cassandra Docker イメージを実行する際に、Docker の run コマンド・ラインで -e オプションを使用して 1 つ以上の環境変数を渡すことで、Cssandra 固有の構成を変更することができます。イメージではこの方法を使用して、コンテナー内の Cassandra パラメーターを変更することになります。詳細については、Docker Hub 上にある、このリンク先の Cassandra イメージの資料を参照してください。

テスト

クラスターの構成をテストする際の最初のステップとして、CQL シェル・ユーティリティー (cqlsh) を使用してクラスターに接続します。この Python コマンド・ライン・スクリプトが作成するクライアントは、任意のクラスター・ホストに接続できます。つまり、cqlsh コマンドを実行するだけで、クラスターに接続できます。このスクリプトがデフォルトで接続しようとするのは、ローカルホスト上で稼働しているインスタンスです。接続を試行する対象のホストを変更するには、host パラメーターを渡します。詳細については、cqlsh のヘルプを参照してください (cqlsh --help)。

CQL シェル・ツール

Docker を使用している場合は、コンテナー内から cqlsh を実行できます。

$ docker exec -it node1 cqlsh
Connected to Test Cluster at 127.0.0.1:9042.
[cqlsh 5.0.1 | Cassandra 3.11.0 | CQL spec 3.4.4 | Native protocol v4]
Use HELP for help.
cqlsh>

このシェルでは SQL のような CQL コマンドを発行して、キースペース (スキーマ) やテーブルを作成、定義して、データを処理することができます。詳細については、このリンク先の Cassandra 資料を参照してください。

テスト用キースペースを作成する

すべての患者診察情報を保管する、最初のキースペースを作成しましょう。

  1. CQL コマンド CREATE KEYSPACE を発行して患者スキーマを作成します。
    cqlsh> CREATE KEYSPACE patient WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 3};
  2. 次は、作成したキースペースにアクセスして、診察データを保管する最初のテーブルを作成します。テーブルを作成するための CQL コマンドは、SQL DDL コマンドと同様です。
    CREATE TABLE patient.exam (
    patient_id int,
    id int,
    date timeuuid,
    details text,
    PRIMARY KEY (patient_id, id));

    上記のコマンドは、テーブルを作成して、そのテーブルの主キーに患者の ID と診察 ID 自体を含めます。

データを挿入する

  1. キースペースの構造が作成されたので、次は、3 名の患者のサンプル・データを挿入します。
    INSERT INTO exam (patient_id,id,date,details) values (1,1,now(),'first exam patient 1');
    INSERT INTO exam (patient_id,id,date,details) values (1,2,now(),'second exam patient 1');
    INSERT INTO exam (patient_id,id,date,details) values (2,1,now(),'first exam patient 2');
    INSERT INTO exam (patient_id,id,date,details) values (3,1,now(),'first exam patient
        3');
  2. テスト・クエリーを実行して、患者 1 のすべての診察情報を取得します。
    cqlsh:patient> select * from exam where patient_id=1;
    図 6. 患者 1 に対するクエリーの実行
    患者 1 に対するクエリーを実行した画面のスクリーン・キャプチャー
    患者 1 に対するクエリーを実行した画面のスクリーン・キャプチャー

クラスターをテストする

ここからは、クラスターの可用性、整合性、分断耐性をテストします。患者キースペースのレプリケーション係数を 3 に設定する場合、3 つのノードのそれぞれに、診察テーブルに書き込まれたすべてのデータのコピーが保持されることになります。

ノードのレプリケーション・テスト

node1 上でデータを書き込むと、そのデータは自動的に node2node3 に複製されます。したがって、node1 にデータを挿入してから node3 に対してクエリーを実行することで、データのレプリカが 3 つ揃っていることを確認できます。node1 に患者データを挿入して、その情報が node3 上で使用可能になるかどうかを確認するには、以下のコマンドを入力します。

$ docker exec -it node1 cqlsh
Connected to Test Cluster at 127.0.0.1:9042.
[cqlsh 5.0.1 | Cassandra 3.11.0 | CQL spec 3.4.4 | Native protocol v4]
Use HELP for help.
cqlsh> INSERT INTO patient.exam (patient_id,id,date,details) values (9,1,now(),'first exam patient 9');
cqlsh> quit;
$ docker exec -it node3 cqlsh
Connected to Test Cluster at 127.0.0.1:9042.
[cqlsh 5.0.1 | Cassandra 3.11.0 | CQL spec 3.4.4 | Native protocol v4]
Use HELP for help.
cqlsh> select * from patient.exam where patient_id=9;
 patient_id | id | date                                 | details
------------+----+--------------------------------------+----------------------
          9 |  1 | 9cf570b0-8e9d-11e7-a592-6d2c86545d91 | first exam patient 9
(1 rows)

ノードの障害テスト

node2node3 を停止してから、node1 に患者データを挿入します。その後、node2node3 を再起動して、node1 に挿入したデータが利用できない状態の node2 と node3 に複製されたかどうかを調べます。

$ docker stop node2
$ docker stop node3
$ docker exec -it node1 cqlsh
Connected to Test Cluster at 127.0.0.1:9042.
[cqlsh 5.0.1 | Cassandra 3.11.0 | CQL spec 3.4.4 | Native protocol v4]
Use HELP for help.
cqlsh> INSERT INTO patient.exam (patient_id,id,date,details) values (10,1,now(),'first exam patient 10');
cqlsh> quit;
$ docker start node2
$ docker start node3
$ docker exec -it node3 cqlsh
Connected to Test Cluster at 127.0.0.1:9042.
[cqlsh 5.0.1 | Cassandra 3.11.0 | CQL spec 3.4.4 | Native protocol v4]
Use HELP for help.
cqlsh> select * from patient.exam where patient_id=10;
 patient_id | id | date                                 | details
------------+----+--------------------------------------+-----------------------
         10 |  1 | 76439070-8f04-11e7-a592-6d2c86545d91 | first exam patient 10
(1 rows)

ノードの整合性テスト

読み取り処理での厳密な整合性が必要な場合は、整合性レベル QUORUM を設定する必要があります。この設定では、あらゆるクエリーが少なくとも 2 つの利用可能なノード上でデータをチェックします。

$ docker stop node1
node1
$ docker stop node2
node2
$ docker exec -it node3 cqlsh
Connected to Test Cluster at 127.0.0.1:9042.
[cqlsh 5.0.1 | Cassandra 3.11.0 | CQL spec 3.4.4 | Native protocol v4]
Use HELP for help.
cqlsh> select * from patient.exam where patient_id=10;
 patient_id | id | date                                 | details
------------+----+--------------------------------------+-----------------------
         10 |  1 | 76439070-8f04-11e7-a592-6d2c86545d91 | first exam patient 10
(1 rows)
cqlsh> consistency quorum
Consistency level set to QUORUM.
cqlsh> select * from patient.exam where patient_id=10;
NoHostAvailable:

この場合、ノードの大半 (2 つ) が稼働中でなければ、クエリーは失敗します。これは、1 つのトレードオフです。可用性を高くすると同時に整合性を強化するとなると、ノードで障害が発生している場合にクラスター内で引き続き動作可能なノードの数を増やさなければなりません。整合性を ONE に設定すると、接続先の node3 上で 1 つのローカル・コピーを利用できるため、クエリーは成功します。

cqlsh> consistency one
Consistency level set to ONE.
cqlsh> select * from patient.exam where patient_id=10;
 patient_id | id | date                                 | details
------------+----+--------------------------------------+-----------------------
         10 |  1 | 76439070-8f04-11e7-a592-6d2c86545d91 | first exam patient 10
(1 rows)
cqlsh> quit;

node1 を再起動すると、ノードの過半数が稼働している状態になるため、QUORUM 整合性は満たされて、クエリーが失敗することはなくなります。

$ docker start node1
node1
$ docker exec -it node3 cqlsh
Connected to Test Cluster at 127.0.0.1:9042.
[cqlsh 5.0.1 | Cassandra 3.11.0 | CQL spec 3.4.4 | Native protocol v4]
Use HELP for help.
cqlsh> consistency quorum
Consistency level set to QUORUM.
cqlsh> select * from patient.exam where patient_id=10;
 patient_id | id | date                                 | details
------------+----+--------------------------------------+-----------------------
         10 |  1 | 76439070-8f04-11e7-a592-6d2c86545d91 | first exam patient 10
(1 rows)

ノードのステータスを調べると、2 つのノードが稼働中 (UN) で、1 つのノードがダウン (DN) していることを確認できます。

$ docker exec -it node3 nodetool status
Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address     Load       Tokens       Owns (effective)  Host ID                               Rack
DN  172.17.0.3  306.19 KiB  256          100.0%            fd135375-711a-471a-b4e5-409199bbaaa5  rack1
UN  172.17.0.2  365.72 KiB  256          100.0%            5db97fc3-70e9-48e5-b63b-0be67e35daea  rack1
UN  172.17.0.4  285.42 KiB  256          100.0%            4deb44f8-9253-4bff-b74b-239085e3a912  rack1

以上の他にも探求できるテスト・シナリオがあります。ノードの数を増やして、レイテンシー・テストやロード・バランシング・テストなどを行って、前述した Cassandra 分散型クラスターの特性を確認してください。

まとめ

このチュートリアルで私が目標としたのは、読者に Cassandra クラスターの基本的なインストールおよび構成手順を案内し、このクラスターの最も重要な特性を説明することです。また、この種の NoSQL データベースについて理解を深められるよう、いくつかの実践的手法も織り込むようにしました。このチュートリアルで学んだ知識があれば、独自のプロジェクトを開始して、そのプロジェクトの要件が Cassandra の特性と一致するようであれば、Cassandra を適用できるはずです。

ここでは取り上げませんでしたが、タイプの異なるデータ・セットに応じたモデリング手法や、管理タスク、そしてパフォーマンスを向上させるための微調整など、考慮しなければならない詳細は他にもあります。さらに、このチュートリアルのスコープからは外れていますが、開発に関連するクライアント・ドライバーの処理についての別の多くの側面もあります。これらのトピックはおそらく今後のチュートリアルで取り上げることもあるかと思いますが、差し当たり、Cassandra についてさらに詳しく調べてください。私がお勧めする情報源は、公式 Apache Cassandra Web サイトと DataStax ドキュメント Web サイトの 2 つです。これらのリンクについては、以下の「関連トピック」を参照してください。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Information Management, Open source
ArticleID=1059449
ArticleTitle=基本的な Apache Cassandra アーキテクチャーをセットアップする
publish-date=04122018