サナギわさわさ.json

サナギさんとキルミーベイベーとプログラミングが好きです

CentOS6.6にApache Zeppelinを入れてチュートリアルをやる

明けましておめでとうございます。山田哲人が野球盤でチェンジアップを上手く拾ってヒットにしていたので今年も良い一年になりそうです。

今回はApache Zeppelinを試してみようと思います。
http://zeppelin-project.org/

Apache Zeppelinについて

  • Apache Sparkのインタラクティブ環境でiPython Notebook的なアレ
  • 組み込みで最初からSparkが入っているのが嬉しい
  • 外部のSparkとも接続できるし、Amazon EMRに乗せる事もできる

依存関係のインストール

基本的には公式の設定そのままですが、Mavenでビルドを行う際にJavaSSL接続でクラッシュしたのでNSSを最新に更新してあります。

参考:Troubleshooting story - Java HTTP client crashes on connections | BackSlasher

yum install fontconfig-devel.x86_64
yum install java-1.7.0-openjdk-devel
yum install npm
yum install wget
yum install nss

#mavenのインストール
cd /opt
wget http://www.eu.apache.org/dist/maven/maven-3/3.3.3/binaries/apache-maven-3.3.3-bin.tar.gz
sudo tar -zxf apache-maven-3.3.3-bin.tar.gz -C /usr/local/
sudo ln -s /usr/local/apache-maven-3.3.3/bin/mvn /usr/local/bin/mvn

インストールできたか確認

java -version
node --version
mvn -version 

ビルド

ここではSpark1.5系、Hadoop2.4系の基本構成でビルドを行います。CDHやMapReduceを使いたい場合などはhttps://github.com/apache/incubator-zeppelinを参考にしてください。

git clone https://github.com/apache/incubator-zeppelin
cd incubator-zeppelin/
mvn clean package -Pspark-1.5 -Phadoop-2.4 -Pyarn -Ppyspark #結構時間かかる

起動

./bin/zeppelin-daemon.sh start

localhost:8080にアクセスしてトップページが見れる事を確認

f:id:kakakazuma:20160106225039p:plain

チュートリアル

公式のTutorialをやってみます。

Tutorial

ここからはほぼ

Zeppelin Notebook Tutorial Walkthrough - Make Data Useful

と同じ内容です。ただ後述しますが1つだけ注意点があります。

データの準備

import sys.process._
"wget http://archive.ics.uci.edu/ml/machine-learning-databases/00222/bank.zip" !
"mkdir data" !
"unzip bank.zip -d data" !
"rm bank.zip" !

実行してエラーが出ない事を確認 f:id:kakakazuma:20160106225859p:plain

データ読み込み

import sys.process._

val zeppelinHome = ("pwd" !!).replace("\n","")
val bankText = sc.textFile(s"$zeppelinHome/data/bank-full.csv")
case class Bank(age:Integer, job:String, marital : String, education : String, balance : Integer)

val bank = bankText.map(s=>s.split(";")).filter(s=>s(0)!="\"age\"").map(
    s=>Bank(s(0).toInt, 
            s(1).replaceAll("\"", ""),
            s(2).replaceAll("\"", ""),
            s(3).replaceAll("\"", ""),
            s(5).replaceAll("\"", "").toInt
        )
).toDF()
bank.registerTempTable("bank")

注意!!

http://www.makedatauseful.com/zeppelin-notebook-tutorial-walkthrough/
の通りに

val sqlCon = new org.apache.spark.sql.SQLContext(sc) 

を含んだコードを実行すると、登録したテーブルが別のパラグラフから読み込めなくなるバグが発生するようです。バグが発生した場合は対象行を削除して

./bin/zeppelin-daemon.sh restart

で再起動してからコードを再実行してください。

参考:apache spark - Zeppelin and SqlContext - Stack Overflow

f:id:kakakazuma:20160106225907p:plain

データの可視化

%sql 
select age, count(1) value 
from bank 
where age < 30 
group by age 
order by age

棒グラフや円グラフなど様々な可視化ができます。 f:id:kakakazuma:20160106225541p:plain

終わり

以上です。簡単に終わると思ったらJavaSSL接続クラッシュとかSQLContextとかで結構はまりました。インタラクティブ環境があるとモチベーションが上がるので、これでSparkの勉強が進む事を願っています。

PlayのFormバリデーションをネストされたパラメータに適用する

PlayのFormでバリデーションするのは楽です。
ネストされたパラメータに適用する際は、頭に@Validをつける必要があります。

Validation Constraints with nested objects in play ...

以上です。来年こそScalaでPlay書きたい...

Amazon ElastiCacheのchunk_sizeとEvictionではまった件

今更ですが今シーズンはヤクルトが優勝したので嬉しいです。記念に人の画像を全部畠山っぽくしてくれるフィルタを作りたいところです。

Unused MemoryがいっぱいなのにEvictions発生

本題です。この前Amazon ElastiCache(Memcached)にバッチでデータをロードしていたのですが、Unused Memoryがまた10GB近く残っているのにEvictionsが発生し始めました。

f:id:kakakazuma:20151215101956p:plain f:id:kakakazuma:20151215102046p:plain

そもそもMemcachedについての知識が無かったので色々調べてみたところ、良さげなサイトが見つかりました。

Cloud, Big Data and Mobile: Part 5: Understanding Amazon ElastiCache Internals: Memory Allocation and Eviction

ElastiCacheのメモリ挙動

詳しくは上に挙げたサイトを読んでください。簡単にまとめると、以下のようになります。

  • ElastiCacheのメモリは1MBのページングされたメモリの集合である
  • 1MBのページングされたメモリの中にはchunkが格納され、chunkのサイズは同一ページの中では全て同じになる
  • 格納可能なchunkのサイズのリストは、chunkの最小値に対して係数(growth factor)をかけていき1MBになったらストップ、という形式で用意される
  • アイテムをElastiCacheに格納する際に使われるchunkは、用意されたchunkのサイズのリストの中で格納するアイテムのサイズに最も近いchunkである
  • 格納されるchunkのサイズと、実際のアイテムのサイズの差はメモリの無駄使いとなる

MemCached界ではたぶん常識ですね、すみませんでした。

ElastiCacheの設定値

上で挙げたメモリ挙動を踏まえると重要な設定値となるのが

  • chunkの最小値
  • chunkのリストを作るときに掛ける係数(growth factor)

なわけですが、ElastiCacheではそれぞれ

  • chunk_size
  • chunk_size_growth_factor

という名前になっています。

参考: https://docs.aws.amazon.com/ja_jp/AmazonElastiCache/latest/UserGuide/ParameterGroups.Memcached.html

というわけで確認してみたところ、 chunk_sizeが1024バイトになっている!!! ※初期値は48バイトです

f:id:kakakazuma:20151215102306p:plain

今回投入していたデータはせいぜい100バイトぐらいなので、投入データ1件につき900バイトぐらいの無駄が発生していた事になります。恐ろしい...

解決編

というわけでchunk_sizeの設定を初期値の48バイトに修正し再度データを投入してみたところ、Evictionsは発生しなくなりました。

f:id:kakakazuma:20151215102443p:plainf:id:kakakazuma:20151215102452p:plain

さすがにここまで極端な例は無いかと思いますが、投入するアイテムのサイズが分かりきっているときはchunk_sizechunk_size_growth_factorの設定を変更すればより効率的にメモリが活用できるかもしれません。