Cassandra 3.7 のクラスタ構築

Cassandraを触ってみています。

Cassandra 3.7をDebian 8.5(jessie)にaptでインストールする
Cassandra 3.7 cqlshでテーブルを作成してデータの登録、検索
Cassandra 外部アクセスを許可しPython(Datastax)で接続する


同じ構成の端末を2台用意し、クラスタ環境の構築を試してみます。


環境



OS:Debian 8.5
Cassandra:3.7

1台目IP:192.168.1.102
2台目IP:192.168.1.104

こんな環境です。






1台目の設定



1台目(192.168.1.102)の設定ファイルを編集していきます。

こちらを参考にしました。
Configuring Cassandra
6. Cassandraのクラスタ構築


設定ファイルを編集


# vi /etc/cassandra/cassandra.yaml




変更箇所は390行目付近のseedsの設定。
「127.0.0.1」となっている箇所を「192.168.1.102」に変更します。


seed_provider:
    # Addresses of hosts that are deemed contact points.
    # Cassandra nodes use this list of hosts to find each other and learn
    # the topology of the ring. You must change this if you are running
    # multiple nodes!
    - class_name: org.apache.cassandra.locator.SimpleSeedProvider
     parameters:
         # seeds is actually a comma-delimited list of addresses.
         # Ex: "<ip1>,<ip2>,<ip3>"
         - seeds: "192.168.1.102"






次は525行目。
listen_addressを「localhost」から「192.168.1.102」に変更します。


#listen_address: localhost
listen_address: 192.168.1.102




加えて、外部からアクセス可能なように構成しました。
Cassandra 外部アクセスを許可しPython(Datastax)で接続する

580行目の「start_rpc」をfalseからtrueに。


#start_rpc: false
start_rpc: true




600行目の「rpc_address」をlocalhostからサーバーのIPアドレスに。


#rpc_address: localhost
rpc_address: 192.168.1.102




これで1台目の設定は完了です。
cassandraを再起動しました。


# service cassandra restart







2台目の設定



2台目(192.168.1.104)の設定ファイルを編集していきます。
設定ファイルを編集


# vi /etc/cassandra/cassandra.yaml




変更箇所は390行目付近のseedsの設定。
「127.0.0.1」となっている箇所を「192.168.1.102」に変更します。
※192.168.1.104ではないことに注意。


seed_provider:
    # Addresses of hosts that are deemed contact points.
    # Cassandra nodes use this list of hosts to find each other and learn
    # the topology of the ring. You must change this if you are running
    # multiple nodes!
    - class_name: org.apache.cassandra.locator.SimpleSeedProvider
     parameters:
         # seeds is actually a comma-delimited list of addresses.
         # Ex: "<ip1>,<ip2>,<ip3>"
         - seeds: "192.168.1.102"




次は525行目。
listen_addressを「localhost」から「192.168.1.104」に変更します。


#listen_address: localhost
listen_address: 192.168.1.104




580行目の「start_rpc」をfalseからtrueに。


#start_rpc: false
start_rpc: true




600行目の「rpc_address」をlocalhostからサーバーのIPアドレスに。


#rpc_address: localhost
rpc_address: 192.168.1.104




これで2台目の設定は完了です。
cassandraを再起動しました。


# service cassandra restart




nodetoolで状態を表示してみます。


# nodetool status
Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address        Load     Tokens     Owns (effective) Host ID                             Rack
UN 192.168.1.104 223.81 KiB 256         49.2%             2a03c49b-6a65-4b73-9eb0-428da65e97b1 rack1
UN 192.168.1.102 257.18 KiB 256         50.8%             20067ac6-49aa-4987-9c88-bef1e4e01514 rack1



2つのノードを認識してくれたようです。





Owns (effective)



Owns (effective)は、データをどのように配分して保持しているかの割合のようです。
各々のノードが50%なので、半分ずつデータを保持しているということでしょうか。

これ、調べてみるとどうやら「CREATE KEYSPACE」で作成した時のオプションに依存するようです。
Cassandra 3.7 cqlshでテーブルを作成してデータの登録、検索


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




値に1を指定しています。
Pythonのドライバーからの引用ですが、
http://datastax.github.io/python-driver/api/cassandra.html#cassandra.ConsistencyLevel


ANY = 0
Only requires that one replica receives the write or the coordinator stores a hint to replay later. Valid only for writes.

ONE = 1
Only one replica needs to respond to consider the operation a success

TWO = 2
Two replicas must respond to consider the operation a success

THREE = 3
Three replicas must respond to consider the operation a success

QUORUM = 4
ceil(RF/2) replicas must respond to consider the operation a success

ALL = 5
All replicas must respond to consider the operation a success

LOCAL_QUORUM = 6
Requires a quorum of replicas in the local datacenter

EACH_QUORUM = 7
Requires a quorum of replicas in each datacenter

SERIAL = 8
For conditional inserts/updates that utilize Cassandra’s lightweight transactions, this requires consensus among all replicas for the modified data.

LOCAL_SERIAL = 9
Like SERIAL, but only requires consensus among replicas in the local datacenter.

LOCAL_ONE = 10
Sends a request only to replicas in the local datacenter and waits for one respo




1は1つのノードに書き込めばOKという指定でした。
「ALTER KEYSPACE」で「5:ALL」に変更してみます。


cqlsh:sample> ALTER KEYSPACE sample WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 5};
cqlsh:sample>




各々のノードのOwns (effective)が100%になりました。


# nodetool status
Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address        Load     Tokens     Owns (effective) Host ID                             Rack
UN 192.168.1.104 270.01 KiB 256         100.0%            2a03c49b-6a65-4b73-9eb0-428da65e97b1 rack1
UN 192.168.1.102 237.36 KiB 256         100.0%            20067ac6-49aa-4987-9c88-bef1e4e01514 rack1





【参考URL】

Configuring Cassandra

6. Cassandraのクラスタ構築



Cassandra 外部アクセスを許可しPython(Datastax)で接続する

Cassandraをインストールし、テーブルを作成。データを登録してみました。
Cassandra 3.7 cqlshでテーブルを作成してデータの登録、検索

別の端末からアクセスできるよう構成を変更し、
Python(Datastax Python driver)で接続してみます。



Cassandraの外部アクセス許可



Cassandraにはデフォルトで9042番ポートで接続します。
試しにtelnetしてみたら接続が拒否されました。


$ telnet 192.168.1.102 9042
Trying 192.168.1.102...
telnet: Unable to connect to remote host: Connection refused




外部からアクセスできるようCassandraの設定ファイルを編集します。


# vi /etc/cassandra/cassandra.yaml




編集するのは2箇所。
580行目の「start_rpc」をfalseからtrueに。


#start_rpc: false
start_rpc: true




600行目の「rpc_address」をlocalhostからサーバーのIPアドレスに。


#rpc_address: localhost
rpc_address: 192.168.1.102




編集が終わったらCassandraを再起動します。


# service cassandra restart




これで9042ポートに接続できるようになるはずです。


$ telnet 192.168.1.102 9042
Trying 192.168.1.102...
Connected to 192.168.1.102.
Escape character is '^]'.
^]
telnet> quit
Connection closed.





設定を変更したら、cqlshで接続できなくなります。


# cqlsh
Connection error: ('Unable to connect to any servers',
{'127.0.0.1': error(111, "Tried connecting to [('127.0.0.1', 9042)]. Last error: Connection refused")})




今後はIPアドレスを指定して接続することになります。


# cqlsh 192.168.1.102
Connected to Test Cluster at 192.168.1.102:9042.
[cqlsh 5.0.1 | Cassandra 3.7 | CQL spec 3.4.2 | Native protocol v4]
Use HELP for help.
cqlsh>







cassandra-driverのインストール



https://github.com/datastax/python-driver
こちらのドライバーを使用します。

インストール手順に従い、Ubuntu 16.04にインストールしました。
http://datastax.github.io/python-driver/installation.html


ビルド時に必要なライブラリをインストール


$ sudo apt install python-setuptools build-essential python-dev libev4 libev-dev




本体のインストール


$ sudo easy_install cassandra-driver




サンプルを参考に、
Cassandra 3.7 cqlshでテーブルを作成してデータの登録、検索
ここで登録したデータを検索してみます。
「sample」キースペースにある「t」テーブルへのselectです。


  1. # -*- coding:utf-8 -*-
  2. from cassandra.cluster import Cluster
  3. cluster = Cluster(['192.168.1.102'])
  4. session = cluster.connect('sample')
  5. rows = session.execute('SELECT id, value FROM t')
  6. for row in rows:
  7.     print row.id, row.value




実行してみるとちゃんとデータが取得できました。


$ python sample.py
2 テスト2




登録、削除も行ってみます。


  1. # -*- coding:utf-8 -*-
  2. from cassandra.cluster import Cluster
  3. cluster = Cluster(['192.168.1.102'])
  4. session = cluster.connect('sample')
  5. # id:3のデータを追加
  6. session.execute('INSERT INTO t(id, value) VALUES (%s, %s)', (3, u'テスト3'))
  7. # id:2のデータを削除
  8. session.execute('DELETE FROM t WHERE id = %s', (2, ))
  9. rows = session.execute('SELECT id, value FROM t')
  10. for row in rows:
  11.     print row.id, row.value




想定通りの結果です。


$ python sample.py
3 テスト3







BatchStatementによる一括登録



こちらを見ていると、バッチ実行で一括登録する機能があるようです。
http://datastax.github.io/python-driver/api/cassandra/query.html

動かしてみます。


  1. # -*- coding:utf-8 -*-
  2. from cassandra.cluster import Cluster
  3. from cassandra.query import BatchStatement
  4. cluster = Cluster(['192.168.1.102'])
  5. session = cluster.connect('sample')
  6. # データを全件削除
  7. # DELETE FROM tはエラーになる
  8. session.execute('TRUNCATE TABLE t')
  9. # BatchStatementによる一括登録
  10. # 「%s」ではなく「?」でパラメーターを指定
  11. insert_data = session.prepare("INSERT INTO t(id, value) VALUES (?, ?)")
  12. batch = BatchStatement()
  13. batch.add(insert_data, (1, u'テスト登録1'))
  14. batch.add(insert_data, (2, u'テスト登録2'))
  15. batch.add(insert_data, (3, u'テスト登録3'))
  16. batch.add(insert_data, (4, u'テスト登録4'))
  17. # 一括登録実行
  18. session.execute(batch)
  19. rows = session.execute('SELECT id, value FROM t')
  20. for row in rows:
  21.     print row.id, row.value




いい感じです。


$ python sample.py
1 テスト登録1
2 テスト登録2
4 テスト登録4
3 テスト登録3






【参考URL】

Configuring Cassandra

The cassandra.yaml configuration file

Client drivers

DataStax Python Driver for Apache Cassandra

Installation

Getting Started



Cassandra 3.7 cqlshでテーブルを作成してデータの登録、検索

Cassandra 3.7をDebianにインストールしてみました。
Cassandra 3.7をDebian 8.5(jessie)にaptでインストールする


今回は、cqlshを使用してテーブルの作成とデータの登録、検索を行ってみます。


KEYSPACE,TABLEの作成



こちらを参考にしました。
http://cassandra.apache.org/doc/latest/cql/ddl.html

テーブルを作成する前に、キースペースを作成する必要があります。
RDBだと「データベース」の概念でしょうか。
作成したキースペース内にテーブルを作成します。

cqlshを起動して、「CREATE KEYSPACE」でキースペースを作成します。

構文は以下の通り。


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




WITHオプションは必須です。
別のデータベースとレプリケーションを行う際のアルゴリズムをclassで指定します。
http://cassandra.apache.org/doc/latest/architecture/dynamo.html


今回は「SimpleStrategy」を指定しました。
最低いくつのノードに書き込むかを「replication_factor」で指定します。
スタンドアロンな環境なので1を指定しました。


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




キースペースを表示するには「DESCRIBE keyspaces」を実行します。
How to list all the available keyspaces in Cassandra?


cqlsh> DESCRIBE keyspaces;

system_schema system_auth system sample system_distributed system_traces



sampleキースペースが追加されていることが確認できました。


「USE sample」で作成したキースペースに切り替えます。


cqlsh> USE sample;
cqlsh:sample>






続いて、sampleキースペースにテーブルを作成します。
一般的なデータベースのcreate table文とほとんど同じです。
こんなテーブルを作成しました。


  1. CREATE TABLE t (
  2.     id int,
  3.     value text,
  4.     PRIMARY KEY (id)
  5. );



PRIMARY KEYの指定は必須です。
指定しないとこんなエラーが表示されます。


InvalidRequest: code=2200 [Invalid query] message="No PRIMARY KEY specifed (exactly one required)"




実行してみます。


cqlsh:sample> CREATE TABLE t (
         ...     id int,
         ...     value text,
         ...     PRIMARY KEY (id)
         ... );



これで「t」テーブルが作成できました。
「DESCRIBE tables」でテーブルの一覧が表示できます。


cqlsh:sample> DESCRIBE tables;

t



表示は寂しいですが、ちゃんとテーブルが作成できました。






データの登録と検索




作成したテーブルにデータを登録してみます。
一般的なデータベースのinsert文と同じ構文です。


  1. INSERT INTO t (id, value) VALUES (1, 'テスト1');




2レコード追加しました。


cqlsh:sample> INSERT INTO t (id, value) VALUES (1, 'テスト1');
cqlsh:sample> INSERT INTO t (id, value) VALUES (2, 'テスト2');




selectでデータを検索してみます。


cqlsh:sample> SELECT * FROM t;

id | value
----+----------
1 | テスト1
2 | テスト2

(2 rows)




もちろんwhere句で検索条件が指定できます。


cqlsh:sample> SELECT * FROM t WHERE id = 2;

id | value
----+----------
2 | テスト2






データを更新するにはupdate。
通常のデータベースと同じ感覚で使用できますね。


  1. UPDATE t SET value = 'テスト1変更' WHERE id = 1;



実行してみます。


cqlsh:sample> UPDATE t SET value = 'テスト1変更' WHERE id = 1;
cqlsh:sample> SELECT * FROM t;

id | value
----+--------------
1 | テスト1変更
2 |     テスト2

(2 rows)






データの削除はdeleteです。


  1. DELETE FROM t WHERE id = 1;




実行結果


cqlsh:sample> DELETE FROM t WHERE id = 1;
cqlsh:sample> SELECT * FROM t;

id | value
----+----------
2 | テスト2

(1 rows)




次はPythonで別の端末から接続してみたいと思います。






【参考URL】

Data Definition

Data Manipulation

How to list all the available keyspaces in Cassandra?

cqlsh commands


Cassandra 3.7をDebian 8.5(jessie)にaptでインストールする

久しぶりにCassandraを触ってみようと思います。
http://cassandra.apache.org/

以前触った時は、バージョン0.4.2でしたが今は3.7までバージョンが上がっていました。
Debin 8(jessie)にaptでインストールしてみます。


OpenJDK 8のインストール



cassandraのインストールにはOpenJDK 8が必要です。
インストール時にこんなエラーが発生しました。


# apt-get install cassandra
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
インストールすることができないパッケージがありました。おそらく、あり得
ない状況を要求したか、(不安定版ディストリビューションを使用しているの
であれば) 必要なパッケージがまだ作成されていなかったり Incoming から移
動されていないことが考えられます。
以下の情報がこの問題を解決するために役立つかもしれません:

以下のパッケージには満たせない依存関係があります:
cassandra : 依存: openjdk-8-jre-headless しかし、インストールすることができません または
                     java8-runtime しかし、インストールすることができません
             推奨: ntp しかし、インストールされようとしていません または
                     time-daemon
E: 問題を解決することができません。壊れた変更禁止パッケージがあります。




先にOpenJDK 8をインストールしておきます。
Debian 8(jessie)にOpenJDK 8をインストールする


/etc/apt/sources.list.d/openjdk.listを作成。


# vi /etc/apt/sources.list.d/openjdk.list




ファイルにOpenJDK 8のリポジトリを記載します。


deb http://ftp.jp.debian.org/debian/ jessie-backports main




ファイルを作成したら、update, installを実行します。


# apt-get update
# apt-get install openjdk-8-jdk




OpenJDK 1.8.0_102がインストールできました。


# java -version
openjdk version "1.8.0_102"
OpenJDK Runtime Environment (build 1.8.0_102-8u102-b14.1-1~bpo8+1-b14)
OpenJDK 64-Bit Server VM (build 25.102-b14, mixed mode)







cassandraのインストール



こちらを参考にインストールを行います。
http://cassandra.apache.org/download/

/etc/apt/sources.list.d/cassandra.listというファイルを作成。
リポジトリのパスを記載します。


# vi /etc/apt/sources.list.d/cassandra.list




記載する書式は以下のとおりです。
[release series]の箇所にインストールしたいcassandraのバージョンを記載します。


deb http://www.apache.org/dist/cassandra/debian [release series] main
deb-src http://www.apache.org/dist/cassandra/debian [release series] main




バージョン名は、このURLで公開されているディレクトリ名と対応しているようです。
http://dl.bintray.com/apache/cassandra/dists/

「3.7」をインストールしたい場合は「37x」と指定します。


deb http://www.apache.org/dist/cassandra/debian 37x main
deb-src http://www.apache.org/dist/cassandra/debian 37x main




ファイルを記載したら、認証キーを追加。


# gpg --keyserver pgp.mit.edu --recv-keys 0353B12C gpg --export --armor 0353B12C | apt-key add -



この後のapt-get updateで以下のエラーが発生する場合があります。


W: GPG エラー: http://www.apache.org 37x InRelease:
公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY 749D6EEC0353B12C



発生した場合は、以下のコマンドを実行します。
New Debian/Ubuntu Repository GPG Signer


# gpg --export --armor 749D6EEC0353B12C | apt-key add -




準備が終わったらupdateとインストールを実行します。


# apt-get update
# apt-get install cassandra




あっさりインストールできました。
起動状態を確認してみます。


# /etc/init.d/cassandra status
● cassandra.service - LSB: distributed storage system for structured data
Loaded: loaded (/etc/init.d/cassandra)
Active: active (running) since 木 2016-08-11 18:32:41 JST; 1min 13s ago
CGroup: /system.slice/cassandra.service
         └─10992 java -Xloggc:/var/log/cassandra/gc.log -ea -XX:+UseThreadP...



activeになっていますね。





クエリーの実行



cassandraの起動確認も兼ねて、クエリーを実行してみます。
Inserting and querying

インストール時、cqlshにパスを通してくれるので以下のコマンドでcqlshが起動します。


# cqlsh localhost
Connected to Test Cluster at localhost:9042.
[cqlsh 5.0.1 | Cassandra 3.7 | CQL spec 3.4.2 | Native protocol v4]
Use HELP for help.
cqlsh>




クエリーを実行してシステムの情報を表示してみます。


cqlsh> SELECT cluster_name, listen_address FROM system.local;

cluster_name | listen_address
--------------+----------------
Test Cluster |     127.0.0.1

(1 rows)



706_01.png

Test Clusterというクラスターがデフォルトで作成されるようです。
次は実際にデータの登録や検索を行ってみます。


Visual Basic 2010 ExpressでCassandraを操作する 登録編

Visual C# 2010 ExpressからDebianで動いているCassandraに接続してみました。

Visual C# 2010 ExpressでCassandraを操作する 登録編
Visual C# 2010 ExpressでCassandraを操作する 検索編


そういば、.Net Frameworkで動作するDLLに変換しているのだから
Visual Basic 2010でもプログラムが書けるのでは?

ということで、試してみました。



ライブラリの準備



提供されているライブラリはC#版なので、とりあえず
「Thrift.dll」と「cassandra.dll」をVisual C# 2010でビルドします。
Visual C# 2010 ExpressでThriftのライブラリをビルドする
Visual C# 2010 ExpressでCassandraのライブラリをビルドする



Visual Basicのプロジェクト作成



「CassandraSample」という名前でWindows フォームアプリケーションを作成します。
08_001_20100531001117.png


プロジェクト名を右クリックして[参照の追加]を選択します。
08_002.png


参照タブを表示し、C#でビルドした「Thrift.dll」と「cassandra.dll」を追加します。
08_003.png




サンプルソース



こんな感じです。


'Thrift
Imports Thrift
Imports Thrift.Transport
Imports Thrift.Protocol
Imports Thrift.Server

'Cassandra
Imports Apache.Cassandra

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim transport As TTransport = New TSocket("192.168.1.242", 9160)
        Dim protocol As TProtocol = New TBinaryProtocol(transport)
        Dim client As Cassandra.Client = New Cassandra.Client(protocol)

        Try
            transport.Open()

            Dim utf8Encoding As System.Text.Encoding = New System.Text.UTF8Encoding
            Dim timeStamp As Long = DateTime.Now.Millisecond

            Dim nameColumnPath As New ColumnPath
            nameColumnPath.Column_family = "Standard1"
            nameColumnPath.Column = utf8Encoding.GetBytes(TextColumn.Text)

            'キースペース名を指定
            '画面上に入力されたキー名称
            '上で作成したカラムパス
            '画面上に入力された値

            client.insert("Keyspace1",
                        TextKey.Text,
                        nameColumnPath,
                        utf8Encoding.GetBytes(TextValue.Text),
                        timeStamp,
                        ConsistencyLevel.ONE)

            transport.Close()

            MessageBox.Show("登録完了")

        Catch ex As Exception
            MessageBox.Show(ex.Message)

        End Try

    End Sub
End Class





C#のコードを参考に書いてます。
簡単に移植できました。



実行してみると・・・

08_004.png



cassandra-cliで確認するとちゃんと登録されています。


# bin/cassandra-cli --host localhost --port 9160
cassandra> get Keyspace1.Standard1['vb']['test']
=> (column=74657374, value=value, timestamp=63)





こんなに簡単にC#でビルドしたdllがVBから呼び出せるとは・・・
Visual Basic、かなり開発に使えるのでは?







プロフィール

Author:symfo
blog形式だと探しにくいので、まとめサイト作成中です。
Symfoware まとめ

PR




検索フォーム

月別アーカイブ