[Rails][NoSQL]Cassandra0.7系を試してみる その2

RailsでCassandra0.7系を試してみる - Cassandra-cliを利用する



RailsからCassandraを操作する前にCassandra-cli(Cassandraのクライアント)を利用してどんなことができそうか試してみます
ヘルプ見るのだるいので簡易リファレンスになるようにメモります


Cassandraサーバの起動


フロントエンドモードで起動させます


cassandra -f

Cassandra-cliの起動


cassandra-cli -host localhost

Cassandra Keyspace


KeyspaceとはRDBにおけるデータベーススキーマのことです


Keyspaceの作成


create keyspace [Keyspace名];

なお、Keyspace名に-の使用はできないようです


Keyspaceの削除


drop keyspace [Keyspace名];

Keyspaceの一覧表示


show keyspaces;

MySQL等と同じです、MySQLの場合はshow databases;です


Keyspaceの構造表示


describe keyspace [Keyspace名];

利用するKeyspaceの指定


use [Keyspace名];

Lesson 1


  • cassandra-test1という名前のKeyspaceは作成できるか
  • namakesugiというKeyspaceを作成せよ
  • namakesugiというKeyspaceを削除せよ

Cassandra Column Families


Column FamiliesはRDBにおけるテーブルのようなものです
1つのKeyspaceに複数のテーブルを作成することが出来ます


Column Familyを作成する


CassandraではColumn Family(RDBにおけるテーブル)をcfと省略して記述します


create column family [Family名] {with xxx = yyy and zzz = aaa ...};

後で解説しますが、KEYとValue(JSON形式等)で保存するだけであれば後ろのオプション({}の部分)は不要です
※あったほうがいい場合もあるようですが


Column Familyを削除する


drop column family [Family名];

Column Familyの構造を変更する


update column famil [Family名] {options};

Column Familyの中身を空っぽにする


truncate [Family名];

MySQL等と同じです


Lesson 2


  • test1というKeyspaceを作成しなさい
  • test1を利用するよう宣言しなさい
  • test1にColumn Familyとしてposxxxを作成しなさい
  • 作成したposxxxを削除しなさい

Column Familyに値をセットする


いよいよ値をセットしていきます


データ構造(meta_data)を定義する


値を設定する前にデータ構造が定義されたColumn Familyを作成します


create column family Balls with column_type=Standard
and comparator=UTF8Type
and column_metadata=[
{column_name:x, validation_class:IntegerType, index_type:KEYS},
{column_name:y, validation_class:IntegerType, index_type:KEYS},
{column_name:r, validation_class:IntegerType, index_type:KEYS},
{column_name:ballname, validation_class:UTF8Type}
];

Cassandra Column Familyに値をセットする


値のセットは以下のように行います
with ttl=[INT(sec)]の部分は利用しませんので無視してください


set [Family名]['key']['column_name']=value {with ttl = [INT(sec)]}

とりあえず以下のように3件ほど登録してみましょう


set Balls['1']['x'] = 10;
set Balls['1']['y'] = 10;
set Balls['1']['r'] = 3;
set Balls['1']['ballname'] = 'redball';
set Balls['2']['x'] = 3;
set Balls['2']['y'] = 8;
set Balls['2']['r'] = 6;
set Balls['2']['ballname'] = 'blueball';
set Balls['3']['x'] = 20;
set Balls['3']['y'] = 0;
set Balls['3']['r'] = 30;
set Balls['3']['ballname'] = 'greenball';

Familyに登録されているデータの一覧を取得する


list [Family名] {limit N}

上記のBalls Familyを例に取ると以下のようになります


[サンプル]
list Balls;
[結果]
Using default limit of 100
-------------------
RowKey: 3
=> (column=ballname, value=greenball, timestamp=1296740168134000)
=> (column=r, value=30, timestamp=1296740166547000)
=> (column=x, value=20, timestamp=1296740166533000)
=> (column=y, value=0, timestamp=1296740166540000)
... 略 ...

3 Rows Returned.

RowKeyの位置を指定してリストを取得する


list [Family名][key:];

[サンプル]
list Balls['2':];
[結果]
-------------------
RowKey: 2
... 略 ...
-------------------
RowKey: 1
... 略 ...
2 Rows Returned.

ここの細かい仕組みはまた今度ー


指定したKeyの値(Value)を取得する


get [Family名]['Key'];

[サンプル]
get Balls['2'];
[結果]
=> (column=ballname, value=blueball, timestamp=1296740166526000)
=> (column=r, value=6, timestamp=1296740166516000)
=> (column=x, value=3, timestamp=1296740166501000)
=> (column=y, value=8, timestamp=1296740166508000)
Returned 4 results.

指定したKeyの特定のColumn名の値を取得する


get [Family名]['Key']['Column名'];

[サンプル]
get Balls['2']['ballname'];
[結果]
=> (column=ballname, value=blueball, timestamp=1296740166526000)

条件に一致するデータを取得する


SQLのwhereです
若干癖があるというかKVSでは当たり前の動きをします


get [Family名] where [Column名]=検索値

=の箇所には=, >, >=, <, <=が利用可能です
※若干癖があります


[サンプル]
get Balls where r=3;
[結果]
-------------------
RowKey: 1
=> (column=ballname, value=redball, timestamp=1296740166493000)
=> (column=r, value=3, timestamp=1296740166479000)
=> (column=x, value=10, timestamp=1296739919512000)
=> (column=y, value=10, timestamp=1296740166467000)

1 Row Returned.

複数条件指定


andつけるだけです


get [Family名] wehre [Column名1]=検索値 and [Column名2]=検索値;

[サンプル]
get Balls where x=3 and y>4;
[結果]
-------------------
RowKey: 2
=> (column=ballname, value=blueball, timestamp=1296740166526000)
=> (column=r, value=6, timestamp=1296740166516000)
=> (column=x, value=3, timestamp=1296740166501000)
=> (column=y, value=8, timestamp=1296740166508000)

1 Row Returned.

なお、以下の方法だとエラーが出ます


[サンプル]
get Balls where y >= 1 and x < 10;
[結果]
No indexed columns present in index clause with operator EQ

ちなみにandを使わない場合でも=(EQ)以外を利用すると上記のように表示されます


もうひとつありまして、以下の場合も同様のエラーがでます


get Balls where ballname='redball';

理由はうえーーのほうのデータ構造のところを見てみると違いがわかるかと思います


型変換をして返す


get [Family名]['Key']['Column名'] as [Type]
Typeは次のものが使用可能 ... IntegerType, LongType, UTF8Type, ASCIIType, TimeUUIDType, LexicalUUIDType

[サンプル]
get Balls['1']['ballname'] as IntegerType;
[結果]
=> (column=ballname, value=32199629166701676, timestamp=1296740166493000)

valueのところに注目してください


眠くなったので続きはまた今度!


スポンサーサイト

[Rails][NoSQL]Cassandra0.7系を試してみる その1

RailsでCassandra0.7系を試してみる - 環境構築(Windows7)


とりあえずゴールは作りながら考えるということでメモブログらしく
適当にメモ


ローカル環境


OS : Windows 7 HomePremium 64bit
MEM : 4GB
JAVA : java version "1.6.0_23"
Java(TM) SE Runtime Environment (build 1.6.0_23-b05)
Java HotSpot(TM) Client VM (build 19.0-b09, mixed mode, sharing)
Cassandraのバージョン : 0.7.0

Cassandra 0.7.0のインストール


インストールといってもダウンロードして設置するだけです


  1. Cassandraのページへ移動します
  2. 右にダウンロードリンクがあるのでダウンロードしてきます
  3. tar.gz形式のファイルとなりますので、適切な解凍ソフトで解凍します
  4. 出来たファイルを任意の場所へ設置します

※私はC:\tools\apache-cassandra-0.7.0という感じで設置しました
以下このディレクトリにインストールしたものとして記述していきます


Cassandraの設定


初期設定はUnixライクなOS用の設定となっていますので、若干設定を変更する必要があります


cassandra.yamlの変更


以下の箇所を変更します


[66] data_file_directories:
[67] - C:/tools/apache-cassandra-0.7.0/datadir/data
... 略 ...
[70] commitlog_directory: C:/tools/apache-cassandra-0.7.0/datadir/commitlog
... 略 ...
[73] saved_caches_directory: C:/tools/apache-cassandra-0.7.0/datadir/saved_caches

上記はCassandraが作成するデータファイルの設置場所となります
なお、datadirは存在しませんので作成しておいてください
※私は一応data,commitlog,saved_cachedというディレクトリもdatadir以下に作成しておきました


log4j-server.properties


こっちはフロントエンドモード(cassandra -f)で動かすだけであれば不要です


[35] #log4j.appender.R.File=/var/log/cassandra/system.log
[36] log4j.appender.R.File=C:/tools/apache-cassandra-0.7.0/log/system.log

35行目をコメントアウトし、36行目に上記のように設定を追加しました


環境変数の登録


CASSANDRA_HOMEという環境変数名で[C:\tools\apache-cassandra-0.7.0]としていします


PATHに[%CASSANDRA_HOME%\bin]と登録します


起動用のbatファイル内ではJAVA_HOMEが利用されていますので
JAVA_HOMEという環境変数名でJAVAのインストールディレクトリが指定されていることを確認します
※私は[C:\Program Files (x86)\Java\jdk1.6.0_23]です


これで一応準備完了です


Cassandra0.7系の起動


コマンドプロンプトを起動させ、以下を実行します


>cassandra -f

以下のように表示されれば起動成功です


Starting Cassandra Server
INFO 00:17:14,183 Heap size: 1070399488/1070399488
INFO 00:17:14,203 JNA not found. Native methods will be disabled.
INFO 00:17:14,333 Loading settings from file:/C:/tools/apache-cassandra-0.7.0/conf/cassandra.yaml
... 略 ...
INFO 00:17:15,723 Binding thrift service to localhost/127.0.0.1:9160
INFO 00:17:15,733 Using TFramedTransport with a max frame size of 15728640 bytes.

なお、指定されたパスが見つかりませんとか言われる場合はJAVA_HOMEなどの値を見直してみましょう
※私はJAVA_HOMEに[;]が入っていたので嵌りました


Cassandra0.7系とお話しする


0.6系と若干異なりますので注意が必要です
cassandra-cli.batというのがCASSANDRA_HOMEのbin以下に存在します


>cassandra-cli -host localhost

接続に成功すると以下のように表示されます
なお、-port [cassandra-port]としていすることで9160ポート以外で動かした場合でも動作させることが出来ます


Starting Cassandra Client
Connected to: "Test Cluster" on localhost/9160
Welcome to cassandra CLI.

Type 'help;' or '?' for help. Type 'quit;' or 'exit;' to quit.
[default@unknown]

ここからCassandraとお話をしていくのですが、コマンドの終了は[;]を入力する必要があります


[default@unknown] create keyspace Keyspace1;
ce97d182-2ee1-11e0-b9cc-e700f669bcfc
[default@unknown] use Keyspace1;
Authenticated to keyspace: Keyspace1
[default@Keyspace1] create column family UserAuth with comparator=UTF8Type and default_validation_class=UTF8Type;
4f6787a4-2ee8-11e0-b9cc-e700f669bcfc
[default@Keyspace1] set UserAuth['1']['login_code'] = 'namakesugi';
Value inserted.
[default@Keyspace1] set UserAuth['1']['password'] = 'namaeksugipass'
Value inserted.
[default@Keyspace1] get UserAuth['1'];
=> (column=login_code, value=namakesugi, timestamp=1296663716569000)
=> (column=password, value=namaeksugipass, timestamp=1296663734764000)
Returned 2 results.

動作しましたね
なお、keyspaceとはRDBにおけるデータベース(スキーマ)のことです


cassandra-cliの簡単なリファレンス


  • keyspaceを作りたい ... create keyspace [Keyspace名]
  • keyspaceの一覧を取得したい ... show keyspaces
  • keyspaceを削除したい ... drop [Keyspace名]
  • 使うkeyspaceを指定したい ... use [Keyspace名]
  • Columnを作りたい ... create column family [Column名]
  • Columnにデータを登録したい ... set [Column名]['key'] = [Value]
    ※valueにはtype(型)を指定することも出来ます
  • 使用可能なtype ... bytes, integer, long, lexicaluuid, timeuuid, utf8, ascii
  • 有効期限の指定 ... set [Column名]['key'] = [Value] with ttl = 30;

とここまで適当に書きましたが、詳しいリファレンスは次回以降やります!

PHP5.3系でOpenPNEのPluginのインストールに失敗する

PHP5.3系でOpenPNEのPluginのインストールに失敗する


なぜPHP5.3系でOpenPNEのPluginのインストールに失敗するのかを追ってみた
途中まで追ったので覚え書きを残す


PHPの状態(全部remiよりyumでインストール)


# yum list installed | grep php
php.x86_64 5.3.5-1.el5.remi.1 installed
php-cli.x86_64 5.3.5-1.el5.remi.1 installed
php-common.x86_64 5.3.5-1.el5.remi.1 installed
php-gd.x86_64 5.3.5-1.el5.remi.1 installed
php-imap.x86_64 5.3.5-1.el5.remi.1 installed
php-mbstring.x86_64 5.3.5-1.el5.remi.1 installed
php-mcrypt.x86_64 5.3.5-1.el5.remi.1 installed
php-mysql.x86_64 5.3.5-1.el5.remi.1 installed
php-pdo.x86_64 5.3.5-1.el5.remi.1 installed
php-pear.noarch 1:1.9.1-6.el5.remi installed
php-pecl-apc.x86_64 3.1.7-1.el5.remi installed
php-xml.x86_64 5.3.5-1.el5.remi.1 installed
# pear list
Installed packages, channel pear.php.net:
=========================================
Package Version State
Archive_Tar 1.3.7 stable
Console_Getopt 1.3.0 stable
PEAR 1.9.1 stable
Structures_Graph 1.0.4 stable
XML_RPC 1.5.4 stable
XML_Util 1.2.1 stable

Pluginのインストーラーの場所


  • symfony openpne:installで呼ばれるのは
    OpenPNE/lib/task/openpneInstallTask.class.php
  • Pluginインストール時に呼ばれるのは
    OpenPNE/lib/task/opPluginInstallTask.class.php
  • class opPluginInstallTask extends sfPluginInstallTaskであり、スーパークラスのexecuteが呼ばれる
    これはOpenPNE/lib/vendor/symfony/lib/task/plugin/sfPluginInstallTask.class.phpにある
  • function execute内の
    $this->getPluginManager()->installPlugin($arguments['name'], $options);が呼ばれる
    これはOpenPNE/lib/vendor/symfony/lib/plugin/sfPluginManager.class.phpにある
  • 229行目以降に注目すると以下のようになっている
        $installer = new PEAR_Installer($this);
    $installer->setOptions(array('upgrade' => true));
    $packages = array($pluginPackage);
    $installer->sortPackagesForInstall($packages);
    PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
    $err = $installer->setDownloadedPackages($packages);
    if (PEAR::isError($err))
    {
    PEAR::staticPopErrorHandling();
    throw new sfPluginException($err->getMessage());
    }

    $info = $installer->install($pluginPackage, array('upgrade' => true));
    PEAR::staticPopErrorHandling();
    if (PEAR::isError($info))
    {
    throw new sfPluginException(sprintf('Installation of "%s" plugin failed: %s', $plugin, $info->getMessage())); <==== ここでエラーがでている
    }
  • エラーが出力されているのはPEAR_InstallerであるのでPEARを見に行く
    場所は/usr/share/pear/PEAR/Installer.php
  • Installer.phpの1129行目のfunction installを見ると以下の記述を発見(1148行目から)
    if (realpath($descfile) != realpath($pkgfile)) {
    $tar = new Archive_Tar($pkgfile);
    if (!$tar->extract($tmpdir)) {
    return $this->raiseError("unable to unpack $pkgfile");
    }
    }

$tar->extractがfalseなのでunable to unpackと出るわけですね
ここだけ見るとPEAR::Archive_Tarが悪そうに見えますが、Download周りが怪しい感じか? => 悪い子でした
ということでInstallerが起動するときに利用しているPluginリストを取得している箇所を探したところ
以下に記述がされていました


OpenPNE/lib/task/opPluginSyncTask.class.phpの
protected function getPluginList()内で以下URLへリクエストを送っていました
http://plugins.openpne.jp/packages/3.4.9.2.yml


ここまでで飽きて来たので一先ず終了
Symfonyとかよくわかりません(´・ω・`)


解決方法 - Twitterより


解決方法を書いてくれている人がいました
コカテイ様(psyjack_net)


OpenPNE/lib/vendor/PEAR/Archive/Tar.phpの差し替えを行うことで動作するようになるらしいです
私の環境のようにPEARが既に入っているならば以下のように入れ替えれば動作します


cp /usr/share/pear/Archive/Tar.php OpenPNE/lib/vendor/PEAR/Archive/Tar.php

なお古いバージョンのTar.phpでエラーが出る箇所は特定できたのですが、
細かいところまではわかりませんでした
以下エラーが出る場所(というかfalseが返る=結果的にエラーとなる場所です)


function _extractList 1538行目以下
} else {
if (($v_dest_file = @fopen($v_header['filename'], "wb")) == 0)


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。