Javaのお勉強 その1 HelloWorld

cassandraの勉強をしているが、Javaの基礎知識が無いと
つらすぎるので、基礎から勉強しなおしてみる。

まずは、お約束のHelloWorldから。
コードはこちら。

satoshi@debian:~/git/sample-codes/java/helloworld$ ls
HelloWorld.java
satoshi@debian:~/git/sample-codes/java/helloworld$ javac HelloWorld.java 
satoshi@debian:~/git/sample-codes/java/helloworld$ ls
HelloWorld.class  HelloWorld.java
satoshi@debian:~/git/sample-codes/java/helloworld$ java HelloWorld
Hello, Java.

昔少しだけ勉強した記憶が少しだけ蘇りました。
今回は超簡単なコードだけど、
これからさらに勉強をすすめていこうと思います。

Yoono Firefox addon について

Yoono Firefox addonがいけてる。
Yoono - Twitter, Facebook, LinkedIn, MySpace, Flickr, AIM, MSN, GTalk...

メッセンジャーやソーシャル系のサービスアカウントの一元管理や
更新アラート機能を一括でできるので、
いちいちサイトにいって、ログインして、更新チェックして、、、
ということをしなくてもよくなる優れもの。


自分は、Facebook, twitter, flickr, Yahoo! Messenger, Google Talk
のアカウントを持っているので登録してみました。
OAuthでログインできるみたい。
twitterやFacebookは複数アカウントの切り替えもできそう
(自分はもっていないので確認できないけど)

あと、twitterはフォロワーのグループ管理ができるっぽい。
(会社の人、大学時代の友人、芸能人、など自分の好きなように。)

内部的にはFlashで動いているっぽい。
これから使いこなしてみようと思います。

firefox on debian lenny で flash ページを表示すると落ちる対策

firefox on debian lenny で flash ページを表示すると落ちるので
結局flashをOFFにしてごまかしていたけど、
Google Analyticsを見れなかったりして不便なので、
重い腰を上げて対策について再度調査してみました。

Ubuntu のfirefoxへ、adobeのflashプラグインの導入 その1(ファイル配置編)
まずは、すでにインストールしているFlashファイルを
削除して、あたらしくadobeのページからダウンロードしたファイルを
~/.mozilla/plugins/
以下に設置して、再起動。

なおったーーー、、、と思ったけど駄目。
Yahoo! メールでかなりの高確率で落ちてしまう。
Yahoo! はFlash広告が多いので、Yahoo!を徘徊して
大丈夫かどうかで、安定したかどうかを判定してます。

で、次に試したのが、
Ubuntu 9.10 の uim で Firefox がクラッシュする
を参考に、Firefoxの起動オプションを変更してみました。
$ cat ~/Desktop/firefox.desktop
[Desktop Entry]
Version=1.0
Encoding=UTF-8
Name=Firefox
Type=Application
Terminal=false
Name[en_US]=Firefox
Name[ja]=Firefox
Exec=env GTK_IM_MODULE=xim /usr/bin/firefox %u
Icon=/usr/lib/firefox/icons/mozicon50.xpm
StartupNotify=true
GenericName[ja_JP]=

Execの部分に、上記の用に環境変数を設定しました。

これを試したところ、Yahoo!を徘徊しても1回も落ちなくなって、
youtubeやGoogle Analyticsも見れるようになりました。

よかったよかった。

flickr の画像URL仕様についてまとめ(Unavailable画像)

ちょっと調べれば日本語でもまとまっている情報ですが、
自分のために備忘録として書いておきます。

Flickrの画像URLを決定するには、以下の値が必要になります。
以下の値はAPIのレスポンスに含まれます。
  • farm ID
    • 画像が保存されているファームのID(数値)
  • server ID
    • 画像が保存されているサーバのID(数値)
  • 画像ID
    • 画像に対して付与されるID(数値)
  • Secret
    • farm ID, server ID, 画像ID から決まるHash値?(数値)
    • 画像URLを予測できないようにしてクロールされないようにするため?
  • Size -> サイズに関する仕様は古いです。画像サイズに関する仕様が若干追加されていたので、別エントリーにまとめました
    • m, s, t, bの4つのどれか
      • m = medium size (オリジナルと縦横比を保持して長い辺を240pxに)
      • s = small size (縦75px横75pxの正方形。中心部分をトリミング?)
      • t = tiny(?) size (オリジナルと縦横比を保持して長い辺を100pxに)
      • b = original size (オリジナルサイズ?上限はありそうだが。) 
これらの値を元に、以下のようなURLになります。
http://farm{farm}.static.flickr.com/{server}/{id}_{secret}_{size}.jpg 
例えば、
FarmID = 5
ServerID = 4055
ImageID = 4395133916
Secret = 943f53af87
Size = m
の画像URLは
http://farm5.static.flickr.com/4055/4395133916_943f53af87_m.jpg
となります。

ここで、
http://static.flickr.com/4055/4395133916_943f53af87_m.jpg
とfarm部分を省略したURLにすると、適切なfarmに302リダイレクトしてくれる。

farmやserver, image id, secretがすべて正しくても、
画像ownerが削除したり、公開設定を変更して非公開になった場合は、
エラー画像URLに301リダイレクトされる。エラー画像のURLは、
http://l.yimg.com/g/images/photo_unavailable_s.gif
で、404は返らずに"200 ok"が返ってくる
sの部分は、通常画像同様、サイズを表すパラメータ(m,s,t)が用意されている。
bは存在しない。photo_unavailable.gifにすれば通常サイズのものを取得できる

参考:
http://webservice.kabufuru.net/flickr/photosUrl.php

なお、ここにある情報は2010/03現在のものです。

Evernote API の調査

EvernoteはAPIが豊富だ、という話を聞いたので、調査してみた。

まずは、APIの利用申請が必要らしい。
https://www.evernote.com/about/developer/api/
英語のページだけど、入力する内容も少ないので、まあなんとかなる。

申請するとすぐにconsumer key, consumer secretが
Evernoteアカウントに登録したメールアドレスに送られてくる。

API仕様書は、
https://www.evernote.com/about/developer/api/evernote-api.htm
で確認できます。

API開発のためには、sandbox環境にアカウントを作らないといけないようで、
https://sandbox.evernote.com/Login.action
こちらからできます。

あとは、
http://www.evernote.com/about/developer/api/
にある、Zipをダウンロードして、そこに含まれるサンプルコードを
動かして、、、っておもったら、全然動かないでござる。。。

心が折れたので、ここでやめて、ふて寝する。

$ php EDAMTest.php tanarky sandboxアカウントパスワード
Is my EDAM protocol version up to date?  1

Fatal error: Uncaught exception 'edam_error_EDAMUserException' in /home/satoshi/src/evernote-api-1.14/lib/php/packages/UserStore/UserStore.php:706
Stack trace:
#0 /home/satoshi/src/evernote-api-1.14/lib/php/packages/UserStore/UserStore.php(128): edam_userstore_UserStore_authenticate_result->read(Object(TBinaryProtocol))
#1 /home/satoshi/src/evernote-api-1.14/lib/php/packages/UserStore/UserStore.php(86): UserStoreClient->recv_authenticate()
#2 /home/satoshi/src/evernote-api-1.14/sample/php/EDAMTest/EDAMTest.php(46): UserStoreClient->authenticate('tanarky', 'satoshi', 'en-edamtest', '0123456789abcde...')
#3 {main}
  thrown in /home/satoshi/src/evernote-api-1.14/lib/php/packages/UserStore/UserStore.php on line 706


参考:
Evernote API

EvernoteでRemember everythingしてみる

Evernoteっていうサイトが流行ってるみたいなので調査してみた。

日本語サイト
本家英語サイト

結局は、インターネット上の情報の中で、自分が気に入った情報を
どんどんクリップできるサービスみたい。

FIrefox addonもすでにあります。
https://addons.mozilla.org/ja/firefox/addon/8381

でも、Tumblrと何が違うんだろう。
同じ考察をしている人は結構いるようで。
http://www.shinyasuzuki.com/websites/evernote%E3%81%A8tumblr%E3%81%AE%E4%BD%BF%E3%81%84%E5%88%86%E3%81%91/

すみわけはサイトの趣旨を理解してから後で考えるとして、
APIは充実しているみたいなんで、今度調査してみる。

cassandraに挑戦 その13 ant gen-thrift-javaを実行してはまった

いろいろ調べていて、
$ ant gen-thrift-java
を実行してから、普通にantが通らなくなってしまったのでメモ。

satoshi@debian:~/cassandra/0.6.0$ ant gen-thrift-java
Buildfile: build.xml

gen-thrift-java:
     [echo] Generating Thrift Java code from /home/satoshi/cassandra/0.6.0/interface/cassandra.thrift ....

BUILD SUCCESSFUL
Total time: 1 second

ant gen-thrift-java自体はうまくいきます。
問題はこのあと、antを実行すると
ジェネレートされた部分のコードが一部よろしくないみたいで、
(一部抜粋)
    [javac] /home/satoshi/cassandra/0.6.0/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java:13280: 互換性のない型
    [javac] 検出値  : int
    [javac] 期待値  : org.apache.cassandra.thrift.ConsistencyLevel
    [javac]       this.consistency_level = 0;
    [javac]                                ^
    [javac] /home/satoshi/cassandra/0.6.0/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java:14380: 互換性のない型
    [javac] 検出値  : int
    [javac] 期待値  : org.apache.cassandra.thrift.ConsistencyLevel
    [javac]       this.consistency_level = 0;
    [javac]                                ^
(一部抜粋終わり)
といったエラーがでます。

正しくは、1や0のように数値じゃなく、
!         this.consistency_level = ConsistencyLevel.ONE;
としないといけないので、とりあえず、手動で直しました。
patchはここに置きました無保証

あー、つかれた。


cassandraに挑戦 その12 C++でクライアントを作ってみる

cassandraはthrift経由でデータ操作できるので、
せっかくだから、いろいろな言語でクライアントを作ってみるでござる

手順は以下のとおり。
satoshi@debian:~/cassandra/0.6.0$ pwd
/home/satoshi/cassandra/0.6.0
satoshi@debian:~/cassandra/0.6.0$ which thrift
/usr/local/bin/thrift
satoshi@debian:~/cassandra/0.6.0$ /usr/local/bin/thrift --gen cpp interface/cassandra.thrift
satoshi@debian:~/cassandra/0.6.0$ ll gen-cpp
合計 388
-rw-r--r-- 1 satoshi satoshi 226714 2010-03-21 13:06 Cassandra.cpp
-rw-r--r-- 1 satoshi satoshi  77574 2010-03-21 13:06 Cassandra.h
-rw-r--r-- 1 satoshi satoshi   5739 2010-03-21 13:06 Cassandra_server.skeleton.cpp
-rw-r--r-- 1 satoshi satoshi    333 2010-03-21 13:06 cassandra_constants.cpp
-rw-r--r-- 1 satoshi satoshi    424 2010-03-21 13:06 cassandra_constants.h
-rw-r--r-- 1 satoshi satoshi  42822 2010-03-21 13:06 cassandra_types.cpp
-rw-r--r-- 1 satoshi satoshi  19483 2010-03-21 13:06 cassandra_types.h

これでコードがジェネレートされたので、
これを元にクライアントコードを準備。

、、、の前に、ldconfigで/usr/local/libにpathを通しておく。
すでに通っていたら必要無し。
$ cat /etc/ld.so.conf.d/additional_path.conf
/usr/local/lib
$  sudo /sbin/ldconfig

これでOK
クライアントコードは、こちらのsimple_client.cpp
このコードを、gen-cpp以下にコピーして、
以下のコマンドでビルド可能

$ g++ -o simple_client -Wall -g -I../gen-cpp/. \
  -I/usr/local/include/thrift -L/usr/local/lib    \
  -lstdc++ -lthrift simple_client.cpp \
  ../gen-cpp/cassandra_constants.cpp
  ../gen-cpp/cassandra_types.cpp
  ../gen-cpp/Cassandra.cpp
$ 

ビルド完了!
データは、以下のものが入っている。
cassandra> get Keyspace1.Standard1['book1']
=> (column=7469746c65, value=dragon ball, timestamp=1267713708356)
=> (column=7072696365, value=500yen, timestamp=1267713720682)
Returned 2 results.

コードを実行してみる。
$ ./simple_client
Column name retrieved is: title
Value in column retrieved is: dragon ball
$ 

というわけで、データ取得できました。
あとはAPI仕様をみていけば簡単にデータを扱えそうです。

検索エンジンApache Luceneをインストールしてサンプルを動かしてみる

Apache Lucene を Debian lenny にインストールしました。
このブログを書いている時点でバージョンは3.0.1でした。

まずはダウンロード
$ mkdir ~/lucene
$ cd ~/lucene
$ wget http://ftp.riken.jp/net/apache/lucene/java/lucene-3.0.1-src.tar.gz

解凍してビルド
$ tar xvzf lucene-3.0.1-src.tar.gz
$ mv lucene-3.0.1 3.0.1
$ cd 3.0.1
$ pwd
/home/satoshi/lucene/3.0.1
$ ant
(略)

BUILD Successful

動作確認のためのコードをビルドする
このコードはtar.gzに同梱されている。
$ ant war-demo

検索インデックスを作成する。データはsrc/以下のファイルから作る。
これでソースコード検索ができるようになる。
ファイル数は817ファイル、サイズは合計7.5M
$ java -cp build/lucene-core-3.0.1-dev.jar:build/lucene-demos-3.0.1-dev.jar org.apache.lucene.demo.IndexFiles src
(略)
Optimizing...
9376 total milliseconds
$ find src/ |wc -l
817
$ du -k -s src/
7564    src/

検索してみる
$ java -cp build/lucene-core-3.0.1-dev.jar:build/lucene-demos-3.0.1-dev.jar org.apache.lucene.demo.SearchFiles
Enter query:
test
Searching for: test
189 total matching documents
1. src/test/org/apache/lucene/util/ArrayUtilTest.java
2. src/test/org/apache/lucene/index/TestIndexWriterLockRelease.java
3. src/site/src/documentation/skins/common/skinconf.xsl
4. src/test/org/apache/lucene/analysis/TestCharArraySet.java
5. src/site/src/documentation/skins/lucene/skinconf.xsl
6. src/test/org/apache/lucene/analysis/TestStopAnalyzer.java
7. src/test/org/apache/lucene/util/LuceneTestCase.java
8. src/test/org/apache/lucene/util/LocalizedTestCase.java
9. src/test/org/apache/lucene/search/function/TestFieldScoreQuery.java
10. src/site/src/documentation/skins/lucene/xslt/html/document-to-html.xsl
Press (n)ext page, (q)uit or enter number to jump to a page.

といった感じで検索ができたー。

全文検索エンジンについての選択肢あれこれ

自分が作りたいものが、検索エンジンがないと実現できないことが
判明したので、検索エンジンを作ることにしました!
と言いたいところだけど、まずは、
オープンソースでの検索エンジンについて調べてみました。
  • Senna
    • Wikipediaによると2ch検索で使われているなど実績がある
    • 日本語に強そう
    • MySQLやPostgreSQLをベースに動くみたい
  • Apache Lunece
    • 読みはルシーン
    • Cassandraと同じApacheプロジェクト
    • 日本語に弱そう、できないこともなさそうだが、手間はかかるのかな?
    • Wikipediaによると1000万ドキュメントを1台でできるらしい。
    • 例のごとくJavaで動く
  • Lux
    • C++のAPIが提供されている
    • 日本人が開発しているので日本語に強そう
  • Hyper Estraier
    • tokyocabinetなどの作者の平林幹雄さん作成の検索エンジン
    • 早そう
    • 中身はtokyocabinetと思いきや、QDBM
    • メンテされてない?十分に枯れてるから?
    • 1000万以上のドキュメントも分散処理できる
うーむ。迷う。
魅力を感じるのは、luceneとhyper estraier。
これからいじってみようとおもう。

cassandraに挑戦 その11 multiget_slice(0.6 API)

cassandra API のmultiget_sliceを使用して、任意のsuper columnの
任意のcolomnだけを取り出すサンプルコードを書いてみた。

サンプルコードはこちらのmultiget.php

データは以下のように入っているとする
cassandra> get Keyspace1.Super1['store1']['item1']
=> (column=title, value=ipod, timestamp=1267714302240)
=> (column=price, value=101, timestamp=1268052816239)
=> (column=description, value=ipod nano 8G / color:silver, timestamp=1268053455479)
Returned 3 results.
cassandra> get Keyspace1.Super1['store2']['item1']
=> (column=title, value=manga, timestamp=1267714346761)
=> (column=price, value=1000, timestamp=1267714336347)
Returned 2 results.
ここでmultiget.phpを実行すると、
Array
(
    [store2] => Array
        (
            [0] => cassandra_ColumnOrSuperColumn Object
                (
                    [column] => cassandra_Column Object
                        (
                            [name] => price
                            [value] => 1000
                            [timestamp] => 1267714336350
                        )

                    [super_column] =>
                )

        )

    [store1] => Array
        (
            [0] => cassandra_ColumnOrSuperColumn Object
                (
                    [column] => cassandra_Column Object
                        (
                            [name] => price
                            [value] => 101
                            [timestamp] => 1268052816240
                        )

                    [super_column] =>
                )
        )
)
store2, store1にある、item1の、priceだけが
取得できていることがわかります。

使い道によっては、すごく便利そうなので、メモメモ

cassandraに挑戦 その10 PHP Clientを動かしてみる

cassandraとThriftの準備が出来たので、
いよいよcassandra PHP clientを作ってみる。

いつものようにcassandraを起動して、
まずは、すでに入っているデータを確認する。
cassandra> get Keyspace1.Super1['store1']['item1']
=> (column=title, value=ipod, timestamp=1267714302240)
=> (column=price, value=101, timestamp=1268052816239)
=> (column=description, value=ipod nano 8G / color:silver, timestamp=1268053455479)
Returned 3 results.
このデータをPHPから取得できるサンプルを作ってみた。
コードはこちらのget.php。

実行結果は、
Array
(
    [0] => cassandra_ColumnOrSuperColumn Object
        (
            [column] => cassandra_Column Object
                (
                    [name] => description
                    [value] => ipod nano 8G / color:silver
                    [timestamp] => 1268053455480
                )

            [super_column] =>
        )

    [1] => cassandra_ColumnOrSuperColumn Object
        (
            [column] => cassandra_Column Object
                (
                    [name] => price
                    [value] => 101
                    [timestamp] => 1268052816240
                )

            [super_column] =>
        )

    [2] => cassandra_ColumnOrSuperColumn Object
        (
            [column] => cassandra_Column Object
                (
                    [name] => title
                    [value] => ipod
                    [timestamp] => 1267714302240
                )

            [super_column] =>
        )

)
cassandra-cliで取得できたものと同じデータが
取れたことを確認できました。

Happy!

参考:
http://wiki.apache.org/cassandra/ClientExamples#PHP

cassandraに挑戦 その9 PHP APC をインストール

cassandraをPHPから使うためにこのページを読んだところ、
Before working with Cassandra and PHP make sure that your PHP installation has APC enabled. If it does not please re-compile PHP and then recompile Thrift. APC drastically increases the performance of Thrift Interface
PHP-APCが必要とのことなので、
自分の開発機にPHP-APCをインストールした。
$ sudo aptitude install php-apc
$ aptitude show php-apc
パッケージ: php-apc
状態: インストール済み
自動的にインストールされた: no
バージョン: 3.0.19-2
優先度: 任意
セクション: web
メンテナ: Pietro Ferrari
展開サイズ: 180k
依存: libc6 (>= 2.7-1), phpapi-20060613+lfs
提案: php5-gd
説明: APC (Alternative PHP Cache) module for PHP 5
 Alternative PHP Cache

 The Alternative PHP Cache, also known as APC, is a free, open, and robust framework for caching and optimizing PHP intermediate code. APC is a fast solution
 for caching PHP code locally, it is not distributed like MemcacheD, but they can be used together for optimal caching.
ホームページ: http://pecl.php.net/package/APC
$ sudo /usr/sbin/apache2ctl restart
これで、phpinfoを確認したところ、apcのセクションがあったので、
無事インストール完了です。

apc

APC Support enabled
Version 3.0.19
MMAP Support Enabled
MMAP File Mask no value
Locking type pthread mutex Locks
Revision $Revision: 3.154.2.5 $
Build Date Dec 17 2008 18:01:29


これでようやく、PHP cassandra clientに取りかかれます。

cassandraに挑戦 その8 thriftのインストール

PHPやJavaのcassandraクライアントを作るために、
interface以下のコンパイルをしたいので、
まずはThriftのインストールをした。

Thriftのダウンロードはこちら

自分の環境では何点かはまったけど、以下の手順でインストールできた。
Thriftのバージョンは、0.2.0
$ sudo aptitude install automake libtool pkg-config libboost-dev byacc mono-2.0-service flex
$ sudo vi /usr/share/aclocal/libmcrypt.m4
$ diff -cw /usr/share/aclocal/libmcrypt.m4 /usr/share/aclocal/libmcrypt.m4.org
*** /usr/share/aclocal/libmcrypt.m4     2010-03-13 19:47:17.000000000 +0900
--- /usr/share/aclocal/libmcrypt.m4.org 2010-03-13 19:47:24.000000000 +0900
***************
*** 14,20 ****
  dnl AM_PATH_LIBMCRYPT([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
  dnl Test for libmcrypt, and define LIBMCRYPT_CFLAGS and LIBMCRYPT_LIBS
  dnl
! AC_DEFUN([AM_PATH_LIBMCRYPT],
  [dnl
  dnl Get the cflags and libraries from the libmcrypt-config script
  dnl
--- 14,20 ----
  dnl AM_PATH_LIBMCRYPT([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
  dnl Test for libmcrypt, and define LIBMCRYPT_CFLAGS and LIBMCRYPT_LIBS
  dnl
! AC_DEFUN(AM_PATH_LIBMCRYPT,
  [dnl
  dnl Get the cflags and libraries from the libmcrypt-config script
  dnl
$ ./bootstrap.sh
$ ./configure
$ mv libtool libtool.org
$ which libtool
$ ln -s /usr/bin/libtool libtool
$ ll libtool*
lrwxrwxrwx 1 satoshi satoshi     16 2010-03-13 19:32 libtool -> /usr/bin/libtool
-rwxr-xr-x 1 satoshi satoshi 220181 2010-03-13 19:23 libtool.org
$ make
$ sudo make install
$ which thrift
/usr/local/bin/thrift
$ thrift -version
Thrift version 0.2.0-exported
はまった点は以下
  • bootstrap.shで、[Debian] warning: underquoted definition of AM_PATH_LIBMCRYPT が出るので、こちらを参考に修正
  • makeの途中でlibtool関連のエラーで止まる

    • 同梱されている?libtoolを使わずに、aptitudeでinstallされた/usr/bin/libtoolを使うようにリンクを設定した
Thriftのインストールはうまくいったので、PHPインターフェースも
インストールしてみる。
$ lib/php/
$ sudo mkdir /usr/share/php/Thrift
$ sudo cp -R src/* /usr/share/php/Thrift/
これでインストールはできたので、
次は、cassandraのPHPクライアントを作ってみようと思う。

参考:
http://www.x0rz.com/2009/09/installing-thrift-interface-on-debian/
http://d.hatena.ne.jp/covanew/20081112/1226511336

Bloggerのダッシュボードにテンプレートデザイナー機能がリリース

Bloggerのダッシュボードにテンプレートデザイナー機能がリリースされました。


非常に便利なレイアウト編集機能です。
Blogger in draftから、レイアウトタブに遷移すれば、
テンプレートデザイナーというリンクがあります。
  • 豊富なデザインテンプレート
  • 幅の調整
  • フォント色や背景色の設定
  • レイアウトの設定

    • 2カラム

      • 左右ナビ
      • 右ナビ2列など

    • 3カラム
BloggerはAPIが豊富な分、デザインツールはあまり充実していませんでしたが、
これで簡単にページのデザインをかっこよくできそうです。

日本受けをよくするための機能でしょうか?

今後もBloggerの新機能に期待です。

cassandraに挑戦 その7 0.6.0 betaの動作確認

apache-cassandra-0.6.0beta版をダウンロード+コンパイルしたのでメモ

0.6.0からはAPIに変更があるようなので、早めに0.6.0に慣れるために
stable版の0.5.1から、0.6.0に乗り換えに挑戦。

APIの変更は以下
  • 0.6系で廃止予定


    • multiget
    • get_range_slice
    • batch_insert

  • 0.6系で追加予定


    • get_range_slices
    • batch_mutate
    • describe_keyspaces
    • describe_cluster_name
    • describe_version
    • describe_ring
    • describe_keyspace
なんだか色々機能が追加されているように見えます。
0.6.0betaの構築手順は以下
$ tar xvzf apache-cassandra-0.6.0-beta2-src.tar.gz
$ rm *tar.gz
$ mv apache-cassandra-0.6.0-beta2-src cassandra-0.6.0
$ cd cassandra-0.6.0/
$ ant
build-project:

(略)
     [echo] apache-cassandra: /home/satoshi/cassandra-0.6.0/build.xml
    [javac] Compiling 272 source files to /home/satoshi/cassandra-0.6.0/build/classes
    [javac] 注:一部の入力ファイルは推奨されない API を使用またはオーバーライドしています。
    [javac] 注:詳細については、-Xlint:deprecation オプションを指定して再コンパイルしてください。
    [javac] 注:入力ファイルの操作のうち、未チェックまたは安全ではないものがあります。
    [javac] 注:詳細については、-Xlint:unchecked オプションを指定して再コンパイルしてください。
[paranamer] Generating parameter names from /home/satoshi/cassandra-0.6.0/interface/avro/gen-java to /home/satoshi/cassandra-0.6.0/build/classes

build:

BUILD SUCCESSFUL
Total time: 4 minutes 26 seconds
$ chmod +x bin/cassandra
$ bin/cassandra -f
で無事起動が出来ました。0.5.1よりもantに時間がかかりました。
cassandra-cliで無事にデータが取れることなどを確認できました。
cassandra> show api version         
2.1.0
0.5.1のときは、cliから、show versionコマンドを実行したら、0.5.1だったんだが、
0.6.1からは、show api versionコマンドとなり、結果も、2.1.0という
cassandraのバージョンとは一致しないものになった。なぜだろう。


cassandraに挑戦 その6 特定のcolumnの値だけを取得

cassandraで、以下のように3つのcolumnにデータセットされている場合、
cassandra> get Keyspace1.Super1['store1']['item1']
=> (column=title, value=ipod, timestamp=1267714302240)
=> (column=price, value=101, timestamp=1268052816239)
=> (column=description, value=ipod nano 8G / color:silver, timestamp=1268053455479)
Returned 3 results.
priceだけ値を取りたいときのperl codeが以下。

use strict;
use warnings;
use Data::Dumper;
use Net::Cassandra;
my $cassandra = Net::Cassandra->new( hostname => 'localhost' );
my $client    = $cassandra->client;
my $key       = 'store1';
eval {
    my $what = $client->get_slice(
        'Keyspace1',
        $key,
        Net::Cassandra::Backend::ColumnParent->new(
            { column_family => 'Super1',
              super_column => 'item1',
            }
        ),
        Net::Cassandra::Backend::SlicePredicate->new(
            { column_names => ['price'] } # ここがポイント
        ),
        Net::Cassandra::Backend::ConsistencyLevel::QUORUM
        );
    print Dumper($what);
};
die Dumper($@) if $@;

結果は、
$ perl get_slice.pl
$VAR1 = [
          bless( {
                   'super_column' => undef,
                   'column' => bless( {
                                        'timestamp' => '1268052816239',
                                        'value' => '101',
                                        'name' => 'price'
                                      }, 'Net::Cassandra::Backend::Column' )
                 }, 'Net::Cassandra::Backend::ColumnOrSuperColumn' )
        ];
となり、priceだけ取得できています。
perl codeの、column_names部分のリストに、
レスポンスに含めたいcolumn_nameを追記すればその値だけが取れます。

cassandraに挑戦 その5 Thrift APIの解読

cassandraは、すごい機能がそろっているようなんですが、
いかんせん、ドキュメントが少ないような気がします。
さらに、まだ日本では流行っていないのか、日本語のドキュメントも
当然ながら少ない状態です。

こういうときは、コードを読むのが一番ですが、Javaは得意ではないので、
まずはPerlのコードをさがして読んでみました。

サンプルコード:
http://cpansearch.perl.org/src/LBROCARD/Net-Cassandra-0.34/examples/simple.pl


Thrift APIの仕様はこちらにまとまっているので、
この仕様とサンプルコードを突き合わせて、
なんとなーく理解を深めてみました。

あれこれコードをいじりながら、エラーメッセージを読みつつ、
わかったことなどのまとめは以下
  • 今はcassandra-0.5.1を使っているが、0.5でdeplicateするAPIと、0.6で新規に追加されるものがあるので、早めに0.6にバージョンを上げよう
  • getやget_sliceなどで、任意の範囲のKeyに対するデータを一発で取得できるが、取得する際に特定のnameだけのvalueを取得したかったが、できないっぽい → その後の調査で出来そうなことが判明

    • keyrangeがstartからfinishまでのもので、かつ、レスポンスには"title" columnだけを含める、というようなレスポンスフィルタができない。すべてのcolumnの結果が返る → その後の調査で出来そうなことが判明
    • column数が増えることによるレスポンスデータの肥大化をどうやって防ぐかが設計時の一番の課題になりそう
    • 設計の正当性はベンチで取るしかないが、どうやってベンチをとるか
    • どんなデータで、どのくらいどんな問い合わせ方をするか、が性能に直結しそう

  • データを扱いたいclientから直接Thrift APIを叩かせるのは危険

    • サービス仕様に応じて使いやすくwrapしたHTTP IFを作るべき
    • このIFはJavaで実装するのがよさげ(あまり根拠はないが、cassandraに近い部分なので、Javaで書くのがいいかな、と)
というわけで、とりあえずJavaの勉強でもしましょうかね、という結論。
以上。

cassandraに挑戦 その4 perl からデータ操作 Net::Cassandra

perlからCassandraのデータを操作してみた。

まずは、環境設定
  1. sudo cpan Net::Cassandra
  2. sudo cpan Bit::Vector
これで準備完了。
サンプルコードは以下。値を取得する部分のみ。
データはあらかじめ、cassandra-cliで突っ込んでます。

use warnings;
use Data::Dumper;
use Net::Cassandra;

my $cassandra = Net::Cassandra->new( hostname => 'localhost' );
my $client    = $cassandra->client;
my $key       = '6hills';

eval {
    my $what = $client->get(
        'Keyspace1',
        $key,
        Net::Cassandra::Backend::ColumnPath->new(
            { column_family => 'Standard1', column => 'item1' }
        ),
        Net::Cassandra::Backend::ConsistencyLevel::QUORUM
        );
    my $value     = $what->column->value;
    my $timestamp = $what->column->timestamp;
    warn "$value , $timestamp";
};
die Dumper($@) if $@; 
これを実行してみると、
$ perl test.pl
ipod , 1267321446497 at test.pl line 22.
無事に値が取れていました。
他のメソッドもこれから試して見ようと思います。

Firefox のデフォルトフォント(font.default.ja)を変更する on Debian lenny

Firefoxの漢字フォントが時々つぶれて表示されるのが
ずっと気になって、調べてました。

症状は以下のような状態でした。
「お菓子」の部分がつぶれているのがわかります。
 
普通は、FIrefoxのツールバーから、編集 -> 設定 -> コンテンツ
にあるフォント設定から設定すれば大丈夫かと思いきや、
全然なおりませんでした。

色々調べたのですが、全然見つからず、あきらめかけたのですが、
最後の望みで、「about:config」でそれっぽいのを編集しちゃえ、
とあたりをつけてやってみたところ、みごとになおりました。

「font.default.ja」に「VL Pゴシック」に設定しました。
設定前は「sans-serif」でした。

長いこと気になっていたので、なおったときはガッツポーズでした。

関連リンク:
無印良品の「自分でつくるガトーショコラ」を作ってみた

flickr API について調査 その3 flickr.tags.getRelatedで関連ワード取得

flickr.tags.getRelatedで関連ワードを取得するサンプルを作ってみました。
日本語の関連ワードはあまりとれないっぽいですが、
英語にしたり、ローマ字で打ち込んだりすると見れるかも。



<script type="text/javascript">
$(document).ready(function(){
  $('#flickr_search').click(function(){
    $('#results').html('please wait...');
    $.ajax({
      url : "http://api.flickr.com/services/rest",
      dataType : "jsonp",
      jsonp: 'jsoncallback',
      data : {
        format: 'json',
        method: 'flickr.tags.getRelated',
        api_key: '7342cf107eb5e911012e4a2e88f6855e',
        tag: $('#flickr_query').val()
      },
      success : function(r){
        $('#results').html('');
        for(i=0;i<r.tags.tag.length;i++){
          var t = r.tags.tag[i];
          $('#results').append($('<b/>').html(t._content+'<br/>'));
        }
      }
    });
  });
});
</script>


hadoop のバージョンを0.20にあげた

Debian lennyに hadoop をインストール
hadoop の examples を動かしてみる @ debian lenny

でhadoopをインストールしましたが、
バージョンが古い、という指摘をもらったので、
バージョンを0.20(test version)にあげました。
$ sudo emacs /etc/apt/sources.list.d/cloudera.list
$ sudo rm /etc/apt/sources.list.d/cloudera.list~
$ curl -s http://archive.cloudera.com/debian/archive.key | sudo apt-key add -
$ sudo aptitude update
$ aptitude search hadoop
$ sudo aptitude install hadoop-0.20
hadoop-0.18を削除しないでinstallしましたが、
サンプルは普通に動きました。
$ /usr/bin/hadoop version
Hadoop 0.20.1+169.56
Subversion  -r 8e662cb065be1c4bc61c55e6bff161e09c1d36f3
Compiled by root on Tue Feb  9 19:22:59 UTC 2010
簡単にできてよかったよかった。

cassandraに挑戦 その3 get_slice

前回に引き続き、bin/cassandra-cliを使って
もう少し深い機能を理解してみた。

ドキュメントを読みつつ、Googleで検索しつつ
手探りで機能を体で理解していく。
まちがってる部分があるかもしれないが、
とりあえず、自分の理解を書いてみる。

まずは、

Cassandra has a data model that can most easily be thought of as a four or five dimensional hash.
cassandraは、4次元または5次元のハッシュ構造としてデータを持てる、
ということ。4次元とは、
  • 日本/東京都/世田谷区/二子玉川 = 'セレブな街'
  • 日本/東京都/世田谷区/田園調布 = 'お金持ちな街'
ということ。5次元は
  • 日本/東京都/港区/六本木/6丁目 = '六本木ヒルズがあります'
  • 日本/東京都/港区/六本木/1丁目 = '森ビルがあります'
  • 日本/東京都/港区/六本木/3丁目 = 'ほげほげがあります'
ということ、のようです。つまり、
Key = Value
の形だが、Keyが多層構造になってる、ということ。

データ構造を4次元にするか、5次元にするかなども含めて、
定義はすべて、
conf/storage-conf.xml
に書きます。

また、Keyの次元は、上から名前が付いています。4次元の場合、
  1. Keyspace
  2. Column Families
  3. Rows
  4. Column ( name and value and timestamp)
5次元の場合は、
  1. Keyspace
  2. Column Families
  3. Super Columns
  4. Rows
  5. Column ( name and value and timestamp)
という名前がそれぞれ付いています。

ここで重要なのが、Keyspace と Column Familiesは
conf/storage-conf.xmlを書き換えても、再起動をしないと
追加/変更ができない、という点です。
プロセスの起動前に定義しておかなければいけません。

逆に言うと、KeyspaceとColumn Familiesは可変ではないが、
Row と Column 随時追加可能です。好き放題データを突っ込めます。

さらに、cassandraにある機能で便利なものが、get_sliceで、
以下のようなデータの取得ができます。
cassandra> set Keyspace1.Standard1['book1']['title'] = 'dragon ball'          
Value inserted.
cassandra> set Keyspace1.Standard1['book1']['price'] = '500yen'    
Value inserted.
cassandra> get Keyspace1.Standard1['book1']                   
=> (column=title, value=dragon ball, timestamp=1267713708356)
=> (column=price, value=500yen, timestamp=1267713720682)
Returned 2 results.
book1/title = dragon ball
book1/price = 500yen
というデータに対して、
( この場合、book1がrow、
title/priceがcolumn name、
dragon ball/priceが column value )
通常のKVSなら、book1/titleとbook1/priceの両方の値を欲しいときは
それぞれ1回ずつ合計2回問い合わせてすべてのcolumn valuesを
取得するしか方法がないが、cassandraの場合、
book1を指定するだけで、それにぶら下がるものすべてを
1回で取得できるようになっている。

これは便利。なぜなら、1回の問い合わせで取得できるのはもちろんのこと、
book1以下にどのようなKEYがぶらさがっているかを知らない場合も
値をすべて取得できるから。

さらに5次元のハッシュの場合、便利さは際立って、
cassandra> set Keyspace1.Super1['store1']['item1']['price'] = '100'
Value inserted.
cassandra> set Keyspace1.Super1['store1']['item1']['title'] = 'ipod'
Value inserted.
cassandra> set Keyspace1.Super1['store1']['item2']['price'] = '200'
Value inserted.
cassandra> set Keyspace1.Super1['store1']['item2']['title'] = 'sony walkman'
Value inserted.
cassandra> set Keyspace1.Super1['store2']['item1']['price'] = '1000'       
Value inserted.
cassandra> set Keyspace1.Super1['store2']['item1']['title'] = 'manga'      
Value inserted.
cassandra> set Keyspace1.Super1['store2']['item2']['price'] = '2000'       
Value inserted.
cassandra> set Keyspace1.Super1['store2']['item2']['title'] = 'cake'       
Value inserted.
というデータを入れたときに、
cassandra> get Keyspace1.Super1['store2']                          
=> (super_column=item2,
     (column=price, value=2000, timestamp=1267714355659)
     (column=title, value=cake, timestamp=1267714368210))
=> (super_column=item1,
     (column=price, value=1000, timestamp=1267714336347)
     (column=title, value=manga, timestamp=1267714346761))
Returned 2 results.
↑これでstore2に含まれる商品とその情報を一発で取得できるし、
cassandra> get Keyspace1.Super1['store2']['item2']
=> (column=title, value=cake, timestamp=1267714368210)
=> (column=price, value=2000, timestamp=1267714355659)
Returned 2 results.
↑これでstore2/item2の商品情報を一発で取得することもできる。

cassandraは、単純なKVSよりも高機能であることがわかった。

こんなに高機能でありながら、高速に動作してくれるらしいので
今後は性能について調べて見ようと思う。

究極のドキュメント管理を考える その6 sphinxのインストール

sphinxはpythonで書かれた、ドキュメントジェネレータです。

ドキュメントをreStructuredText形式で書いておけば、
コマンドを実行するだけで、HTMLやLaTexに書き出してくれる優れものです。

インストール手順は以下
$ sudo aptitude install python-sphinx
 使い方は、
  1. ドキュメント保存のためのディレクトリ作成



  2. $ mkdir sphinx_text && cd sphinx_test
    



  3. /usr/bin/sphinx-quickstartを実行して質問に答える



  4. $ sphinx-quickstart
    英語で質問されるので、答える。
    基本、Enter連打でOKだが、「rstソースとジェネレートファイル置き場を分けるか?」
    という質問に対して、Yesにした方が管理しやすいのでおすすめ
    



  5. 2.でできた ***.rst を編集したり、新しく ***.rst を追加したりする



  6. $ tree
    .
    |-- Makefile
    |-- build
    `-- source
        |-- conf.py
        `-- index.rst
    
    2 directories, 3 files
    $ emacs source/my.rst source/index.rst
    my.rstを新規追加
    index.rstには、my.rstに遷移できるようにリンクをつける
    -----
    .. toctree::
       :maxdepth: 2
    
       my
    -----
    



  7. make html でHTMLをジェネレート


  8. $ make html
    mkdir -p build/html build/doctrees
    sphinx-build -b html -d build/doctrees   source build/html
    Sphinx v0.4.2, building html
    trying to load pickled env... done
    building [html]: targets for 1 source files that are out of date
    updating environment: 0 added, 1 changed, 0 removed
    reading... index 
    pickling the env... done
    checking consistency...
    writing output... index 
    finishing... 
    writing additional files...
    copying static files...
    dumping search index...
    build succeeded.
    
    Build finished. The HTML pages are in build/html.
    


  9. web serverのドキュメントルートにコピーすればHTMLを確認できます


  10. $ cp -R build/html/* /var/www/nginx-default/sphinx/
    
といった流れです。
できたページが、


こんなページになります。
デフォルトでこのような見た目のページができて、かつ、
検索機能も付いています。
検索機能はjavascriptで実装されているので、
CGIの準備は必要ありません。

検索機能について、や、カスタマイズ方法については
また別途ブログに書きたいと思います。

参考:
http://sphinx.shibu.jp/index.html
http://plaza.rakuten.co.jp/kugutsushi/diary/200803230001/

jQuery Keyz plugin で特殊キーの押下イベントを取得する

jQuery Keyz pluginを使えば、windowキーやFunctionキーなどの
特殊キーを押したときのイベントを取得出来るようになります。

デモページはこちら。

Firefox 3.6 on linux で試しましたが、正常にキーイベントを
取得できてました。今度何かのツールを作るときに
使って見ようかとおもいます。

flickr API について調査 その2 flickr.photos.searchで画像検索

とりあえず、簡単なところで、flickr.photos.search APIを使って
Javascriptで画像検索できるようにしてみました。

単純にテキストで検索するだけだけど、
なかなか面白い写真が見つかって楽しいです




yomiowatter 2010/02 読了ランキング

http://www.geocities.jp/tanarky/yomiowatter/

yomiowatterの2010年2月の読了ランキングを集計しました。
多少botっぽいのを捨てました。まだ、マッチング精度が悪いのはご容赦ください。
では、どうぞ。



こうやってみると、1月とは結果が全然ちがいますな。
定期的に集計してみたいと思います。


cassandraに挑戦 その2 インストール

自分の開発機(Debian lenny)にcassandra環境を構築してみました。
色々はまったのですが、とりあえず、うまくいった方法は以下の通り。

1. Java環境のインストール
$ sudo aptitude install openjdk-6-jdk openjdk-6-jre
$ which java
/usr/bin/java
$ which javac
/usr/bin/java
$ java -version java version "1.6.0_0" OpenJDK Runtime Environment (build 1.6.0_0-b11)
OpenJDK Client VM (build 1.6.0_0-b11, mixed mode, sharing)
2. ソース版cassandraのダウンロード

この記事を書いている時点の最新stable版バージョンが0.5.1でした。
http://incubator.apache.org/cassandra/
からダウンロードすればいいのですが、
http://www.apache.org/dyn/closer.cgi?path=/incubator/cassandra/0.5.1/apache-cassandra-0.5.1-bin.tar.gz
のページに表示される日本のミラーサイトには、
最新版がないのか、404 not foundになったので、
http://www.apache.org/mirrors/
から適当にhttpサイトを選んで、
incubator -> cassandra -> 0.5.1
とフォルダを降りればtar.gzが見つかります。
http://ftp.kddilabs.jp/infosystems/apache/incubator/cassandra/0.4.1/apache-cassandra-0.4.1-src.tar.gz

3. 解凍
$ wget 'http://ftp.kddilabs.jp/infosystems/apache/incubator/cassandra/0.5.1/apache-cassandra-0.5.1-src.tar.gz'
$ tar xvzf apache-cassandra-0.5.1-src.tar.gz
$ cd apache-cassandra-0.5.1-src/
$ ant
(略)

BUILD SUCCESSFUL
Total time: 23 seconds
4. もろもろの準備
$ sudo mkdir -p /var/log/cassandra
$ sudo chown -R `whoami` /var/log/cassandra
$ sudo mkdir -p /var/lib/cassandra
$ sudo chown -R `whoami` /var/lib/cassandra
$ chmod +x bin/cassandra bin/cassandra-cli
5. 起動
$ bin/cassandra -f
6. 別のターミナルからcassandra-cliで動作確認
$ bin/cassandra-cli --host localhost --port 9160
  cassandra> set Keyspace1.Standard1['jsmith']['first'] = 'John'
  Value inserted.
  cassandra> set Keyspace1.Standard1['jsmith']['last'] = 'Smith'
  Value inserted.
  cassandra> set Keyspace1.Standard1['jsmith']['age'] = '42'
  Value inserted.
  cassandra> get Keyspace1.Standard1['jsmith']
    (column=age, value=42; timestamp=1249930062801)
    (column=first, value=John; timestamp=1249930053103)
    (column=last, value=Smith; timestamp=1249930058345)
  Returned 3 rows.
  cassandra>
というわけで、無事に動きました。
-f で起動していれば、停止するときは、Ctrl + c で停止できます。
一度停止しても、再度起動して、getすれば、一度保存していたデータが
ちゃんと取れたことも確認しました。

これから使い倒してみます。

参考:
http://wiki.apache.org/cassandra/CassandraCli
http://wiki.apache.org/cassandra/API
http://wiki.apache.org/cassandra/GettingStarted
ソースに含まれているREADME.txt

flickr API について調査 その1 API一覧

flickr API について、調査。

猫暦を作ってたときには分かってなかったですが、
最近、ようやくflickrのすごさについて理解しました。
flickrは、
  • ユーザ数が多い
  • 綺麗な写真が多い(クオリティが高い写真が多い)
  • お目当ての写真を見つけやすい
  • コミュニティがたくさんあって楽しい
  • APIが豊富
  • bloggerなどの外部サイトとの連携が簡単(写真からブログを書いたり)
などなど。
というわけで、
APIについて 調査開始。

一覧は、http://www.flickr.com/services/api/
にあります。
おためしにAPIを叩いてみたい場合は、
http://www.flickr.com/services/api/explore/
から叩けるので、実装する前に確認ができます。

便利便利。


cassandraに挑戦 その1 実績調査

最近、cassandraの存在を知りました。

http://ja.wikipedia.org/wiki/Apache_Cassandra

Cassandraはイベンチュアル・コンシステンシーにより構造化されたキー・バリュー型データストアを提供 する。キーは複数の値にマッピングされ、これらはcolumn familyとしてグルーピングされる。column familyはCassandraデータベースが作成される際は固定されているが、後にfamilyに対し列を追加することは可能である。さらに、列は特 定のキーにのみ追加されるので、どのfamilyにおいても異なるキーは任意の列数を持つことができる。各キーに対応するcolumn familyの値は連続して記録され、このことによりCassandraは列指向データベースマネジメントシステムと行指向データベースシステムの複合型であ ると言える。
cassandraの実績を調べてみました。
Twitter、MySQLデータベースからCassandraに移行
分散データベースの「Cassandra」がApacheのトップレベルプロジェクトに

本家サイト
http://incubator.apache.org/cassandra/


欲しい機能が実装されていそうだったのと、
評判もいいので、これから色々調査して見ようと思います。


尾山台の串カツ 田中

尾山台に最近できたと思われる串カツ田中にいってきました。

調べて見たところ、どうやら都内3店舗目で、
世田谷店はなかなか有名らしいです。

ソースの2度つけは罰金1000円なので、
最初はびくびくしてましたが、
どろっとしてて甘め+濃い目のソースで、
1回つけるだけでちょうど良く食べられました。

家からも近いので、下見程度に何本か食べて
さらっと帰ろうと思いきや、揚げ物とは思えないくらい
軽い感じで、結局、2時間弱店にいました。
それでも会計は二人で4500円程度で
お財布にやさしいお店と判明。

これからも何度か足を運ぼうと思います。