CentOS7.0にMySQL5.6をインストールしてみた。

VirtualBoxにCentOS7.0をインストールし、MySQLを使ってみる。CentOS7.0では、デフォルトでMariaDBというのが入っている。以前はMySQLだったが、CentOS7.0からMariaDBに変わったらしい。MySQL5.5からMySQL5.6とMariaDBに分岐したようだ。不勉強でMariaDBは使ったことがない。移行は容易らしいが、親しみのあるMySQL5.6の方にしてみた。

(1) MariaDBをアンインストールする。

MySQL5.6をインストールするためには、プリインストールされているMariaDBをremoveする必要がある。mariadb-libsが入っていたのでこれを削除した。


# yum list installed | grep maria
# yum -y remove mariadb-libs

(2) MySQL5.6を取得してきて、インストールする。


# yum -y install http://dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm
# yum info mysql-community-server
Available Packages
Name : mysql-community-server
Arch : x86_64
Version : 5.6.21
Release : 2.el6
Size : 53 M
Repo : mysql56-community

# yum -y install mysql-community-server
# mysqld --version
mysqld Ver 5.6.21 for Linux on x86_64 (MySQL Community Server (GPL))
# mysql -uroot
・・・
mysql>

yumを使って簡単にインストールできる。すぐに利用可能となる。自前のデータを投入したいので、character-setなどを変更したい。

(3) /etc/my.cnfを編集するとエラーになった。(character_set_serverに対応)

MySQL5.6の /etc/my.cnf を編集して、default-character-set=utf8 を追加したら、サービス起動でエラーになった。


# /etc/init.d/mysqld restart
Restarting mysqld (via systemctl): Job for mysqld.service failed.
See 'systemctl status mysqld.service' and 'journalctl -xn' for details. [失敗]
ステータスを見ろと言われる。

# systemctl status mysqld.service
mysqld.service - SYSV: MySQL database server.
Loaded: loaded (/etc/rc.d/init.d/mysqld)
Active: failed (Result: exit-code) since 2015-09-03 11:31:29 JST; 1min 50s ago

9月 03 11:31:26 systemd[1]: Starting SYSV: MySQL database server....
9月 03 11:31:29 mysqld[7104]: MySQL Daemon failed to start.
9月 03 11:31:29 mysqld[7104]: Starting mysqld: [失敗]
9月 03 11:31:29 systemd[1]: mysqld.service: control process exited,...=1
9月 03 11:31:29 systemd[1]: Failed to start SYSV: MySQL database se.....
9月 03 11:31:29 systemd[1]: Unit mysqld.service entered failed state.

# cd /var/log
# tail -200 mysqld.log
・・・
2015-09-03 11:31:26 7359 [Note] InnoDB: 5.6.26 started; log sequence number 1626077
2015-09-03 11:31:26 7359 [ERROR] /usr/sbin/mysqld: unknown variable 'default-character-set=utf8'
2015-09-03 11:31:26 7359 [ERROR] Aborting

default-character-set=utf8 を認識してくれない。ネット情報から「サーバー側は、MySQL5.5から表記が変わったようです。新しい書き方は、character_set_server=utf8 」というのを見つけた。私がインストールしたのは5.6だ。変数名のエイリアスが許可されなくなったようだ。character_set_server は見たことがある。mysqlコンソールで show variables をやった時に表示される変数名だ。

mysql> show variables like 'char%';
 +--------------------------+-------------+
 | Variable_name | Value |
 +--------------------------+-------------+
 | character_set_client | utf8 |
 | character_set_connection | utf8 |
 | character_set_database | utf8 |
 | character_set_filesystem | binary |
 | character_set_results | utf8 |
 | character_set_server | utf8 |
 | character_set_system | utf8 |
 +----------------------------------------+
ここでまた早まったことをやってしまった。[mysqld]では character_set_server だが、[client]や[mysql]では character_set_client=utf8 は受け付けてくれない。従来の default-character-set=utf8 のままで良かった。紛らわしい。ハイフンとアンスコの違いにも注意だ。最終的に、my.cnf は以下の感じに記述した。
[mysqld]
lower_case_table_names=1
character_set_server=utf8 # ここの記述を変更するだけ!
[mysql]
default-character-set=utf8 # ここは従来通り!
[mysqldump]
default-character-ser=utf8

再起動して、mysqlコンソールで確認してみる。

# /etc/init.d/mysqld restart
Restarting mysqld (via systemctl): [ OK ]
# mysql -uroot
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.6.26 MySQL Community Server (GPL)
・・・
mysql> show variables like 'char%';
・・・
うまくいっている。サービスが自動で起動されるようにしておく。

# chkconfig --list mysqld
mysqld 0:off 1:off 2:off 3:off 4:off 5:off 6:off
# chkconfig mysqld on
# chkconfig --list mysqld
mysqld 0:off 1:off 2:on 3:on 4:on 5:on 6:off

ホストOSとゲストOSでディレクトリを共有する。

VirtualBoxCentOSを入れて、ホストOS(Windows側)とゲストOS(CentOS側)でディレクトリを共有するための設定手順をメモしておく。

(1) Guest Additionsをインストールする。

  • 以下を取り込んでおく。


# yum upgrade
# yum install kernel-devel gcc

  • ここでCentOSを再起動する。再起動しないとうまくいかないらしい。
  • VirtualBoxの[デバイス]-->[Guest AdditionsのCDイメージを挿入]をクリックする。
  • CDを実行するかどうかを尋ねるダイアログが表示される。[実行する]をクリックする。
  • 現在使用しているアカウントのパスワードの入力を求められるので入力する。端末が立ち上がり、自動的にインストールが始まる。Press Return to close this window...という表示が出てきたら、エンターキーを押す。

(2) VirtualBoxで共有フォルダを設定する。

  • VirtualBoxマネージャで、作成した仮想マシンを選択し、左上の「設定」をクリックする。
  • 左のメニューから「共有フォルダ」を選択する。「新規共有フォルダを追加」を選ぶ。
  • 「共有フォルダの追加」画面で設定する。c:\share-vboxというディレクトリを作成して共有してみる。名前=share-vbox、パス=c:\share-vbox、自動マウント=Yesにしてみる。Windows側で c:\share-vbox に aaa.txt のようなダミーのテキストファイルを作ってみる。

(3) CentOS側で共有を確認する。


# cd /media
# ls
sf_share-vbox
# cd sf_share-vbox
# ls
aaa.txt
# echo test > bbb.txt
# ls
aaa.txt bbb.txt
# ln -s /media/sf_share-vbox /var/share-vbox
# gpasswd --add <ユーザー> vboxsf
共有を確認できた。個人的に共有は/varの下で行う習慣なので、/media/sf_share-vbox は馴染みにくい。/var/share-vbox としてシンボリックリンクしておく。共有フォルダは、vboxsfというグループにしかアクセス権限がないので、自身のアカウントで利用できるようにvboxsfグループに所属させておく。

VirtualBoxでCentOS 7.0を使ってみる。

CentOSもしばらく触っていないと、いろいろなことを忘れてしまう。バージョンも今は7.0なのか。WindowsPCにVirtualBoxを入れ、そこにCentOS 7.0をインストールしてみることにした。手順を残しておこう。

(1) CentOS7.0をダウンロードする。

(2) VirtualBoxをダウンロードし、インストールする。

(3) VirtualBoxを起動し、仮想マシンを作成する。

  • VirtualBoxマネージャを起動し、「新規」をクリックして「仮想マシンの作成」を開く。
  • 任意の名前("CentOS7.0"など)を入力し、LinuxRed Hat(64bit)を選択して、次へ進む。
  • メモリは最低でも768MBが必要と出ていた。私は 1,500MB 程度にした。
  • 「仮想ハードドライブを作成する」を選択し、VDI (VirtualBox Disk Image)を選択して、次へ進む。
  • 物理ハードドライブにあるストレージは、固定サイズを選択して、次へ進む
  • ファイルの場所とサイズでは、仮想ドライブの容量を指定して、仮想ドライブと仮想マシンを作成する。私は 30GB 程度にした。

(4) CentOS7.0をインストールする。

  • VirtualBoxマネージャで、作成した仮想マシンを選択し、起動する。
  • 「起動ハードディスクを選択」画面のプルダウンメニュー右で「仮想光学ディスクファイルの選択」クリックし、ダウンロードしておいたISOイメージを選択し、インストーラを開始する。
  • インストール時に使用する言語で「日本語 Japanese」を指定する。
  • 「ソフトウェアの選択」を選択し、左のベース環境から「サーバー (GUI使用) 」を選択して「完了」する。
  • 「インストール先」を選択し、何もせずに「完了」する。
  • 「ネットワークとホスト名」を選択し、「ネットワークとホスト名」設定画面の右上にあるスイッチを「オン」にして「完了」する。
  • ユーザー設定で「rootパスワード」を選択し、任意のパスワードを設定する。
  • 「ユーザーの作成」を選択し、ユーザー名とパスワードを入力、sudoコマンドを有効にするためには管理者に設定しておく。
  • CentOSのインストールが完了したら「再起動」する。
  • 初期セットアップ画面が表示され、ログイン画面に切り替わる。先ほど作成したユーザーを指定する。
  • 日本語、入力ソース、オンラインアカウントはそのままにして、次へ進む。
  • 「Start using CentOS Linux」をクリックしてセットアップが完了する。

GNOMEパネル右側にある 「ja」をクリックし、「日本語 (Kana Kanji) 」を選択して日本語入力ができる。
※マウス統合を有効にすると、Ctrlキーを押さなくてもゲストOSとホストOSの間でマウスの制御が自動で切り替わる。
※ゲストOSのファイルメニューから、デバイス-->クリップボードの共有-->双方向を選択しておくとよい。必要ならデバイス-->ドラッグ&ドロップ-->双方向も可能だ。

SWEBOK V3 を読んでみた。

SWEBOK V3がやっと、2014/11/21にリリースされた。4,000円だ。私も昨日購入して、ざっと眺めてみた。SWEBOK 2004版が2005年に出てから9年以上も経過しているのに、内容はあまり変化がないなというのが感想だ。これまでの10個の知識領域で比較すると、新たな記述はアジャイルプロセスや再利用に関する部分が補充されている程度だ。

SWEBOK V3のドラフト版では、ソフトウェア計量(Measurement)、ソフトウェアセキュリティ(Security)も知識領域として挙がっていたが、独立した知識領域にはならなかったようだ。そのため、10個の知識領域も大して変化のないものになっている。ただ、10個の知識領域もあらたに訳し直したようで、2004版での誤訳が多くの箇所で修正されていた。

知識領域にもう1つ「プロとしての実践(Professional Practices)」が追加され、さらに4つの教育領域が追加されている。エンジニアリング経済基礎(Engineering Economics foundations)、コンピュータ基礎(Computing foundations)、数学基礎(Mathematical foundations)、一般エンジニアリング基礎(Engineering foundations)だ。これら5つの領域も2005年にはCSDPのシラバスとしてSWEBOKとは別に存在していたので、それらがマージされただけと言える。SWEBOKは、当初よりプロ(職業人)としての拠り所となるだけでなく、ソフトウェアエンジニアリングを学ぶ学生のベースになるものとされていた。2004年版は前者にしか対応できなかった(間に合わなかった)が、V3でやっと後者にも対応できたということだろう。なお、V3での訳語はどうも気に入らない。専門技術者実践規律ではないように思うし、計算基礎よりコンピュータ基礎の方が適切だと思うな。

数学基礎

教育領域の内容は難しいな。たとえば、数学基礎の教育領域だ。日本語訳が難解すぎる。訳語が適切でない感じがする。知らないのだが「戦前」の数学ではないか。訳者が数学を知らないのかもしれない。たとえば、以下のような訳語が使われている。


×分布法則 --> ○分配則、分配律
×矛盾を使う証明 --> ○背理法
×帰納推論を使う証明 --> ○帰納法
×一致(Identity)、一致要素 --> ○単位元
×逆転(Inverse)、逆要素 --> ○逆元
distributiveは一般には「分配」だと思うが「分布」と訳されている。分配法則、分配律と呼んでほしいのに、分布法則となっている。聞いたことがない。上記のように一般的な背理法帰納法単位元、逆元といった用語も使われていないのだ。誤植もあった。矛盾律が「矛盾率」になっている。構成は以下の感じだ。以前、ドラフトで出ていた構成と変わってはいない。

14 数学基礎(Mathematical foundations)
+-- 1 関数、関係、集合(Functions, Relations, Sets)
| +-- 1.1 集合演算
| +-- 1.2 集合の性質
| +-- 1.3 関係と関数
+-- 2 論理
| +-- 2.1 命題論理(prepositional)
| +-- 2.2 述語論理(predicate)
+-- 3 証明法
| +-- 3.1 定理証明法
| | +-- 直接証明(direct)
| | +-- 背理法(contradiction)
| | +-- 帰納法(inductive)
+-- 4 計数(Basic Counting)
+-- 5 グラフとツリー(Graphs, Trees)
| +-- 5.1 グラフ
| +-- 5.2 ツリー
+-- 6 離散確率(Discrete Probability)
+-- 7 有限ステートマシン(Finite State Machines)
+-- 8 文法(Grammars)
| +-- 8.1 言語認識
+-- 9 精度と誤差(Numerical precision, accuracy, errors)
+-- 10 数論(Number Theory)
| +-- 10.1 整除性
| +-- 10.2 素数、最大公約数
+-- 11 代数(Algebraic Structures)
+-- 11.1 群
+-- 11.2 環
さらに命題論理の解説の中が、明治時代的だ。

conjunction 連言 --> 論理積(∧)
disjunction 選言 --> 論理和(∨)
implication 含意 --> 導出(→)
tautology 恒真
contradiction 矛盾
contingency 随伴
私は、連言、選言、含意、恒真、随伴という表現を知らなかった。こんな用語がソフトウェアエンジニアリングに必要なのか。「→」のマークを「含意」と呼ぶそうだ。私は「ならば」くらいにしか読んでなかった。連言、選言は、論理積論理和で十分だろう。恒真に至っては仏教用語かと思った。「常にtrue」という意味で恒真というのか。
といった感じで、SWEBOK V3の教育領域が一体何に利用できるか、悩んでいる。

CassandraとHectorを試してみる。(3)

Cassandra(カサンドラ)とHector(ヘクタ)をScalaで試してみたいが、Cassandraの学習どまりで、なかなかHectorまで辿りつけない。

(1) Cassandraの復習

Cassandraの最新は、2013/09/25時点で apache-cassandra-2.0.1-bin.tar.gz になっていた。"demo" というkeyspaceに"users"というcolumn familyを作成してみた。このデータにHectorからアクセスできるようにしてみたい。


[default@unknown] create keyspace demo;
f8ddf6cc-99e5-3736-b5c3-1b98d765c3d0
[default@unknown] use demo;
Authenticated to keyspace: demo

[default@demo] create column family users with comparator=UTF8Type and
default_validation_class=UTF8Type and key_validation_class=UTF8Type
da16021c-1c9d-388d-a9ff-e9dacfa47d95

[default@demo] set users['ID00001']['uid'] = 'ID00001'; // ユニークIDはRow名=uidで重複して持たせた
Value inserted.
Elapsed time: 209 msec(s).
[default@demo] set users['ID00001']['name'] = 'tacohachi';
Value inserted.
Elapsed time: 5.5 msec(s).
[default@demo] set users['ID00001']['age'] = '39'; // 数値もとりあえず文字列で代入
Value inserted.
Elapsed time: 9.46 msec(s).

[default@demo] get users['ID00001'];
=> (name=age, value=39, timestamp=1380168529216000)
=> (name=name, value=tacohachi, timestamp=1380168521788000)
=> (name=uid, value=ID00001, timestamp=1380168501150000)
Returned 3 results.
Elapsed time: 95 msec(s).

[default@demo] list users; // listというコマンドが便利
Using default limit of 100
Using default cell limit of 100

                                    • -

RowKey: ID00001
=> (name=age, value=39, timestamp=1380168529216000)
=> (name=name, value=tacohachi, timestamp=1380168521788000)
=> (name=uid, value=ID00001, timestamp=1380168501150000)

1 Row Returned.
Elapsed time: 271 msec(s).
[default@demo]

ちなみにkeyspace,column family,key(=row),super column,valueの関係は、以下の感じになる。実際にはuse demo;して利用するので「demo.」の部分は不要だ。key(=row)の字面を何にすればよいかは判断できていないが、RDBでのunique keyに相当する値を用いるべきだろう。例ではuidをunique keyとしているので、'ID00001'が重複したように見えてしまう。

set demo.users['ID00001']['uid'] = 'ID00001'
set demo.users['ID00001']['name'] = 'tacohachi'
set demo.users['ID00001']['age'] = '39'
│ │ │ │ └ value
│ │ │ └ column
│ │ └ key(=row)
│ └ column family
└ keyspace

set demo.users['ID00001']['home' ]['phone'] = '090-xxxx-xxxx'
set demo.users['ID00001']['home' ]['zip-code'] = '210-xxxx'
set demo.users['ID00001']['company']['phone'] = '03-xxxx-xxxx'
│ │ │ │ │ └ value
│ │ │ │ └ column
│ │ │ └ super column
│ │ └ key(=row)
│ └ column family
└ keyspace

実際にcliのコマンドとして利用するときは、

[default@unknown] use demo;
[default@demo] set users['ID00001']['uid'] = 'ID00001';
の感じだ。またsuper columnを使うには、create column familyでcolumn_type=Superとsubcomparator=UTF8Typeを指定しておく必要がある。階層を合わせるためにダミーで[00](16進で0)を指定してみたが、['base']のような字面でも良いかもしれない。

[default@unknown] use demo;
[default@demo] create column family persons
with column_type=Super // これが必要
and comparator=UTF8Type
and subcomparator=UTF8Type // これも必要
and default_validation_class=UTF8Type
and key_validation_class=UTF8Type;
[default@demo] set persons['ID00001'][00]['uid']= 'ID00001';
[default@demo] set persons['ID00001'][00]['name'] = 'tacohachi';
[default@demo] set persons['ID00001']['home']['phone'] = '090-xxxx-xxxx';
[default@demo] set persons['ID00001']['home']['zip-code'] = '210-xxxx';
[default@demo] set persons['ID00001']['company']['phone'] = '03-xxxx-xxxx';
[default@demo] list persons;
Using default limit of 100
Using default cell limit of 100

                                    • -

RowKey: ID00001
=> (super_column=00,
(name=name, value=tacohachi, timestamp=1380353550907000)
(name=uid, value=ID00001, timestamp=1380353540368000))
=> (super_column=company,
(name=phone, value=03-xxxx-xxxx, timestamp=1380353583390000))
=> (super_column=home,
(name=phone, value=090-xxxx-xxxx, timestamp=1380353569578000)
(name=zip-code, value=210-xxxx, timestamp=1380353576766000))

1 Row Returned.
Elapsed time: 42 msec(s).

(2) Cassandraのストレージ

Cassandraのデータは標準では、var/lib/cassandra/data にdbファイルとして保持される。Linux風のディレクトリだ。メモリ上にキャッシュされているデータは、dbファイルと同期していない可能性ある。明示的に flush する必要がある。またスナップショトとして保持することも可能だ。スナップショトを取ると強制的にflushされる。スナップショトしたdbファイルはバックアップとして利用できる。これらの実行はcassandraで提供されるツールnodetoolを利用する。"demo"のkeyspaceに対して試してみる。


> nodetool flush demo // flushして保存する。
Starting NodeTool
> nodetool snapshot demo // スナップショトとしてコピーを生成する。
Starting NodeTool
Requested creating snapshot for: demo
Snapshot directory: 1380169417960

> nodetool clearsnapshot // ちなみにclearsnapshotでスナップショトは削除される
Starting NodeTool
Requested clearing snapshot for: all keyspaces

var/lib/cassandra/dataを覗いてみる。demoの配下には"users"というcolumn familyが作られている。column familyはディレクトリで表現されるのだ。その配下に、先ほど作成したスナップショトもある。

var
├─lib
│ └─cassandra
│ ├─commitlog
│ ├─data
│ │ ├─demo
│ │ │ └─users
│ │ │ │ demo-users-jb-1-CompressionInfo.db
│ │ │ │ demo-users-jb-1-Data.db
│ │ │ │ demo-users-jb-1-Filter.db
│ │ │ │ demo-users-jb-1-Index.db
│ │ │ │ demo-users-jb-1-Statistics.db
│ │ │ │ demo-users-jb-1-Summary.db
│ │ │ │ demo-users-jb-1-TOC.txt
│ │ │ │
│ │ │ └─snapshots
│ │ │ └─1380169417960
│ │ │ demo-users-jb-1-CompressionInfo.db
│ │ │ demo-users-jb-1-Data.db
│ │ │ demo-users-jb-1-Filter.db
│ │ │ demo-users-jb-1-Index.db
│ │ │ demo-users-jb-1-Statistics.db
│ │ │ demo-users-jb-1-Summary.db
│ │ │ demo-users-jb-1-TOC.txt
│ │ │
│ │ ├─system
│ │ │ ├─batchlog
│ │ │ ├─compactions_in_progress
│ │ │ ├─hints
│ │ │ ├─IndexInfo
│ │ │ ├─local
│ │ │ ├─NodeIdInfo
│ │ │ ├─paxos
│ │ │ ├─peers
│ │ │ ├─peer_events
│ │ │ ├─range_xfers
│ │ │ ├─schema_columnfamilies
│ │ │ ├─schema_columns
│ │ │ ├─schema_keyspaces
│ │ │ └─schema_triggers
│ │ └─system_traces
│ │ ├─events
│ │ └─sessions
│ └─saved_caches
└─log
└─cassandra
system.log

(3) Cassandraの設定ファイルの変更

cassandraを使用して数日経つと、cassandraサーバーを起動した際に以下のエラーが出るようになった。古いdbファイルを削除できないらしい。


ERROR 11:07:05,889 Unable to delete \var\lib\cassandra\data\system\local\system-local-jb-66-Data.db (it will be removed on server restart; we'll also retry after GC)
ERROR 11:07:05,889 Unable to delete \var\lib\cassandra\data\system\local\system-local-jb-69-Data.db (it will be removed on server restart; we'll also retry after GC)
\var\lib\cassandra\dataあたりにアクセス権限(削除権)がないためなのかと、フォルダの権限をフルコントロールに変更したりと四苦八苦したが、そうではなく、Cassandraの設定ファイルを変更しないといけないことに気付いた。Linux環境での設定になっているので、Windows環境用に変更してやらなければならなかった。/var/lib/... のところが C:\var\lib\... になるように変更すればよかった。該当するファイルは、インストール先の cassandra\conf にある cassandra.yamllog4j-server.properties の2つのファイルだ。cassandra.yam では、以下のように3箇所を変更した。パスの記述をWindowsの表現に変更した。

data_file_directories:
- C:\var\lib\cassandra\data
commitlog_directory: C:\var\lib\cassandra\commitlog
saved_caches_directory: C:\var\lib\cassandra\saved_caches
同様に log4j-server.properties も以下のように変更した。

log4j.appender.R.File=C:\var\log\cassandra\system.log

(4) Cassandraデータのimport/export

Cassandraのデータのimport/exportは、csv形式ではなく、json形式のファイルで行われる。dbファイルは存在しているのでexportというより、ファイルのフォーマット変換といった感じだ。exportにはいろいろあるのかもしれないが、とりあえず、demo.usersというcolumn familyのディレクトリに移動してsstable2jsonを実行するのがよさそうだ。


> cd C:\var\lib\cassandra\data\demo\users
> sstable2json -f demo-users-20130927.json demo-users-jb-2-Data.db
ERROR 16:48:15,504 Exception encountered during startup
FSWriteError in C:\var\lib\cassandra\commitlog\CommitLog-3-1380354419683.log
at org.apache.cassandra.io.util.FileUtils.deleteWithConfirm(FileUtils.java:115)
at org.apache.cassandra.db.commitlog.CommitLogAllocator.recycleSegment(CommitLogAllocator.java:185)
at org.apache.cassandra.db.commitlog.CommitLog.recover(CommitLog.java:130)
at org.apache.cassandra.service.CassandraDaemon.setup(CassandraDaemon.java:300)
at org.apache.cassandra.service.CassandraDaemon.activate(CassandraDaemon.java:443)
at org.apache.cassandra.service.CassandraDaemon.main(CassandraDaemon.java:486)
Caused by: java.io.IOException: Failed to delete C:\var\lib\cassandra\commitlog\CommitLog-3-1380354419683.log
... 6 more
あれ、残念ながらエラーとなってsstable2jsonが機能してくれない。古いlogのdeleteやrenemeでエラーになっているようだ。保留としておこう。早く、Hectorの方に話を進めたい。(つづく)

CassandraとHectorを試してみる。(2)

Cassandra(カサンドラ)とHector(ヘクタ)をScalaで試してみておきたい。

(1) create/update/dropコマンド

先日、Cassandraコンソール(cassandra-cli)でget/set/delコマンドを確認したが、create/update/dropのコマンドもみておきたい。keyspaceはRDBのdatabase相当だ。keyspaceに対しては、create, update, dropの操作ができる。updateは、SQLではalternate相当だろうが、おそらく使うことはないだろう。helpでは以下のように記述されている。


create keyspace Add a keyspace to the cluster.
update keyspace Update the settings for a keyspace.
drop keyspace Remove a keyspace and its data.
column familyは、RDBのtable相当だ。column familyに対しては、create, update, drop, truncateの操作ができる。updateは、SQLではalternate相当。truncateはcolumn family内のデータのみ削除するのに対し、dropはデータと定義そのものも削除する。 truncateは、SQLではdelete相当だが、delはcolumnに対する操作とし、truncateを新たにcolumn familyに対する操作としたようだ。

create column family Add a column family to an existing keyspace.
update column family Update the settings for a column family.
drop column family Remove a column family and its data.
truncate Drop the data in a column family.

まず、keyspaceに対する操作を試してみる。cassandra, cassandra-cliをcmdから起動しておく。cassandra-cliでは引数で -hlocalhost -p9160 のようにホストとポートを指定できる。デフォルトのTest Clusterであること。keyspacesも確認しておこう。systemとsystem_tracesというkeyspacesがある。systemには、IndexInfo, NodeIdInfo, hints, schema_keyspacesのColumn Familyがある。system_tracesにはColumn Familyは1つもない。


> cassandra-cli -hlocalhost -p9160
Starting Cassandra Client
Connected to: "Test Cluster" on localhost/9160
Welcome to Cassandra CLI version 2.0.0

[default@unknown] describe cluster;
Cluster Information:
Name: Test Cluster
Snitch: org.apache.cassandra.locator.SimpleSnitch
Partitioner: org.apache.cassandra.dht.Murmur3Partitioner
Schema versions:
59adb24e-f3cd-3e02-97f0-5b395827453f: [127.0.0.1]

[default@unknown] show keyspaces;
Keyspace: system:
Replication Strategy: org.apache.cassandra.locator.LocalStrategy
Durable Writes: true
Column Families:
ColumnFamily: IndexInfo
ColumnFamily: NodeIdInfo
ColumnFamily: hints
ColumnFamily: schema_keyspaces
Keyspace: system_traces:
Replication Strategy: org.apache.cassandra.locator.SimpleStrategy
Durable Writes: true
Column Families:
[default@unknown]

(2) createコマンドの確認

"demo"という名前のkeyspaceを追加して、簡単な操作をチェックしてみたい。


[default@unknown] create keyspace demo;
a66605c1-5ae9-36f7-b1d0-052778aa15e8 // keyspaceが生成できた
[default@unknown] describe demo;
Keyspace: demo:
Replication Strategy: org.apache.cassandra.locator.NetworkTopologyStrategy
Durable Writes: true
Column Families:

[default@unknown] use demo; // useで接続先を変えるとプロンプトも変わる
Authenticated to keyspace: demo

[default@demo] create column family cf1;
6f76b870-0ec3-31ee-ad5f-fa6e7322ac1a // column familyも作成できた

[default@demo] set cf1['row1']['col1'] = 'aaaa';
org.apache.cassandra.serializers.MarshalException: cannot parse 'col1' as hex bytes
// あれ、エラーでsetできない。
[default@demo] set cf1[01][02] = 03;
Value inserted. // デフォルトでは16進数しか扱えない
Elapsed time: 11 msec(s).
[default@demo] set cf1[FF][0001] = FFFF;
Value inserted. // やはり、16進数しかダメ。使えない。
Elapsed time: 9.96 msec(s).
[default@demo]

column familyを安易に生成しても文字列を受け付けてくれないようだ。00からFFの16進表現しか受け付けない。整数もダメたっだ。またcassandra-cliのコンソールは日本語入力もできない。cassandraの面倒なところだ。ネット情報で学習すると、create column familyでは明示的にUTF8Typeを指定する必要があるそうだ。

まず、columnには、標準(Standard)とスーパー(Super)のタイプ(column_type)があり、またソートの際に利用されるcomparatorのタイプには{ AsciiType, BytesType, LexicalUUIDType, LongType, TimeUUIDType, UTF8Type }があるということだ。

標準カラムは、column family[row][col]のようにアクセスするが、スーパーカラムは1階層深くなり、column family[row][super-col][col]のようにアクセスできる。それ以上の階層はない。column_typeが省略されると標準カラムとして扱われる。

comparatorタイプは、デフォルトがBytesTypeのようだ。我々はUTF8Typeが扱えないと困る。だからほぼすべてのcolumn familyには、comparator=UTF8Typeが必要となる。まずcomparatorをAsciiTypeにしてみる。


[default@demo] create column family dummy with comparator=AsciiType;
[default@demo] set dummy['aa']['bb']='cc';
Elapsed time: 154 msec(s).
[default@demo] get dummy['aa'];
=> (name=bb, value=cc, timestamp=1379995227572000)
Returned 1 results.
Elapsed time: 418 msec(s).
文字列で扱えるようになった。今後はAsciiTypeでなく、UTF8Typeを明示しよう。ちなみにLongTypeは、整数ということではなく、BytesTypeで大きなデータを扱えるもののようだ。普段は使わないだろう。先ほどのcolumn familyの「dummy」をdescribeしてみると、Cells sorted byの値に「AsciiType」が見える。しかしまだ、Key Validation Class、Default column value validatorにBytesTypeが残っている。ネット情報によると、default_validation_class=UTF8Type and key_validation_class=UTF8Type を合わせて指定する必要があるとのことだ。

[default@demo] describe dummy;
ColumnFamily: dummy
Key Validation Class: org.apache.cassandra.db.marshal.BytesType
Default column value validator: org.apache.cassandra.db.marshal.BytesType
Cells sorted by: org.apache.cassandra.db.marshal.AsciiType
GC grace seconds: 864000
Compaction min/max thresholds: 4/32
Read repair chance: 0.1
DC Local Read repair chance: 0.0
Populate IO Cache on flush: false
Replicate on write: true
Caching: KEYS_ONLY
Default time to live: 0
Bloom Filter FP chance: default
Index interval: 128
Speculative Retry: NONE
Built indexes: []
Compaction Strategy: org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy
Compression Options:
sstable_compression: org.apache.cassandra.io.compress.LZ4Compressor

[default@demo]
[default@demo] create column family dummy2 with comparator=UTF8Type and
default_validation_class=UTF8Type and key_validation_class=UTF8Type;

[default@demo] set dummy2['aa']['bb']='cc';
Value inserted.
Elapsed time: 64 msec(s).

[default@demo] get dummy2['aa'];
=> (name=bb, value=cc, timestamp=1379996125542000)
Returned 1 results.
Elapsed time: 9.2 msec(s).

[default@demo] describe dummy2;
ColumnFamily: dummy2
Key Validation Class: org.apache.cassandra.db.marshal.UTF8Type
Default column value validator: org.apache.cassandra.db.marshal.UTF8Type
Cells sorted by: org.apache.cassandra.db.marshal.UTF8Type
GC grace seconds: 864000
Compaction min/max thresholds: 4/32
Read repair chance: 0.1
DC Local Read repair chance: 0.0
Populate IO Cache on flush: false
Replicate on write: true
Caching: KEYS_ONLY
Default time to live: 0
Bloom Filter FP chance: default
Index interval: 128
Speculative Retry: NONE
Built indexes: []
Compaction Strategy: org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy
Compression Options:
sstable_compression: org.apache.cassandra.io.compress.LZ4Compressor
[default@demo]

毎回create column familyごとに comparator=UTF8Type and default_validation_class=UTF8Type and key_validation_class=UTF8Type の属性を記述するのは面倒だ。cliが使いづらい。system上でこのデフォルト値を変更できるかもしれないが、まだ知見がない。

(3) update/dropコマンドの確認

後は残ったコマンドを確認しておこう。updateでcolumn familyの定義情報が変更できるようだが、「comparators do not match or are not compatible.」のエラーが出るときがある。AsciiTypeをUTF8Typeに変更することはできるが、その逆はcomparators do not match or are not compatible.」となった。そして、truncateでcolumn familyのデータが削除され、dropで定義も削除される。


[default@demo] update column family dummy with comparator=UTF8Type
// compatibleな属性(column)であれば、updateできる。
[default@demo] truncate dummy;
dummy truncated. // truncateできた

[default@demo] describe dummy;
ColumnFamily: dummy
Key Validation Class: org.apache.cassandra.db.marshal.BytesType
Default column value validator: org.apache.cassandra.db.marshal.BytesType
Cells sorted by: org.apache.cassandra.db.marshal.UTF8Type
...
[default@demo] drop column family dummy;
aff7429f-73f0-33e5-be3f-9d5799155aa1 // dropできた

[default@demo] describe dummy;
Sorry, no Keyspace nor ColumnFamily was found with name: dummy
[default@demo]

同様にkeyspaceについても、dropできることを確認した。keyspaceに対するupdateも用意されてはいるが、どのような属性(column)に対して変更の必要があるのかはっきりせず。使うことはないだろう。

[default@demo] drop keyspace demo;
43bda891-4673-324b-aea6-7f54d4cd1405 // dropできた

[default@unknown] describe demo; // dropした時点でプロンプトがunknownに変わる

Keyspace with name 'demo' wasn't found, to lookup ColumnFamily
with that name, please, authorize to one of the keyspaces first.
[default@unknown]

今日はとりあえず、ここまで。ScalaからHectorを利用してアクセスするまでは後日調査したい。(つづく)

CassandraとHectorを試してみる。(1)

Cassandra(カサンドラ)は、apacheが提供するNoSQLといわれるタイプの分散データベースだ。NoSQLは、Not only SQLSQLだけではないぞ)という意味で、RDBが得意な分野にはRDBを使ってRDBが得意でない部分では他の適したミドルウェアを使うということだ。Cassandraは、もともとFacebookで開発され、その後にApacheに移されたものらしい。Cassandraは、Javaで書かれ、APIも公開されている。どうもそのAPIが、コネクションプーリングやモニタリングなどの機能が貧弱なのか、それを補うためにHector(ヘクタ)が提供されているという経緯のようだ。

(1) Cassandraのインストール

Cassandraは http://cassandra.apache.org/ からダウンロードできる。私はapache-cassandra-2.0.0-bin.tar.gz を持ってきて、C:\cassandra\apache-cassandra-2.0.0 に展開した。以下の環境変数を設定する。


set JAVA_HOME = C:\Java\jdk1.7.0
set CASSANDRA_HOME = C:\cassandra\apache-cassandra-2.0.0
set CASSANDRA_CONF = %CASSANDRA_HOME%\conf
set CASSANDRA_MAIN = org.apache.cassandra.service.CassandraDaemon
set path = %path%;%CASSANDRA_HOME%\bin
cassandraサーバを起動してみる。cmdからcassandraを実行すればよいはず。

> cassandra
Starting Cassandra Server
Error occurred during initialization of VM
Could not reserve enough space for object heap
ヒープ領域が確保できないと言われる。%CASSANDRA_HOME%\binにあるcassandra.batを開いて、Java VMのサイズらしきところを小さめに変更した。

set JAVA_OPTS=-ea^
-javaagent:"%CASSANDRA_HOME%\lib\jamm-0.2.5.jar"^
-Xms128M^ // was Xms1G
-Xmx512M^ // was Xmx1G
-XX:+HeapDumpOnOutOfMemoryError^
-XX:+UseParNewGC^
-XX:+UseConcMarkSweepGC^
-XX:+CMSParallelRemarkEnabled^
-XX:SurvivorRatio=8^
-XX:MaxTenuringThreshold=1^
-XX:CMSInitiatingOccupancyFraction=75^
-XX:+UseCMSInitiatingOccupancyOnly^
-Dcom.sun.management.jmxremote.port=7199^
-Dcom.sun.management.jmxremote.ssl=false^
-Dcom.sun.management.jmxremote.authenticate=false^
-Dlog4j.configuration=log4j-server.properties^
-Dlog4j.defaultInitOverride=true
再度実行すると、一応サービスが起動されたようだ。

> cassandra
Starting Cassandra Server
INFO 12:18:56,572 Logging initialized
INFO 12:18:56,673 32bit JVM detected. It is recommended to run Cassandra on a 64bit JVM for better performance.
INFO 12:18:56,676 JVM vendor/version: Java HotSpot(TM) Client VM/1.7.0
INFO 12:18:56,676 Heap size: 129761280/518979584
(snip)
INFO 12:19:12,373 Starting listening for CQL clients on localhost/127.0.0.1:9042...
INFO 12:19:12,472 Binding thrift service to localhost/127.0.0.1:9160
INFO 12:19:12,621 Using TFramedTransport with a max frame size of 15728640 bytes.
INFO 12:19:12,665 Using synchronous/threadpool thrift server on localhost : 9160
INFO 12:19:12,667 Listening for thrift clients...

(2) cassandraコンソールで動作確認

もう1つ別にcmdを開いて、cassandraのコンソール(cassandra-cli)を起動してみる。ユーザーなどは指定していないが[default@unknown]というプロンプトが表示される。どんなコマンドがあるのか。help;と入力してみる。セミコロンが必要。exit;やquit;で抜けられる。


> cassandla-cli
Starting Cassandra Client
Connected to: "Test Cluster" on 127.0.0.1/9160
Welcome to Cassandra CLI version 2.0.0

Please consider using the more convenient cqlsh instead of CLI
CQL3 is fully backwards compatible with Thrift data; see http://www.datastax.com/dev/blog/thrift-to-cql3

Type 'help;' or '?' for help.
Type 'quit;' or 'exit;' to quit.

[default@unknown] help;
Getting around:
? Display this help.
help; Display this help.
help ; Display command-specific help.
exit; Exit this utility.
quit; Exit this utility.

Commands:
assume Apply client side validation.
connect Connect to a Cassandra node.
consistencylevel Sets consisteny level for the client to use.
count Count columns or super columns.
create column family Add a column family to an existing keyspace.
create keyspace Add a keyspace to the cluster.
del Delete a column, super column or row.
decr Decrements a counter column.
describe cluster Describe the cluster configuration.
describe Describe a keyspace and its column families or column family in current keyspace.
drop column family Remove a column family and its data.
drop keyspace Remove a keyspace and its data.
drop index Remove an existing index from specific column.
get Get rows and columns.
incr Increments a counter column.
list List rows in a column family.
set Set columns.
show api version Show the server API version.
show cluster name Show the cluster name.
show keyspaces Show all keyspaces and their column families.
show schema Show a cli script to create keyspaces and column families.
truncate Drop the data in a column family.
update column family Update the settings for a column family.
update keyspace Update the settings for a keyspace.
use Switch to a keyspace.

[default@unknown]

column family, keyspace, clusterなどという概念があることは分かる。RDBとはちょっと違う感じだが、cluster=テーブルスペース, keyspace=データベース, column family=テーブルくらいの感覚でいいのだろう。row, column, super columnという概念もある。column familyの中にrow.column(=key)が定義でき、値(=value)が代入できる。そうかEXCELファイルをイメージすればいいのかな。EXCELのような2次元のテーブルでrow,column,cellを意識すれば分かりやすい。column family=ワークシート、keyspace=EXCELファイル、cluster=ファイルをまとめたフォルダやバインダといった感じかな。いくつかコマンドを手探りしてみる。

[default@unknown] show api version;
19.37.0
[default@unknown] show cluster name;
Test Cluster
[default@unknown] show keyspaces;

WARNING: CQL3 tables are intentionally omitted from 'show keyspaces' output.
See https://issues.apache.org/jira/browse/CASSANDRA-4377 for details.

Keyspace: system:
Replication Strategy: org.apache.cassandra.locator.LocalStrategy
Durable Writes: true
Options: []
Column Families:
ColumnFamily: IndexInfo
ColumnFamily: NodeIdInfo
ColumnFamily: hints
ColumnFamily: schema_keyspaces
Replication Strategy: org.apache.cassandra.locator.SimpleStrategy

Keyspace: system_traces:
Replication Strategy: org.apache.cassandra.locator.SimpleStrategy
Durable Writes: true
Options: [replication_factor:1]
Column Families:

[default@unknown] use system; // systemへ移動して
Authenticated to keyspace: system

[default@unknown] show schema; // 定義情報を参照
(snip)
[default@unknown] describe; // systemの詳細
(snip)
[default@unknown] describe IndexInfo; // system.IndexInfoの詳細
ColumnFamily: IndexInfo
"indexes that have been completed"
Key Validation Class: org.apache.cassandra.db.marshal.UTF8Type
Default column value validator: org.apache.cassandra.db.marshal.BytesType
Cells sorted by: org.apache.cassandra.db.marshal.UTF8Type
GC grace seconds: 0
Compaction min/max thresholds: 4/32
Read repair chance: 0.0
DC Local Read repair chance: 0.0
Populate IO Cache on flush: false
Replicate on write: true
Caching: KEYS_ONLY
Default time to live: 0
Bloom Filter FP chance: 0.01
Index interval: 128
Speculative Retry: NONE
Built indexes: []
Compaction Strategy: org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy
Compression Options:
sstable_compression: org.apache.cassandra.io.compress.LZ4Compressor

デフォルトで「Test Cluster」というclusterが利用できるようだ。明示的にconnectしなくても、cassandra-cliで起動すると、デフォルトでTest Clusterに接続される。Connected to: "Test Cluster" on 127.0.0.1/9160のメッセージが出ている。Test Clusterには、systemとsystem_tracesという2つのkeyspaceが作成されている。keyspaceは、database相当の概念だ。clusterはkeyspaceの集合を扱うので、Oracleなどのtablespace相当と捉えておくことにする。keyspaceはuseコマンドで移動できる。systemというkeyspaceには、IndexInfo, NodeIdInfo, hints, schema_keyspacesという4つのColumnFamilyがある。これらはtable相当だろう。
たとえば、systemというkeyspaceに移動して、IndexInfoというColumnFamilyの定義を覗いてみる。describe IndexInfoの結果をみると、IndexInfoはコンパイルされたインデックスの格納場所のようだ。カラムには例えば、Default time to liveといった長めの名前のものがあり、初期値=0 が設定されていることが分かる。

(3) set/get/delコマンド

set/get/delのコマンドを試してみたい。systemのkeyspaceを触わると問題があるかもしれないが、とりあえずsystemのIndexInfoを直接触ってみる。'test'というrowでアクセスしてみる。


> get IndexInfo['test']; // 'test'は存在していない。
Returned 0 results. // エラーにはならず、0件となる。
Elapsed time: 84 msec(s).

> set IndexInfo['test']['Default time to live'] = 23; // 整数の代入
Value inserted.
Elapsed time: 388 msec(s).

> set IndexInfo['test']['Replicate on write'] = 02; // 16進数(hex bytes)の代入
Value inserted.
Elapsed time: 114 msec(s).

> get IndexInfo['test']; // 'test'を取得
=> (name=Default time to live, value=23, timestamp=1379918657809000)
=> (name=Replicate on write, value=02, timestamp=1379918591765000)
Returned 2 results.

> del IndexInfo['test']; // 'test'を削除
row removed.
Elapsed time: 63 msec(s).

> get IndexInfo['test']; // 削除後に'test'を再取得
Returned 0 results.
Elapsed time: 84 msec(s).

今日はcassandraをコンソールで確認するまでしかできず、タイトルのScalaにもHectorにも辿りつけなった。(つづく)