nigoblog

技術系会社のCEOブログ~私的編~

4月に読んだ本リスト、読んだ理由と感想

4月は比較的時間がとれたので本を読みました。
土曜日 or 日曜日にドトールで2時間ほどまとめて読書の時間をとるようにしています。

なので4月に読んだ本を紹介していきたいと思います。

技術・学術系

Bandit Algorithms for Website Optimization

Bandit Algorithms for Website Optimization

Bandit Algorithms for Website Optimization

バンディットアルゴリズムを理解するために読みました。
久しぶりに英語の本を読んだので疲れました。
Bandit Algorithmの入門書。論文とかを読む前にまずはこちらからって感じの本。
基本的な3つのアルゴリズムが示されています。
最初に言葉の定義が書かれていたのが丁寧でよかったなと。

プログラミング Hive

プログラミング Hive

プログラミング Hive

Hadoopを使う際、Hiveを利用したので購入して読みました。
リファレンス代わりに使っております。チューニングW方法が示されているところがよかったなと。
(ただHadoopはHiveよりも効いてくるとこが多いので役に立つかといえば微妙なところ)

WEB+DB PRESS vo.80

WEB+DB PRESS Vol.80

WEB+DB PRESS Vol.80

とりあえず毎号買っているんですが、今回の注目はテスト駆動インフラ。serverspecに関してはvo.76
ですでにやっていたので特に新しい情報はなかったな…
一歩先ゆくRubyと理論で学ぶSQLがなくなって悲しんだのは自分だけじゃないはず。

統計学入門(基礎統計学)

統計学入門 (基礎統計学)

統計学入門 (基礎統計学)

学部時代にもやったけど、復習のため。忘れているところが多々あったので思い出せてよかったなと。
統計量に関してはRやPythonの関数を使うのもいいけど、あえてRubyで書いてみました。
分布の概念はデータのモデリングをするために重要だなと。

自然科学の統計学(基礎統計学)

自然科学の統計学 (基礎統計学)

自然科学の統計学 (基礎統計学)

こちらは具体的な利用例など。まだ全部は読めていないですが、統計学入門でさらっと流している分布について詳しく書かれています。

ビジネス・教養系

MEDIA MAKERS

MEDIA MAKERS―社会が動く「影響力」の正体

MEDIA MAKERS―社会が動く「影響力」の正体

前々から読んでみたいと思って購入。
ブログもやっているし、今後メディアも作っていきたいと思ったので。
内容は単純に面白かった。じゃらんのくだりで、部屋の露天風呂特集らへんの話が面白い。

仕事に効く 教養としての「世界史」

最近世界史にハマっていて、ビジネスにもつながるのかと思い購入。
ビジネスにつながるかどうかは別として面白かった。
高校・大学と数学・物理・専門教科ばかりに気を取られ、教養系や歴史系を軽視していたのを後悔しています。なので今世界史の本を読むと新たな発見が盛りだくさんですごく楽しい。

経済は世界史から学べ!

経済は世界史から学べ!

経済は世界史から学べ!

上記と同じ理由で購入。
ためになったっちゃあためになったけど、ある程度世界史の知識が身についた後に読んだので物足りない感がある一冊。
これからはもうちょいスコープを狭めディープな歴史を学んでいこうかなと思います。

まとめ

最近はベーシックな部分の本を読むようにしています。
教養系では世界史もそうだけど地理の本ももう少したくさん読みたいなと思っています。

新しく技術・知識を身に付けるためのやりかた

最近スキルの幅が広がったかなと思います。

理由としては
ビジネスで要件がでる。
-> とある技術を使わなければいけない。
-> その技術を理解する&使う。

こういうフローが経営に近くなるほど起こりやすいのでスキルの幅がかなり広がっています。

最近で身に付けた技術は

  • fluentd
  • Hadoop (EMR)
  • Hive
  • Bandit Algorithm

なんかを身に付けました。
どんなフローで身に付けていったかを簡単に書いていきます。

スライドシェアを見る

公式ドキュメントよりもまずはこっちを先に見るのがよいかと思います。
理由としては使い方以外に「なぜそれを使うのか」ということが同時にわかるケースが多いからです。

バンディットアルゴリズムの時には
バンディットアルゴリズム入門と実践
バンディットアルゴリズム概論

この2つがかなり参考になりました。

入門書を読む

イントロダクションはスライドシェアでなんとなくわかっていると思うので飛ばし、実装フェーズあたりから読む。
そして写経をする。

Hadoopの時には前回までの3つのブログでも書きましたが、

Hadoopファーストガイド

Hadoopファーストガイド

これがかなり良かったです。
まずコマンドを実行する -> 結果を見る -> そのコマンドがなんとなくわかる。

バンディットアルゴリズムの時には

Bandit Algorithms for Website Optimization

Bandit Algorithms for Website Optimization

こちらを読みました。
とりあえず写経する -> 結果を見る -> パラメータを変えてみる -> そのアルゴリズムがなんとなくわかる

公式ドキュメントを読む

ここでやっと公式ドキュメントが出てきます。
公式ドキュメントは新しく学ぶためというより、ある程度わかってきた時のリファレンス感覚で使うのが良いかなと。
EMRは
開発者用リソース - Amazon Elastic MapReduce(Hadoopクラスター Amazon EMR) | アマゾン ウェブ サービス(AWS 日本語)
この辺。
Hiveは
Apache Hive TM
この辺。
今回のやつはググったら公式ドキュメントが多く出てきた気がします。

ググる

これも公式ドキュメントと同じ使い方ですね。
なんか躓いたり、これも出来ないかなと思ったらググる
より正確な情報を得るために、公式ドキュメントで探してそれでもダメだったらググるほうがよいかと思っています。

誰かに教える

誰かに教えたり、発表すると記憶が定着します。
資料作ってる時に使ってたコマンドを参照したり、なんとなく理解していたものを質問されて詳しく調べたりなど。
結構質問の時に新しい発見あったりするんだよね。

使い続ける・チューニングし続ける

そうしないとすぐに忘れてしまうので。


というわけでかなり個人的ですが、新しく技術や知識を身に付ける手順でした。

ビッグデータ取り扱いまでの流れ3 自動化編

今回はhiveの動作を自動化させる方法に書いていきます。

前回の記事
ビッグデータ取り扱いまでの流れ2 解析編 - nigoblog
ではsshでEMRのmasterインスタンスにログインし、hiveの動作を行います。

基本的にはこの作業をrailsで自動化させます。(もっとうまいやり方があると思うが…)

というわけで早速やり方を見ていきます。

net/sshの利用

net/sshというgemを利用します。
Net::SSH、Net::SCP RubyでSSH/SCPコマンドを実行 [Ruby] - 酒と泪とRubyとRailsと
詳しい使い方はこちらの記事に。

このように利用します

require 'net/ssh'

Net::SSH.start(HOST, USER, opt) do |ssh|
    ssh.exec!("[何かしらのコマンド]") do |channel, stream, data|
      p data if stream == :stdout 
      p data if stream == :stderr
    end
end

ここでHOSTはEMR masterのpublic DNS
USERはhadoop, optは

opt = {
 keys: [公開鍵のパス]
 port: [sshのポート(普通は22)]
}

と定義しておきます。

感のいい方ならお気づきかもしれませんが、[何かしらコマンド]に

hive -e "[hiveのhql]"

とすることでhiveのコマンドを実行出来ます。

確認方法

テストコードを書ければ問題ないのですが、hiveを使うこともあってかなりしんどいです。
なので手動テストの方法を書いていきます。
先ほどのコードは

class Hoge < ApplicationController
  def fuga
     [hiveを実行する処理]
  end
end

のようにあるクラスのインスタンスメソッド内で行っているとします。

Railsのルートで

rails c

とするとirbが立ち上がります。
そこで

hoge = Hoge.new
hoge.fuga

とすると処理が走ります。
これで確認していきます。

(将来的にはhiveのテストコードを作りたい。hive_spec的な)

自動化

これはwheneverというgemを利用します。
wheneverの詳しい使い方はこちら
Wheneverは導入が超簡単なcrontab管理ライブラリGemです![Rails] - 酒と泪とRubyとRailsと
(本日2度目の引用です。いつもありがとうございます。(面識はありませんが笑))

gemをインストールすると
config/schedule.rbに

every '00 * * * *' do
  runner "Hoge.new.fuga"
end

とします。
なんとこれだけでオッケー。内部的にはcrontabの内容が書き換わっています。
確認には

crontab -e

で。
(cron系をやったことない人は何も知らずにこれをやると危険というかダメな気がするのでcronについて調べてみましょう)

というわけでhiveの処理を自動化しました。
あとはS3の内容を取得してRDS等、データベースに書き込む処理を同メソッド内に記述すればオッケー。

ここまででビッグデータの取り扱いまでの流れを書いていきました。
いずれ、得られたデータを解析するシステムについても書いていこうと思います。

ビッグデータ取り扱いまでの流れ2 解析編

今回は収集したデータをどう解析していくか書いていきます。

解析にはHadoopを利用します。

Hadoopの動作環境はAmazon EMR (Elastic MapReduce)を使います。

  1. fluentdのインストール
  2. td-loggerでアプリケーションログの吐き出し
  3. td-loggerで受け取ったログをS3に送信
  4. S3のデータをHadoopで解析
  5. Hadoopで解析したデータをRDSに突っ込む

今回は前回の続きということでS3のデータをHadoopで解析から解説します。
Hadoopの処理はSQLライクに書けるHiveを利用します。

S3のデータをHadoopで解析

先程も書きましたが、EMRを利用します。
基本的にはコマンドラインのみでやっていきます。
なのでコマンドラインツールを予めインストールしといてください。

参考図書はこちら

Hadoopファーストガイド

Hadoopファーストガイド

EMRの起動

まずはEMRの起動から
認証系の設定ファイルを書きます
.credentials.jsonをホームディレクトリに追加。内容は以下です

{
  "access-id":     'AWSのkey',
  "private-key":   'AWSのsecret-key',
  "key-pair":      '公開鍵のファイル',
  "key-pair-file": '公開鍵のファイルのパス',
  'region': 'リージョン名[ap-northeast-1(東京)]',
  "log-uri":       ''
}

第3回 Amazon Elastic MapReduce Ruby ClientでEMRを起動する:Amazon Elastic MapReduceの使い方─Hadoopより手軽にはじめる大規模計算|gihyo.jp … 技術評論社
こちらが参考になります。

起動コマンドはこちら

elastic-mapreduce --create --alive --name "クラスター名" --key-pair "キーの名前" ¥
--instance-group master --instance-type m1.small --instance-count 1 ¥
--bid-price 0.02 ¥
--instance-group core --instance-type m1.small --instance-count 2 ¥
--bid-price 0.02 ¥
--hive-interactive

これで起動が完了です。
解説すると

--create で起動
--alive でシャットダウンを手動で行う設定
--name Hadoopクラスター名を指定
--key-pair インスタンスの鍵を指定
--instance-group master 詳しくは解説しませんが、hadoopにはmaster, core, taskのインスタンスグループがあります。masterとcoreは必ず必要です。
--instance-type インスタンスのサイズなどを指定します
--instance-count そのグループのインスタンス数を指定。masterは1つ。
--bid-price スポットインスタンスの入札価格 
--hive-interactive hiveを使うためのオプション。これがないとhiveが使えません。

スポットインスタンスに関して詳しくはこちら(
Amazon EC2 スポットインスタンス - Amazon EC2 (クラウド上の仮想サーバー Amazon Elastic Compute Cloud) | アマゾン ウェブ サービス(AWS 日本語))

確認は

elastic-mapreduce --list --active

としたとき

j-[jobflow_id]     WAITING        [public DNS][クラスター名]
   COMPLETED      Setup Hive   

このように
WAITING

COMPLETED
と表示されていれば利用できます。

hiveの利用

sshでmasterノードに入り作業をします

ssh -i [公開鍵のパス] hadoop@[public DNS]

ユーザーはhadoopユーザーを利用します。

sshでログイン後

hive

と入力します。するとhiveのコンソールが表示されます。
まずはS3からデータを取り込みます。(厳密には取り込むっていい方は違うっぽい(もうちょい詳しくなりたい))
イメージ的にはテーブルを作ってそこにS3のデータを取り込む
この辺はこちらを参考にしました。
はじめてのEMR/fluentdでS3にアップロードしたログをElastic MapReduceで検索・集計する | Developers.IO

CREATE EXTERNAL TABLE IF NOT EXISTS [テーブル名] (dt string, tag string, json string)
PARTITIONED BY ( PT STRING ) 
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n'

このようなテーブルを作成します。

desc [テーブル名]

とすると

dt string
tag string
json string
pt string

このようなcolumn情報が表示されます。
前回の記事からログは

2014-03-29T00:40:11+09:00	my_app.test	{"hoge":"piyo"}

このような感じになります。
なのでイメージ的には
dt 2014-03-29T00:40:11+09:00
tag my_app.test
json {"hoge" : "piyo"}
というデータが入っていきます。

ただこの段階ではソースは指定されていません。
ソースの指定はパーティションの追加により行います。
パーティションの追加は

ALTER TABLE [テーブル名] ADD IF NOT EXISTS PARTITION (pt = '[日付情報など]') LOCATION 's3://[S3のバケット名]'

このように行います。

ここまででhiveでS3に保存したデータを取り扱うことができます。

実際にSELECT文で色々試してみましょう

select * from [テーブル名];

とすると仮にS3の内容が

2014-03-29T00:40:11+09:00	my_app.test	{"hoge":"piyo"}
2014-03-29T00:40:11+09:00	my_app.test	{"hoge":"fuga"}

だとすると
そのまま

2014-03-29T00:40:11+09:00	my_app.test	{"hoge":"piyo"}
2014-03-29T00:40:12+09:00	my_app.test	{"hoge":"fuga"}

と出てきます。
jsonが少々扱いにくいのでこのように書くとjsonの中身を利用できます。

select hoge
from [テーブル名] LATERAL VIEW json_tuple(テーブル名.json, hoge) j AS hoge

とすると

piyo
fuga

となります。
さらに条件もjsonの中身のやつを利用できます

select hoge
from [テーブル名] LATERAL VIEW json_tuple(テーブル名.json, hoge) j AS hoge
where hoge = "piyo"

とすると

piyo

のみが取り出せます。

前回のと組み合わせるとアプリケーションログを取得し、かつhiveにより利用出来るようになりました。

今回はボリュームが多くなってきたので、この辺で。
次回はこれらの処理をrubyから動作させる方法について書いていきたいと思います。

参考図書

この本は本当に参考になりました。まず最初に読むべき本かと思います。

Hadoopファーストガイド

Hadoopファーストガイド

ビッグデータ取り扱いまでの流れ1 収集編

最近ビッグデータを取り扱ってきているので、その流れを記録しようかと思います。
Ruby on Railsで構築していますが、一部以外は別の言語やフレームワークでも利用できます。

ビッグデータの定義ですが、この本の帯の「データサイズが悩みの種ならそれはもうビッグデータです」

Hadoopファーストガイド

Hadoopファーストガイド

っていうのがすごくしっくりきました。

丁度データサイズに悩み始めてきたため、ビッグデータを取り扱っているといえるでしょう。

ざっくりとした流れは

  1. fluentdのインストール
  2. td-loggerでアプリケーションログの吐き出し
  3. td-loggerで受け取ったログをS3に送信
  4. S3のデータをHadoopで解析
  5. Hadoopで解析したデータをRDSに突っ込む

というような流れとなっております。

fluentdのインストール

これはいろんなところで書いてあるのであまり深くは書きませんが、
こんな感じでインストールします。

/etc/yum.repos.d/td.repo

[treasuredata]
name=TreasureData
baseurl=http://packages.treasure-data.com/redhat/$basearch
gpgcheck=0
$ yum update
$ yum install td-agent

td-loggerでアプリケーションログの吐き出し

Gemfileにて

gem 'td-logger'

を追加しbundle install

ファイル
config/treasure_data.yml

development:
  agent: localhost:24224
  tag: アプリケーション名
  debug_mode: true  # enable debug mode

production:
  agent: localhost:24224
  tag: アプリケーション名
  debug_mode: false

# disable logging
test:

を追加

取得したい場所に

TD.event.post('[タグの名前]', ハッシュ)

するとログでは

datetime アプリケーション名.タグの名前 json

みたいな感じです。具体的に入れると

TD.event.post('test', { hoge: :piyo })

アプリケーション名をmy_appとするとログは

2014-03-29T00:40:11+09:00	my_app.test	{"hoge":"piyo"}

みたいな感じになります。

td-loggerで受け取ったログをS3に送信

次は

2014-03-29T00:40:11+09:00	my_app.test	{"hoge":"piyo"}

こちらのログをS3に入れます。

設定ファイルに次の設定を追加します
/etc/td-agent/td-agent.conf

<match my_app.event>
  type s3
  aws_key_id AWSのキー
  aws_sec_key AWSのシークレットキー
  s3_bucket バケット名
  s3_endpoint S3のリージョン.amazonaws.com
  s3_object_key_format %{path}%{time_slice}_%{index}_%{hostname}.%{file_extension}
  path events/
  buffer_path /var/log/fluentd/events_s3
  time_slice_format %Y-%m-%d/%H
  time_slice_wait 10m 
</match>

これでオッケー。
あとはしばらく動かして、バケットの中身を見ると、gzip形式のファイルがどんどん溜まっていきます。
それをhadoopで処理します。

動いてないと思ったら

tail -f /var/log/td-agent/td-agent

などでログを見て行きましょう。

というわけで今回はここまで。
次回はhadoopで処理する方法を書いていきます。

参考記事

fluentd+rails+mongoでサクッとログ環境を整備してみる - dev.log

データサイエンティスト養成読本 [ビッグデータ時代のビジネスを支えるデータ分析力が身につく! ] (Software Design plus)

データサイエンティスト養成読本 [ビッグデータ時代のビジネスを支えるデータ分析力が身につく! ] (Software Design plus)