2013年12月7日土曜日

ElasticSearch と Kibana で画像共有サイトのシェアを調べてみる

 Twitterを眺めてたら ElasticSearchKibana というものが流行ってるらしいので、たまたま気になっていた画像共有サイトのシェアを調べてみた。

Install ElasticSearch

まずは、ElasticSearchをインストールする。
Gentoo Linux の場合は以下のコマンドで一発。

$ sudo emerge -av  app-misc/elasticsearch

設定ファイルのサンプルが /etc/elasticsearch/ にインストールされているので、それをベースに設定する。
今回はデフォルトのまま使用した。

$ sudo cp /etc/elasticsearch/elasticsearch.yml.sample /etc/elasticsearch/elasticsearch.yml
$ sudo cp /etc/elasticsearch/logging.yml.sample /etc/elasticsearch/logging.yml

あとはサービスを起動する。

$ sudo /etc/init.d/elasticsearch start

この起動スクリプトは複数のインスタンスが起動できるようになっているようで、例えば hogehoge.yml という設定を作り /etc/init.d/elasticsearch.hogehoge という名前の起動スクリプトを作ればいいらしい。
デフォルトでは elasticsearch.yml が利用される。


Install Kibana

Kibana 自体は HTML と JavaScript で構成されているものなので、ダウンロードしてきて展開するだけである。

$ tar zxvf kibana-3.0.0milestone4.tar.gz
$ cd kibana-3.0.0milestone4
$ python3 -mhttp.server

一時的に動かすだけであれば、これで十分。

Install Twitter River

 ElasticSearch に Public streamssample をどうやって入れればいいのか調べてみたところ、 Twitter River というプラグインを使えばいいことが分かった。

$ sudo /usr/share/elasticsearch/bin/plugin -install elasticsearch/elasticsearch-river-twitter/1.4.0 
-> Installing elasticsearch/elasticsearch-river-twitter/1.4.0...
 Trying http://download.elasticsearch.org/elasticsearch/elasticsearch-river-twitter/elasticsearch-river-twitter-1.4.0.zip...
 Downloading ....................................................................DONE
 Installed elasticsearch/elasticsearch-river-twitter/1.4.0 into /usr/share/elasticsearch/plugins/river-twitter


使い方については README を見れば判ると思う。
今回は sample を利用するので type は省略する。

$ curl -XPUT localhost:9200/_river/tweets/_meta -d '
  {
      "type" : "twitter",
      "twitter" : {
          "oauth" : {
              "consumer_key" : "**** CONSUMER KEY ****",
              "consumer_secret" : "**** CONSUMER SECRET ****",
              "access_token" : "**** ACCESS TOKEN ****",
              "access_token_secret" : "**** ACCESS SECRET TOKEN ****"
          },
          "ignore_retweet" : true
      },
      "index" : {
        "index": "tweets",
        "type": "tweet",
        "bulk_size": 100
      }
  }
  '
  {"ok":true,"_index":"_river","_type":"tweets","_id":"_meta","_version":1}

これで tweets と言う名前の index が作成され、自動的に Twitter Stream に接続してツイートを収集してくれる。
ツイートがある程度溜まるまでちょっと待ってから Kibana にアクセスしてみる。

前述の通りに Kibana をインストールしている場合は http://localhost:8000/ で表示できます。
ホーム画面の一番下に Blank Dashboard というリンクがあるのでクリックしてみます。


右下に Add Row というボタンがあるのでクリックします。


Create Row ボタンを押します。


Add Panel というボタンを押してパネルを追加します。
Panel Type は Histogram でやってみます。
Sizeは12にすると横幅がマックスになります。

Time Field はデフォルトでは @timestamp になっていて、レコードが追加された日時になるようです。
ただ、Twitter River ではそのようなフィールドはないので Tweets のフィールドである created_at に変更しておきます。


また、右上に Configure Dashboard ボタンで Dashboard の設定を変えられるのですが、そこの Timepicker の設定も created_at に変更しておきます。



そうすると、このようなグラフが表示されます。
簡単ですね。

Customize Twitter River

 さて、これでシェアを調べられると思ったのですが、Twitter Riverプラグインでは Entities の urls フィールドしか取得していないようで、media フィールド内にある pic.twitter.com の情報は取得できませんでした。
 Twitter River には raw という Tweets オブジェクトをまるまる保存するオプションがあります。これを使用すればいいだろうと思って試してみました。

$ curl -XDELETE localhost:9200/_river/tweets/
$ curl -XPUT localhost:9200/_river/tweets/_meta -d '
  {
      "type" : "twitter",
      "twitter" : {
          "oauth" : {
              "consumer_key" : "**** CONSUMER KEY ****",
              "consumer_secret" : "**** CONSUMER SECRET ****",
              "access_token" : "**** ACCESS TOKEN ****",
              "access_token_secret" : "**** ACCESS SECRET TOKEN ****"
          },
          "ignore_retweet" : true,
          "raw": true
      },
      "index" : {
        "index": "tweets",
        "type": "tweet",
        "bulk_size": 100
      }
  }
  '
  {"ok":true,"_index":"_river","_type":"tweets","_id":"_meta","_version":1}

これを試してみたところ created_at が文字列型になってしまいタイムスタンプとしての利用ができませんでした。
試しに Index の型を変更してみようとしたところエラーが出て変更できませんでした。

$ curl -XPUT localhost:9200/tweets/tweet/_mapping -d '
  {
    "tweet" : {
      "properties" : {
        "created_at" : {"type" : "date", "format": "EE MMM d HH:mm:ss Z yyyy" }
        }
      }
    }
  }' | jq .
  {
    "error":"MergeMappingException[Merge failed with failures {[mapper [created_at] of different type, current_type [string], merged_type [date]]}]",
    "status":400
  }

どうも型の変更はできないようです。
Twitter Riverプラグインはオープンソースなのでフォークして、Media内のURLのインデックスを作成するように修正してみました。

https://github.com/kjmkznr/elasticsearch-river-twitter/tree/add-media-entities

$ git clone https://github.com/kjmkznr/elasticsearch-river-twitter.git
$ cd elasticsearch-river-twitter
$ git checkout add-media-entities
$ mvn package

これで target/releases/elasticsearch-river-twitter-1.5.0-SNAPSHOT.zip というファイル名でプラグインがビルドされます。

これを ElasticSearch にインストールします。

  $ sudo /usr/share/elasticsearch/bin/plugin -remove river-twitter
  -> Removing river-twitter 
  Removed river-twitter
  $ sudo /usr/share/elasticsearch/bin/plugin -u file:/path/to/elasticsearch-river-twitter-1.5.0-SNAPSHOT.zip -i river-twitter
  -> Installing river-twitter...
  Trying file:/path/to/elasticsearch-river-twitter-1.5.0-SNAPSHOT.zip...
  Downloading ....DONE
  Installed river-twitter into /usr/share/elasticsearch/plugins/river-twitter
  $ /usr/share/elasticsearch/bin/plugin -l
  Installed plugins:
      - river-twitter

あとはまた収集されるのを待ち Kibana でグラフを表示させます。



このグラフは2013/12/03 18:25 - 2013/12/07 18:25 のものです。
前述のプラグインをさらに修正して lang フィールドが ja のものを対象としています。

1位pic.twitter.com150,804 件
2位twitpic.com3,661 件
3位p.twipple.jp1,112 件
4位instagram.com689 件
5位photozou.jp118 件
6位flickr.com/flic.kr22 件
7位movapic.com1 件


調査対象は自分が思いついたサイトです。
95% は pic.twitter.com が使われているようで、思ったよりシェアが大きくびっくりしました。
公式クライアント・Webを使っている人が増えているようですね。

画像共有とはちょっと違いますが、vine.co を含むツイートを調べてみたところ、2,800件もありました。
結構普及しているんですね。

参考文献

* CactiのデータをElasticSearch+Kibanaでまとめてみてみよう