焼肉が食べたい

ただの日記です。技術的に学んだことも書こうと思っていますが、あくまで自分用メモです。

PyConJP 2017に登壇してきた

ずっと放置していたブログを、久しぶりに書く。
PyConJP 2017に初参加・初登壇してきた。
ちなみにTalk内容はこれ。

pycon.jp

登壇資料はこれ。

speakerdeck.com

はてブ数337ブックマークついた。ホットエントリー入りした。 今回のPyConJPの資料の中では一番はてブはついたんじゃないかと思う。

ちなみに開催前に座談会のオファーを頂き、
CodeZineデビューもしました。

news.infoseek.co.jp

発表の振り返り

スライドの内容について

  • 発表内容がありきたりな技術説明が多くなってしまったと思う
    PyConという場は初参加だったが、Sparkのようなビッグデータ領域の技術に興味がある、使ったことがある人はそれほど多くないかな、と予想した。
    なので、「Sparkのいろは」的なところから説明するような発表内容にした。
    結果的に、Toggetterの反応を見る限り、狙ったとおり、Spark使ったことがないというユーザにある程度興味をもってもらうことには成功したように思う。

togetter.com

ただ、一部のSparkをガンガン使っている人にとっては、前半部分特に知ってる内容でつまらなかったんじゃないかと反省。
いろんなレベルの人に満足してもらえる発表は難しい。。

テーマについて

本当は、発表に盛り込みたい内容として、もう一つあった。
それは、「入社して2ヶ月で月間3000万UUを支える分析基盤をほとんど一人で作った話」。

今回PyConにCfPだしたのは、この件でSparkを使ったからだった。
わりと、ここのはなしもつらみとか工夫とかいろいろあって、その話もしたかったけど、
Pythonとの関連性が低かったから入れなかった。
どこかで昇華させたい。笑

登壇準備とか当日の流れとか

  • 仕事がいろいろあった+体調崩してて、発表前日の夜にあわててスライドとデモ作った。
    発表練習も1度もできないままの登壇になった。
    もう少し前からちゃんと準備して発表練習すればよかった。
  • アクシデントでパワーポイントが使えなかった。事前にspeaker deckに登壇資料あげていたので、とりあえずそれでできたけど、
    今何分経ったかもわからない状態でしゃべることになったが、その割にだいたい時間どおりに話せたのは奇跡だった。
    今度からPCは2台持ちにしよう。

登壇の感想

  • 登壇のあと、質問をしてくれる人が何人かいた。昼食の時間を削ってまで熱心に質問してくれるのはとても嬉しかった。
  • スピーカーTシャツを着ていたためか、懇親会でも話しかけてもらえた。自分から話しかけるのが苦手なので、とてもありがたかった。
    わたしはPython自体にとても詳しいわけではないので、むしろ教えていただく事が多く、本当に貴重な機会だったと思う。

全体の雰囲気とか

  • とにかく人が多かった。
  • 昼はもちろん、早めに行くと朝弁当も出る。懇親会のごはんも美味しかった。
  • やってみた系の話から機械学習などの特定技術の深い話や事例の話まで、非常に幅広かった。
    Python自体にそこまでこだわらなくてもいいっぽい?

自分が聞いたセッションで面白かったものいくつか

  • 1日目は質疑応答の対応とかいろいろで、セッションきけなかったので、2日目のみ。。

基調講演: Pandasコアコミッターが語る 今日から誰でも始められるOSS活動のススメ

OSS活動の生の話が聞けてよかった。
OSSコミュニティに限らずチーム開発を行う上でのヒントになりそうな内容がたくさんあった。

speakerdeck.com

Running Dask in the Cloud

PySparkと違ってpure Pythonで動く並列分散処理フレームワーク daskの説明。
PySparkと比べたときのメリットとして、複雑な分散コンピューテーションが可能とのこと。
どういうことかあとで調べる。

Geospatial data analysis and visualization in Python

geopandasなどを使った対話的な地理データを使った分析とビジュアライゼーション。
食べログデータを使っているとのこと。
デモが分かりやすかった。

SREエンジニアがJupyter+BigQueryでデータ分析基盤をDev&Opsする話

ちょっと疲れたのでyoutubeで聞いてた。
ここ3ヶ月の私と同じ課題と立ち向かっていそうなのでこの人と会話してみたかった。

speakerdeck.com

さいごに

こんな大きなイベントを企画遂行している運営の方はすごい。
ありがとうございました。
参加者の方々も、皆様お疲れ様でした。

EMRのスレーブノード(コアノード)にSSHアクセスする

EMRでは、セキュリティオプションでEC2キーペアを選べば、 そのキーペアを使用してマスターノードにはSSHアクセスできますが、スレーブノードにアクセスしたいときはどうすればよいのでしょうか。

SSHエージェントを使うことで、スレーブノードへのアクセスもできるようになります。 コマンドは以下の通り。

localhost$ ssh-add ~/.ssh/keypair.pem
localhost$ ssh -i ~/.ssh/keypair.pem -A hadoop@emr-master
emr-master$ hadoop dfsadmin -report |grep ^Name |cut -f2 -d: |cut -f2 -d' '
10.187.XX.XX <- slaveのIPアドレス
10.167.YY.YY
emr-master$ ssh hadoop@10.187.XX.XX

Scala/Sparkプログラミングをjupyter+brunelで快適に♫

Scala/Sparkだいすきですが、今度働くことになる会社はPython文化。
Scalaだって、Jupyter Notebook使えるし、matplotlibみたいに、ビジュアライゼーションできるよ!ということをアピールしたい、というのがモチベーションです。

ScalaをJupyterで使うために

Jupyter NotebookはもともとPythonの開発用にiPython Notebookとして開発されていましたが、
最近はカーネルさえインストールすれば、BashでもRubyでも、なんでも動くようになっていますね。
ということで、今回はScala/Sparkが動くカーネルを入れて動かしてみます。
Scalaを動かすためのカーネルとしては、Apache Toreeを使います。
Toree以外にもJupyter Notebook用Scalaカーネルとしては以下もありますが、開発が活発そうなのと、Apache Incubatorプロジェクトになっているので、
Toreeを選びました。
* IScala
* ISpark
* jupyter-scala

Brunelとは

PythonでいうMatplotlibのようなビジュアライゼーションライブラリとして、Scalaでは、Brunelが使えます。
ちなみにBrunelはScala以外にもPythonとRでも使えます。
結構おしゃれなグラフが色々かけて楽しそうです。

github.com

インストール手順

Toreeをインストールして、Jupyter Notebookを起動してみます。
手順は簡単。

pip install https://dist.apache.org/repos/dist/dev/incubator/toree/0.2.0/snapshots/dev1/toree-pip/toree-0.2.0.dev1.tar.gz
jupyter toree install --spark_home=/path/to/spark
jupyter notebook

早速試してみる

val ds = spark.read.option("header","true").csv("/Users/chiehayashida/work/tmp/test.csv")
ds.show()
//+----+----+
//|col1|col2|
//+----+----+
//|   1|   1|
//|   2|   2|
//|   3|   1|
//|   4|   5|
//|   5|   2|
//+----+----+

// Brunelパッケージをダウンロード・インクルードする。
%AddJar -magic https://brunelvis.org/jar/spark-kernel-brunel-all-2.4.jar 

// brunelで描画するために%%brunelを入れる
%%brunel
data('ds') bar x(col1) y(col2:reverse) label(col2) legends(all) title("test")

f:id:chie8842:20170417002240p:plain

気づいたこと

  • Brunelの対応するSparkバージョン Brunelでは現在Spark2.1以上には対応していないようで、
    以下のエラーが出てしまう。
%%brunel
data('ds') x(a) y(b)
// エラー内容
//Magic brunel failed to execute with error: 
//org/apache/spark/sql/DataFrame
  • 軸名の編集ができない Brunelで色々いじってみたけれど、X軸・Y軸の名前の編集ができなそう。

dein.vimを使ってvimのプラグイン管理をする

dein.vimは、vimプラグイン管理ツールの一つ。 今までNeoBundleというプラグイン管理ツールが主流だったが、最近はdein.vimを使う人も多いらしい。

dein.vimのインストール

$ mkdir -p ~/.vim/dein/repos/github.com/Shougo/dein.vim
$ git clone https://github.com/Shougo/dein.vim.git \
    ~/.vim/dein/repos/github.com/Shougo/dein.vim

.vimrcを含む自分カスタマイズの環境設定ファイルをGitHub上においているので、これをクローンして、.vimrcを配置する

git clone https://github.com/chie8842/configs.git
configs/files/vimrc ~/.vimrc

vimを立ち上げると設定ファイルに書かれていてまだインストールされていないプラグインをインストールしはじめる。

$ vim
[dein] Not installed plugins: ['neosnippet', 'vimproc.vim', 'neomru.vim', 'vim-monokai', 'neocomplete.vim', 'nerdtree']
[dein] Update started: (2017/03/27 17:14:48)

Python3.5.3+conda+Jupyter Notebookでpyarrow(apache arrow)を使えるようにする

pythonのライブラリには、apache Arrowではない、arrowという日付や時刻に関する処理を行うライブラリもあるので注意。

ドキュメントでは、pipでインストールできると書いてあるのに、 pipではそんなパッケージはないと怒られた。

chie8842@chie-no-ubuntu:~/work/tensorflow$ pip install pyarrow
Collecting pyarrow
  Could not find a version that satisfies the requirement pyarrow (from versions: )
No matching distribution found for pyarrow

JIRAを見ると、pipはarrow0.2では使えなくて、次のバージョンから対応する予定らしい。
https://issues.apache.org/jira/browse/ARROW-240

仕方ないのでconda環境構築。
※3/8現在、pyarrowの対象バージョンは、2.7,3.4,3.5のみ。
最新のanaconda3-4.3.0はpython3.6ベースなので、
python3.5.2ベースのanaconda3-4.2.0を入れる。

chie8842@chie-no-ubuntu:~/work/tensorflow$  pyenv install anaconda3-4.2.0
chie8842@chie-no-ubuntu:~/work/tensorflow$ pyenv local anaconda3-4.2.0
chie8842@chie-no-ubuntu:~/work/tensorflow$ python --version
Python 3.5.2 :: Anaconda 4.2.0 (64-bit)

## 上記でpythonバージョンが切り替わっていない場合は、以下を実施して環境を更新する
chie8842@chie-no-ubuntu:~/work/tensorflow$ pyenv rehash


chie8842@chie-no-ubuntu:~/work/tensorflow$ conda create -n py3.5.3-conda4.2.0 python=3.5.3 anaconda
chie8842@chie-no-ubuntu:~/work/tensorflow$ source ~/.pyenv/versions/anaconda3-4.2.0/bin/activate py3.5.3-conda4.2.0
(py3.5.3-conda4.2.0) chie8842@chie-no-ubuntu:~/work/tensorflow$ conda info -e
# conda environments:
#
py3.5.3-conda4.2.0    *  /home/chie8842/.pyenv/versions/anaconda3-4.2.0/envs/py3.5.3-conda4.2.0
root                     /home/chie8842/.pyenv/versions/anaconda3-4.2.0

(py3.5.3-conda4.2.0) chie8842@chie-no-ubuntu:~/work/tensorflow$ conda update conda
(py3.5.3-conda4.2.0) chie8842@chie-no-ubuntu:~/work/tensorflow$ conda install -c conda-forge pyarrow

ついでにほかのライブラリもインストールしておく。

(py3.5.3-conda4.2.0) chie8842@chie-no-ubuntu:~/work/tensorflow$ conda install matplotlib seaborn scikit-learn

インストールされているライブラリ一覧を見る

(py3.5.3-conda4.2.0) chie8842@chie-no-ubuntu:~/work/tensorflow$ conda list (-n environment_name)

jupyter notebookを立ち上げる

jupyter notebook

これだとpyarrowが使えなかった。。。
py3.5.3-conda4.2.0をdeactivateして、condaのrootにpyarrowをインストールして、jupyter notebookを再起動すると、使えるようになってた。

docker インストールとTensorflowコンテナの起動

Dockerのインストール・設定とTensorflowコンテナを起動した時の手順。
Dockerインストール手順はちょくちょく変わっているようなので、最新の情報は公式ドキュメントを参照すること。

公式ドキュメントでのUbuntuへのDockerインストール手順
Get Docker for Ubuntu - Docker Documentation

Dockerインストール

sudo apt-get update
# …
# Reading package lists... Done

sudo apt-get -y install \
linux-image-extra-$(uname -r) \
linux-image-extra-virtual
# …
# Setting up linux-image-generic (4.4.0.66.70) ...
# Setting up linux-image-extra-virtual (4.4.0.66.70) ...
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# [sudo] password for chie8842:
# OK
sudo apt-key fingerprint 0EBFCD88
# pub   4096R/0EBFCD88 2017-02-22
#       Key fingerprint = 9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88 <- 公式ドキュメント(https://docs.docker.com/engine/installation/linux/ubuntu/#install-using-the-repository)に載っているフィンガープリントと一致しているか確認すること。
uid                  Docker Release (CE deb) <docker@docker.com>
# sub   4096R/F273FCD8 2017-02-22

sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"

sudo apt-get update
# …
# Reading package lists... Done
sudo apt-get install docker-ce
apt-cache madison docker-ce
#  docker-ce | 17.03.0~ce-0~ubuntu-xenial | https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages
sudo docker run hello-world
# Unable to find image 'hello-world:latest' locally
# latest: Pulling from library/hello-world
# 78445dd45222: Pull complete
# BDigest: sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7
# Status: Downloaded newer image for hello-world:latest

# Hello from Docker!
# This message shows that your installation appears to be working correctly.

# To generate this message, Docker took the following steps:
#  1. The Docker client contacted the Docker daemon.
#  2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
#  3. The Docker daemon created a new container from that image which runs the
#     executable that produces the output you are currently reading.
#  4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

# To try something more ambitious, you can run an Ubuntu container with:
#  $ docker run -it ubuntu bash

# Share images, automate workflows, and more with a free Docker ID:
#  https://cloud.docker.com/

# For more examples and ideas, visit:
#  https://docs.docker.com/engine/userguide/

インストール後の設定

現在のユーザでDockerを実行できるように権限付与する

sudo groupadd docker
# groupadd: group 'docker' already exists
sudo usermod -aG docker $USER
docker run -it ubuntu bash
# docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.26/containers/create: dial unix /var/run/docker.sock: connect: permission denied.

# 公式ドキュメントの通りだと、ここでdocker run に成功するはずだが、
# 上記のように失敗する。OS再起動したらうまくいくようになった。
sudo shutdown -r now
docker run -it ubuntu bash
# Hello from Docker!
# This message shows that your installation appears to be working correctly.

# To generate this message, Docker took the following steps:
#  1. The Docker client contacted the Docker daemon.
#  2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
#  3. The Docker daemon created a new container from that image which runs the
#     executable that produces the output you are currently reading.
#  4. The Docker daemon streamed that output to the Docker client, which sent it
#     to your terminal.

# To try something more ambitious, you can run an Ubuntu container with:
#  $ docker run -it ubuntu bash

# Share images, automate workflows, and more with a free Docker ID:
#  https://cloud.docker.com/

# For more examples and ideas, visit:
#  https://docs.docker.com/engine/userguide/

Dockerサービスの起動と自動起動の設定

sudo systemctl enable docker
# [sudo] password for chie8842:
# Synchronizing state of docker.service with SysV init with /lib/systemd/systemd-sysv-install...
# Executing /lib/systemd/systemd-sysv-install enable docker

sysv-rc-conf --list |grep docker
# docker       0:off      1:off   2:on    3:on    4:on    5:on    6:off
# 自動起動がONになっていない場合は、自動起動をONにする。
sudo sysv-rc-conf docker on

Tensorflowコンテナの起動

docker run -it -p 8888:8888 gcr.io/tensorflow/tensorflow # 初回はDockerイメージのダウンロードが行われるので時間がかかる
# …
#     Copy/paste this URL into your browser when you connect for the first time,
#     to login with a token:
#         http://localhost:8888/?token=******* <-このURLでブラウザを開くと、Jupyter Notebookにアクセスできる。 

開いたJupyter Notebookのキャプチャ

デフォルトでGetting StartedやMNistなどのサンプルのノートブックが入っている。

f:id:chie8842:20170327174654p:plainf:id:chie8842:20170327174658p:plainf:id:chie8842:20170327174702p:plainf:id:chie8842:20170327174705p:plain

起動スクリプトrc.localがFailする場合の対処

/etc/rc.localスクリプトで共有ディレクトリのマウント処理を行うようにしていたのだけれど、 なぜかわからないけれど、dockerを入れた後に、再起動してもマウントされなくなっていた。

source /etc/rc.local

とすると、きちんとマウントされる。 rc.localのサービスステータスを確認すると、以下のようになっていた。

chie8842@chie-no-ubuntu:~$ sudo systemctl start rc-local
● rc-local.service - /etc/rc.local Compatibility
   Loaded: loaded (/lib/systemd/system/rc-local.service; static; vendor preset: enabled)
  Drop-In: /lib/systemd/system/rc-local.service.d
           └─debian.conf
   Active: failed (Result: exit-code) since 月 2017-03-27 14:22:15 JST; 2min 1s ago
  Process: 897 ExecStart=/etc/rc.local start (code=exited, status=32)

 3月 27 14:22:15 chie-no-ubuntu systemd[1]: Starting /etc/rc.local Compatibility...
 3月 27 14:22:15 chie-no-ubuntu rc.local[897]: mount: mount //169.254.173.204/share on /home/chie8842/share f
 3月 27 14:22:15 chie-no-ubuntu systemd[1]: rc-local.service: Control process exited, code=exited status=32
 3月 27 14:22:15 chie-no-ubuntu systemd[1]: Failed to start /etc/rc.local Compatibility.
 3月 27 14:22:15 chie-no-ubuntu systemd[1]: rc-local.service: Unit entered failed state.
 3月 27 14:22:15 chie-no-ubuntu systemd[1]: rc-local.service: Failed with result 'exit-code'.
...skipping...
● rc-local.service - /etc/rc.local Compatibility
   Loaded: loaded (/lib/systemd/system/rc-local.service; static; vendor preset: enabled)
  Drop-In: /lib/systemd/system/rc-local.service.d
           └─debian.conf
   Active: failed (Result: exit-code) since 月 2017-03-27 14:22:15 JST; 2min 1s ago
  Process: 897 ExecStart=/etc/rc.local start (code=exited, status=32)

 3月 27 14:22:15 chie-no-ubuntu systemd[1]: Starting /etc/rc.local Compatibility...
 3月 27 14:22:15 chie-no-ubuntu rc.local[897]: mount: mount //169.254.173.204/share on /home/chie8842/share f
 3月 27 14:22:15 chie-no-ubuntu systemd[1]: rc-local.service: Control process exited, code=exited status=32
 3月 27 14:22:15 chie-no-ubuntu systemd[1]: Failed to start /etc/rc.local Compatibility.
 3月 27 14:22:15 chie-no-ubuntu systemd[1]: rc-local.service: Unit entered failed state.
 3月 27 14:22:15 chie-no-ubuntu systemd[1]: rc-local.service: Failed with result 'exit-code'.

手動で起動しようとしても失敗する。

chie8842@chie-no-ubuntu:~$ sudo systemctl start rc-local
Job for rc-local.service failed because the control process exited with erro                                r code. See "systemctl status rc-local.service" and "journalctl -xe" for det                                ails.

標準出力にあるコマンドを実行してみるが、原因はわからず。

chie8842@chie-no-ubuntu:~$ sudo systemctl start rc-local.service
Job for rc-local.service failed because the control process exited with erro                                r code. See "systemctl status rc-local.service" and "journalctl -xe" for det                                ails.
chie8842@chie-no-ubuntu:~$ journalctl -xe
 3月 27 14:10:21 chie-no-ubuntu systemd[1]: Time has been changed
-- Subject: Time change
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- The system clock has been changed to REALTIME microseconds after January
 3月 27 14:10:21 chie-no-ubuntu systemd[1]: snapd.refresh.timer: Adding 1h 5                                1
 3月 27 14:10:21 chie-no-ubuntu systemd[1]: snapd.refresh.timer: Adding 5h 3                                3
 3月 27 14:10:21 chie-no-ubuntu systemd[1]: apt-daily.timer: Adding 6h 51min                                
 3月 27 14:10:21 chie-no-ubuntu systemd[1080]: Time has been changed
-- Subject: Time change
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- The system clock has been changed to REALTIME microseconds after January
 3月 27 14:10:21 chie-no-ubuntu systemd[1695]: Time has been changed
-- Subject: Time change
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- The system clock has been changed to REALTIME microseconds after January

最終的に、起動スクリプトの最初にsleepを入れるとうまくいった。

sleep 10
mount -t cifs …
exit 0