Jubatusのクライアントがタイムアウト吐き出してエラー落ちした本当の原因

皆さん、こんにちは

ちょっと機械学習やりたいなぁとか思って、手頃っぽいjubatusに手を出してみました
チュートリアルをためしてみると、割とあっさりできてしまえるのだけど、どうしてもハマっちゃうところが出たので、その原因と対策を共有します。

# jubatus

http://jubat.us/ja/index.html

オンライン機械学習むけ分散処理フレームワークというやつらしいです。
最近は日本製の機械学習ツールが増えてきたんじゃないかなぁって思っていたのですが、これは結構前からあった模様。
日本語のドキュメントも充実しているので、せっかくだから使ってみるぜ！ってことで試してみた次第です。

# インストール

インストールはそのままクイックスタートを追いかけただけです。
また、例によって仮想環境に突っ込んで見ることにしました。

まず仮想環境としてはubuntuのtrusty64 というボックスが公式に提供されているので、こいつを使用します。

```
vagrant init ubuntu/trusty64; vagrant up --provider virtualbox
```

これで仮想環境はできたので、すぐに中に入ってインストール作業をやります。
http://jubat.us/ja/quickstart.html

jubatusのクライアントとしてはpythonにしておきましょう。
大体のLinuxには入っているので

```
$ sudo vim /etc/apt/sources.list.d/jubatus.listv #リポジトリを加える
$ cat /etc/apt/sources.list.d/jubatus.list
deb http://download.jubat.us/apt binary/

$ sudo apt-get update
$ sudo apt-get install jubatus # jubatusがインストールされる

$ sudo apt-get install python-pip
$ sudo pip install jubatus # pythonのjubatusクライアントがインストールされる

$ source /opt/jubatus/profile # 毎回設定ファイルを読み込むので ~/.bash_profileに突っ込んでおくといい
```

# チュートリアルを動かす

なんの問題もなくインストールが完了したので、次はチュートリアルを動かしてみます。
初期のubuntuにはgitがないようなので、ホスト上で

```
git clone https://github.com/jubatus/jubatus-tutorial-python.git
cd jubatus-tutorial-python
```
落としたリポジトリが、そのまま作業ディレクトリになりますので、ここでテストデータを突っ込みます。

```
$ wget http://qwone.com/~jason/20Newsgroups//20news-bydate.tar.gz
$ tar xvzf 20news-bydate.tar.gz
```
かなり重いので、ダウンロード終了まで我慢しましょう。
ダウンロードが終わったら、早速jubatusを起動します。

```
jubaclassifier --configpath config.json
```
jubatusサーバが起動したようです。
最後にクライアントを起動させ、テストデータをjubatusに投げ込んでみましょう。

# エラーが。。。

```
python tutorial.py
```
これで、クライアントが起動するのですが。。。

```
msgpackrpc.error.RPCError: Request timed out
```
という、タイムアウトエラーを吐き出して停止します
これだけなら単純なタイムアウトなのかなぁと思うのですが。。。

```
starting load from /tmp/10.0.2.15_9199_classifier_tutorial.jubatus
Killed
```
こんな感じのエラーを吐き出してサーバが停止しています。
単純なタイムアウトであればサーバは停止しないはずです。

で、もう少し検証してみたのですが、先にサーバが止まり、その後にクライアントが止まっているようです。
そもそも、なんの断りもなく、突如としてkillされているので、OS側からやられているっぽいです。
そんならsyslogでも見てみれば良いということで

```
$ tail /var/log/syslog
Feb  8 12:29:49 vagrant-ubuntu-trusty-64 kernel: [56821.828429] [ 9500]  1000  9497   128839    93956     234        0             0 jubaclassifier
Feb  8 12:29:49 vagrant-ubuntu-trusty-64 kernel: [56821.828431] [ 9501]  1000  9501    12649     2238      29        0             0 python
Feb  8 12:29:49 vagrant-ubuntu-trusty-64 kernel: [56821.828432] Out of memory: Kill process 9500 (jubaclassifier) score 750 or sacrifice child
Feb  8 12:29:49 vagrant-ubuntu-trusty-64 kernel: [56821.829547] Killed process 9500 (jubaclassifier) total-vm:515356kB, anon-rss:375824kB, file-rss:0kB
```
Out of memory !!
MySQLで散々やられたやつですね
プロセスファイルが見つからないとかわけのわからんエラーを吐いたくせに、ログを見るとメモリ不足でエンジンを立ちあげられなかっただけとかいう。。。

だったら、メモリ増やしてやればいいようです
AWSとかだったらスワップ作るんですが、今回はvagrantなのでお手軽に増やせます

```
   config.vm.provider "virtualbox" do |vb|
  #   # Display the VirtualBox GUI when booting the machine
  #   vb.gui = true
  #
  #   # Customize the amount of memory on the VM:
     vb.memory = "2048"
   end
```
流石に2GBもメモリあれば、動くでしょう。

で、結果ですが

```
OK,sci.med, sci.med, 0.584435760975
NG,sci.electronics, soc.religion.christian, 0.37116548419
OK,talk.politics.guns, talk.politics.guns, 1.49401080608

▽
OK,rec.sport.hockey, rec.sport.hockey, 1.0699224472
===================
OK: 5398
NG: 2134
```
しっかりと動いてくれました。

# まとめ

out of memory でkillするんなら、out of memoryって書いてくれてもいいじゃない。。。
まあ、syslogで出すからいいんだってことなんでしょうかね。。。

とりあえず、クライアントどころかサーバまで落ちてるようなら、syslog確認するといいよって話でした。

# 参考

[Jubatus : オンライン機械学習向け分散処理フレームワーク](http://jubat.us/ja/#)
[Jubatusのtimed out errorがtimed out error じゃなくて嵌った件](http://wwld.jp/2016/02/07/jubatus-error.html)
(一日前に同じ悩みを抱えていた方がいらっしゃるとは。。。)