garbagetown

個人の日記です

Docker と Redis と Spring

TL; DR

  • 職場のウインドーズでも spring-boot したい
    • spring-security したい
    • spring-session したい
  • ウインドーズに redis を入れる気はないので docker で入れる
    • docker-machine 便利

Docker Toolbox

下記 URL を参考に Docker Toolbox をインストールする。インストーラをダウンロードしてデフォルトのまま Enter を連打すればいい。

Docker

公式ドキュメントのメンテナンスが追い付いていないようで、書いてある通りにやってもうまくいかない、と言うかそもそも書いてある通りに実行できないので、勘と経験と度胸で進める。

まずは docker ホストを作る。ウインドーズはネイティブで docker ホストを実行できないので、Docker Toolbox に含まれる VirtualBox 上に docker ホストを立てる。この作業を簡単にしてくれるのが docker-machine コマンドで、例えば dev という名前の docker ホストは次のようにして作る。

c:\TEMP>docker-machine create --driver virtualbox dev
Running pre-create checks...
(dev) Default Boot2Docker ISO is out-of-date, downloading the latest release...
(dev) Latest release for github.com/boot2docker/boot2docker is v1.9.1
(dev) Downloading C:\Users\yu-umezawa\.docker\machine\cache\boot2docker.iso from https://github.com/boot2docker/boot2doc
ker/releases/download/v1.9.1/boot2docker.iso...
(dev) 0%....10%....20%....30%....40%....50%....60%....70%....80%....90%....100%
Creating machine...
(dev) Copying C:\Users\yu-umezawa\.docker\machine\cache\boot2docker.iso to C:\Users\yu-umezawa\.docker\machine\machines\
dev\boot2docker.iso...
(dev) Creating VirtualBox VM...
(dev) Creating SSH key...
(dev) Starting VM...
Waiting for machine to be running, this may take a few minutes...
Machine is running, waiting for SSH to be available...
Detecting operating system of created instance...
Detecting the provisioner...
Provisioning with boot2docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect Docker to this machine, run: docker-machine env dev

docker-machine ls で docker ホストを一覧できる。

c:\TEMP>docker-machine ls
NAME   ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER   ERRORS
dev    -        virtualbox   Running   tcp://192.168.99.100:2376           v1.9.1

作成した docker ホストに対して docker コマンドを実行するために、docker コマンドが参照する環境変数に docker ホストの情報を設定する。docker-machine env コマンドで設定すべき環境変数を確認できるので、出力された通りに設定する。

c:\TEMP>docker-machine env --shell cmd dev
SET DOCKER_TLS_VERIFY=1
SET DOCKER_HOST=tcp://192.168.99.100:2376
SET DOCKER_CERT_PATH=C:\Users\yu-umezawa\.docker\machine\machines\dev
SET DOCKER_MACHINE_NAME=dev
REM Run this command to configure your shell:
REM     FOR /f "tokens=*" %i IN ('docker-machine env --shell cmd dev') DO %i

c:\TEMP>SET DOCKER_TLS_VERIFY=1
c:\TEMP>SET DOCKER_HOST=tcp://192.168.99.100:2376
c:\TEMP>SET DOCKER_CERT_PATH=C:\Users\yu-umezawa\.docker\machine\machines\dev
c:\TEMP>SET DOCKER_MACHINE_NAME=dev

お約束の Hello World が正常に実行できることを確認する。

c:\TEMP>docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world

b901d36b6f2f: Pull complete
0a6ba66e537a: Pull complete
Digest: sha256:8be990ef2aeb16dbcb9271ddfe2610fa6658d13f6dfb8bc72074cc1ca36966a7
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 Hub account:
 https://hub.docker.com

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

Redis

docker の準備が整ったので、docker ホスト上で redis を実行するコンテナを起動する。指定しているオプションの詳細は下記の通り。

  • --name でコンテナに任意の名前を付ける
  • -d でデーモンとして起動する
  • -p で docker ホストの 6379 番ポートに対するアクセスを redis コンテナの同じく 6379 番ポートにフォワードする
c:\TEMP>docker run --name redis -d -p 6379:6379 redis
Unable to find image 'redis:latest' locally
latest: Pulling from library/redis

9ee13ca3b908: Pull complete
23cb15b0fcec: Pull complete
52a374d9c478: Pull complete
(snip)
Digest: sha256:7dfb86a89af97d915fbde39a91c87a0bf55d76f9fc979b89bfa05a5671f851c2
Status: Downloaded newer image for redis:latest
4101734092f09f3057433e02fdef26306c6ab501d602be2b7efc793f0ec48815

docker ps で docker コンテナを一覧できる。

c:\TEMP>docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
4101734092f0        redis               "/entrypoint.sh redis"   6 seconds ago       Up 5 seconds        0.0.0.0:6379->6379/tcp   redis

Spring

web, security, session, redis を追加した Spring Boot アプリケーションを作る。急にコマンドプロンプトではなく cygwin で作業しているが気にしない。

$ mkdir test && cd $_

$ curl https://start.spring.io/starter.tgz -d style=web -d style=security -d style=session -d style=redis -d name=test | tar -zxvf -
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 49996  100 49936  100    60  38051     45  0:00:01  0:00:01 --:--:-- 42318
mvnw
.mvn/
.mvn/wrapper/
src/
src/main/
src/main/java/
src/main/java/com/
src/main/java/com/example/
src/main/resources/
src/main/resources/static/
src/main/resources/templates/
src/test/
src/test/java/
src/test/java/com/
src/test/java/com/example/
.mvn/wrapper/maven-wrapper.jar
.mvn/wrapper/maven-wrapper.properties
mvnw.cmd
pom.xml
src/main/java/com/example/TestApplication.java
src/main/resources/application.properties
src/test/java/com/example/TestApplicationTests.java

TestApplication にいろいろ追加してセッション情報を Redis で管理する Web アプリケーションにする。

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
@EnableRedisHttpSession
public class TestApplication extends WebSecurityConfigurerAdapter {

    @RequestMapping("/")
    public String index() {
        return "Hello, Spring Boot!";
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic().and().authorizeRequests().anyRequest().authenticated();
    }

    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }
}

application.properties にデフォルトパスワードと docker ホストのアドレスを設定する。

security.user.password=password
spring.redis.host=192.168.99.100

アプリケーションが正常に起動することを確認する。Redis に繋がらないと起動時点で例外が発生してコケる。何度もコケた。

$ mvn spring-boot:run
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building test 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
(snip)
[INFO] --- spring-boot-maven-plugin:1.3.1.RELEASE:run (default-cli) @ demo ---

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.3.1.RELEASE)
(snip)
2016-01-05 15:58:15.195  INFO 7440 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2016-01-05 15:58:15.201  INFO 7440 --- [           main] com.example.TestApplication              : Started TestApplication in 2.838 seconds (JVM running for 5.199)

localhost:8080 にアクセスすると spring-security の機能で Basic 認証ダイアログが表示されるので、ユーザ名に user を、パスワードに application.properties に指定した password を入力する。

これでセッション情報が Redis に書き込まれるので、docker exec コマンドで redis コンテナに入って確認する。また急にコマンドプロンプトで作業しているが気にしない。

c:\TEMP>docker exec -it redis bash
root@4101734092f0:/data# redis-cli

127.0.0.1:6379> keys *
1) "spring:session:expirations:1451979000000"
2) "spring:session:sessions:25c0619f-1dbf-422e-bd8e-85c9650f1073"
3) "spring:session:sessions:e27ff8dc-a3cf-4bc6-9093-b506600cc3bb"

セッション情報が二つあるのは、未認証状態で favicon を取得した時のものと、認証後にアクセスした時のものっぽい。ひとまずここまででやりたいことは大体できた。

2016/01/20 修正。セッション情報が二つあるのは、セッション偽装対策のために認証前後で JSESSIONID が変わるためだった。

おまけ

flushdb で redis 上のデータを削除することができる。

127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> keys *
(empty list or set)

MNP 備忘録

TL;DR

  • softbank から auMNP した
  • 月々の携帯電話料金が約 5,800 円から、一年目は約 1,800 円、二年目は約 2,800 円になった
  • iPhone 4S から iPhone 6S に機種変更した
  • 持つべきものは情強友人 a.k.a. MNP 乞食

動機

未来を生きるために Hulu か Netflix を契約したいけど家庭内稟議を通すために費用を捻出する必要があるので携帯電話料金を節約したいとツイートしたところ、こういう話が大好物の友人たちからざくざく情報が集まり MNP を検討することに。

計画

自分が softbank で妻が docomo で自宅の回線は B フレッツに Nifty という体たらくだったので、

  • 二台同時に auMNP
  • iPhone 6 以降と Android
  • 本体一括ゼロ円
  • 高額キャッシュバック
  • au ひかりにしてスマートバリュー適用

と方針を定めて twitter#MNP #au #一括0円 などと検索していたら良さそうな情報を発見。この手のツイートはすぐに消えるので画像添付。

f:id:garbagetown:20151228104554p:plain

特典と条件の意味がよく分からなかったので電凸確認したところ

  • キャッシュバックの内訳は以下のとおり。
    • 56,000 円を口座振込
      • 自分は下取り端末が iPhone 4S 16GB なので 8,000 円減額で 48,000 円
    • 3,000 円 x 2 をプリベイド au wallet カードにチャージ
  • かえる割スーパーは以下から選択可能。自分は前者を選択
    • 1,000 円 x 12 ヶ月 x 2 台を月々の支払いから減額
    • au wallet に 12,000 円ずつチャージ
  • au オプションは以下すべて 30 日間無料、月を跨げば解約可能
    • au スマートパス、うたパス、ブックパス、ビデオパス、アニメパス、ディズニーパス
    • KKBOX

ということで、有料オプションの解約さえ忘れなければ問題なさそう。au ひかりも併せて確認すると

  • モバワンから 10,000 円キャッシュバック
  • プロバイダを Biglobe にすると Biglobe から 11,000 円キャッシュバック
  • B フレッツ、Nifty の解約違約金も Biglobe が最大 10,000 円まで負担

とのことで、こちらも悪くない条件。全体的にキャッシュバック額はそこそこだけど iPhone 6S 64GB が魅力的なので決断。

実行

以下、必要なものを準備して店頭で手続きする。

  • 妻の同意
    • 月々の支払いが減り、娘の習い事の費用に回せる点などを情熱を持って説明
  • 身分証明書
  • クレジットカード
  • 振込口座情報
  • MNP 予約番号
    • 情弱なので電話で取得したら一時間くらいつながらなかった。情強はネットで取得するらしい
  • 下取り端末
    • iPhoneiTunes でバックアップ。Android は SD カードにコピー
    • 端末初期化は店頭で本人確認のもと行ってくれる

なお、委任状は不可で契約者本人が来店しなければならない。印鑑と現金は一応準備したけど必要なかった。実際の手続きは店側が au ひかりの一括請求手続きにちょっと手間取ったこともあって全体で三時間くらい掛かった。

評価

今回のような動機で MNP してみて分かったこと、感じたこと。

  • 情報が多過ぎてつらい
    • 情強の友人たちから助言をもらえてラッキーだった
    • 条件のいい情報が早めに見つかってラッキーだった
  • 準備不足
    • 自分も妻も解約月ではなかったので違約金が発生した
    • 端末下取りが条件のため急いでバックアップしなければならなかった
  • キャリア変更
    • ざっくり想定していたよりも全体の費用を抑えることができた
    • Twitter/Facebook/LINE 時代にキャリアメールは必要ない
    • 回線品質も問題ないどころか 4G になって快適
  • 機種変更
    • iPhone 4S 16GB から iPhone 6S 64 GB への変更は三階級特進くらいのインパク
    • iOS のバージョンさえ合わせれば問題もなく復元できた
    • touch ID の精度と速度がすごい
    • LINE など iPhone 4S ではかなり重かったアプリがさくさく動く

以前に iPhone 欲しさに docomo から softbankMNP したときは選択肢がなかったので気楽だったけど、今回はずいぶん事情が違った。

改善

二年後に MNP バブルが続いているかは不明だけど、以下を改善したい。

  • 定期的に情報収集する
    • キャッシュバック額などの相場感を持つ
    • MNVO も検討できるよう各種サービスを把握する
  • 定期的にバックアップする
    • キャリア、端末に依存せずにインターネットサービスを活用する
  • 違約金など不要な費用を抑える
    • Google カレンダーに解約月アラートを毎年くり返しで登録した

まとめ

Twitter/Facebook/LINE でコミュニケーションを取り、各社から iPhone が発売されている現在において、キャリアにこだわる理由はないので積極的に MNP した方がいいとは思うけど、決して健全とは言えない経済に加担しているイメージがあって個人的には人生が虚しいので、MNP 乞食などしなくても携帯電話利用料を安く抑えられる世界になってほしいと思いました。

あと友人宅で体験してみたところ Hulu/Netflix より Apple Music のほうが自分の人生に必要だったので、節約した費用で Apple Music を契約します。

TED日本語 - ジェニフェアー・シニア: 幸福は親には高すぎるハードル | デジタルキャスト

すばらしい。

育児に対する漠然とした不安や、時には頭を抱えたくなるほどの煩わしさ、そしてそれを補って余りある幸福感の正体と、なにを目的として育児に取り組むべきかを情熱的に説いてくれています。

f:id:garbagetown:20151205094608p:plain

すべてのエンジニアが伴侶と子宝に恵まれ、仕事と育児と趣味の狭間でもがき苦しみますように。

TED日本語 - クリス・ハドフィールド: 宇宙で目が見えなくなり学んだ事は | デジタルキャスト

おもしろかった。

f:id:garbagetown:20151125232900p:plain

Netflix 社が障害に備えるために人工的に障害を起こし続ける話を思い出しました。

東京リカーランド北千住東口店がヤバい

久しぶりに寄ったらとんでもないことになっていたのでご紹介。

とは言えちょっとググったらすぐに有用な情報が見つかったので、まずはこれらを読んでもらうとして。

当日のツイート

連投したらフォロワーが五人くらい減った当日のツイート。

まずはシングルホップシリーズで有名な ミッケラー の変わり種。左下の方にはコピ・ルアックというネコのうんこから取るコーヒー豆を使ったインペリアルスタウトとか置いてありました。なに言ってるか分からないですよね。書いているこっちもよく分かりません。

見たことも聞いたこともないローグ・ブードゥードーナッツ・ベーコン・メイプル・エール。「この夏はこれで乾杯しよう!世界のユニークすぎるビール5選 | RETRIP」 によると甘じょっぱいらしい。

たんごさん がうまいと言っていたアメリカのレフトハンド醸造所のミルクスタウト。ミルクスタウトというスタイルそのものを知らなかった。

入手困難という噂のデリリウムの 25 周年記念限定瓶。となりのデリリウムレッドはいわゆるレッドビールではなくて、トレメンスにチェリーを漬け込んだフルーツビール。ものすごくおいしいのでおすすめ。

よこなさん が飲んでいた PUNK IPA をはじめ、ここ数年で急激に知名度を上げたスコットランドブリュードッグ もずらり。

こざけさん が大好きなパウエルクワックのギフトセットもある。こざけさんは高いと言っていたけど、あのグラスがそもそも 3,000 円くらいする ので、小瓶四本付いてきてこの値段はむしろ良心的。

買った

たんごさんおすすめのミルクスタウト。楽しみ。
f:id:garbagetown:20150509153624j:plain

デリリウムレッドは見掛けるたびに買ってしまう。自宅に帰ってみたらもう一本あった。
f:id:garbagetown:20150509153718j:plain

ブリュードッグとミッケラーのコラボ作品。IBU 130 とのことなのでめっちゃ苦そう。
f:id:garbagetown:20150509153651j:plain

ジャケ買い。スト II 世代として買わずにいられなかった。IPA らしい。
f:id:garbagetown:20150509153705j:plain

箕面ヴァイツェン。なんか海外の色モノばかり買っちゃった感があったので。
f:id:garbagetown:20150509153638j:plain

その他補足

自分が北千住に移り住んだ 2006 年には東京リカーランドは東口店と西口店があって、当時は両店ともつまらない街の酒屋だった。西口店の急な階段を登った二階に「びあマ」、三階に「ワイマ」ができたのが 2011 年くらいだったと思う。

その頃から輸入ビールの品揃えはなかなか良かったけど、場所のせいか急な階段のせいか、お客さんはあまり多くなくて、店員さんがいつも魔女の宅急便にみたいに暇そうにカウンターに座っていたのをよく覚えている。

その後しばらくして西口店が閉鎖することになり、在庫一掃セールがあって一気に 10 本くらい買った。そのとき「これだけの品揃えの店がなくなるのは惜しい」と言ったら、「東口店に移設するからそっちに来てくれ」と言われてほっとしたわけだけど、まさかここまで本気の店になるとは思っていなかった。

交通の便がいいとか大学の誘致に成功したとか、そういう理由で北千住に不動産を買ったんだけど、東京リカーランドは完全に嬉しい誤算だった。これからも積極的にお金を落としていきたい。

Hadoop を 30 分で試す

ややチート気味ですが Hadoop を 30 分で試すことができたのでお知らせします。

経緯

先日のブログ に書いた通り、Cloudera QuickStart VM はとても便利なのですが、メモリをめちゃくちゃ喰うので一般的なご家庭にあるスペックのマシンではまともに動きません。

なんでそんなにメモリを喰うかと言うと、おそらく Hive やら何やらごっちゃり入っているからで、とりあえず MapReduce を動かしてみたいだけの人には、少々オーバースペックである感が否めません。

お仕着せの環境が肌に合わないからと言って自分で環境をこしらえようにも、初心者に疑似分散とか YARN とか言われてもどうしていいか分かりませんし、Oracle JDK のインストールが地味に面倒です。

このような実情を身に染みて感じたので、以下の内容を参考に Cent OS 上に疑似分散モードの YARN 環境を作る Ansible Playbook を書いて Ansible Galaxy にアップロードしてみました。

ご用意頂くもの

一般的なご家庭に Linux 物理マシンなどあるわけがないので、以下では仮想マシンを使用します。

また、VirtualBoxVagrant, Cent OS の box などを用意済みとしている点に若干キユーピー 3 分クッキング的な突っ込みどころを感じますが、意識の高いエンジニアであれば、これくらいの備えは常識の範囲内としても差し支えないでしょう。

手順

以下、実施する手順を掛かる時間の目安と併せて紹介します。

Mac OS で動かした際のログを紹介していますが、Windows でも動くと思います。プロキシの配慮は省略しているので、企業 LAN 内などで試す際はがんばってください。

仮想マシンの用意 (5 分)

適当なディレクトリを掘って Vagrant 仮想マシンを初期化します。box の名前は自身の環境に合わせて読み替えてください。

$ mkdir cdh5; cd cdh5
$ vagrant box list
CentOS-6.4-x86_64           (virtualbox, 0)
(snip)
$ vagrant init CentOS-6.4-x86_64

Vagarnt が仮想マシンに割り当てるメモリ容量はデフォルトで 480 MB で、さすがにこれでは MapReduce が動きません。Vagrantfile には 1024 MB を割り当てる設定例が記載されているので、コメントアウトを外して設定を有効にします。

$ vi Vagrantfile
$ grep -A 1 -B 9 modifyvm Vagrantfile
  # Provider-specific configuration so you can fine-tune various
  # backing providers for Vagrant. These expose provider-specific options.
  # Example for VirtualBox:
  #
  config.vm.provider "virtualbox" do |vb|
  #   # Don't boot with headless mode
  #   vb.gui = true
  #
    # Use VBoxManage to customize the VM. For example to change memory:
    vb.customize ["modifyvm", :id, "--memory", "1024"]
  end

設定が済んだら仮想マシンを起動します。2, 3 分あれば起動すると思います。

$ vagrant up
(snip)
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
==> default: Configuring and enabling network interfaces...
==> default: Mounting shared folders...
    default: /vagrant => /Users/garbagetown/dev/vagrants/cdh5

仮想マシンが起動したらログインしましょう。以降の手順はすべて Cent OS 上で実施します。

$ vagrant ssh
Welcome to your Vagrant-built virtual machine.

Ansible のインストール (3 分)

残念なことに Ansible は Cent OS の標準リポジトリには含まれていないので、EPEL リポジトリを追加します。

[vagrant@localhost ~]$ sudo rpm -ivh http://ftp.riken.jp/Linux/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
(snip)
   1:epel-release           ########################################### [100%]

詳細を理解していないのですが、このままだと Ansible のインストールに失敗するので baseurl と mirrorlist のコメントを入れ替えます。

[vagrant@localhost ~]$ sudo vi /etc/yum.repos.d/epel.repo 
[vagrant@localhost ~]$ sudo grep -n fedora /etc/yum.repos.d/epel.repo 
3:baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch
4:#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch
12:baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch/debug
13:#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-6&arch=$basearch
21:baseurl=http://download.fedoraproject.org/pub/epel/6/SRPMS
22:#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-source-6&arch=$basearch

Ansible をインストールします。2, 3 分あればインストールできると思います。

[vagrant@localhost ~]$ sudo yum -y install ansible
(snip)
Installed:
  ansible.noarch 0:1.8.2-3.el6                                                                                                                                                                             

Dependency Installed:
  PyYAML.x86_64 0:3.10-3.1.el6             libyaml.x86_64 0:0.1.3-4.el6_6            python-babel.noarch 0:0.9.4-5.1.el6  python-crypto.x86_64 0:2.0.1-22.el6     python-crypto2.6.x86_64 0:2.6.1-1.el6 
  python-httplib2.noarch 0:0.7.7-1.el6     python-jinja2.x86_64 0:2.2.1-2.el6_5      python-keyczar.noarch 0:0.71c-1.el6  python-paramiko.noarch 0:1.7.5-2.1.el6  python-pyasn1.noarch 0:0.0.12a-1.el6  
  python-setuptools.noarch 0:0.6.10-3.el6  python-simplejson.x86_64 0:2.0.9-3.1.el6 

Complete!

CDH のインストール (20 分)

いよいよ CDH をインストールします。

と言っても、時間は掛かりますが手順は単純です。まず、ansible-galaxy コマンドを使って playbook をダウンロードします。2, 3 分かかると思います。

[vagrant@localhost ~]$ sudo ansible-galaxy install garbagetown.cdh5_yarn_pseudo
- downloading role 'cdh5_yarn_pseudo', owned by garbagetown
- downloading role from https://github.com/garbagetown/cdh5_yarn_pseudo/archive/master.tar.gz
- extracting garbagetown.cdh5_yarn_pseudo to /etc/ansible/roles/garbagetown.cdh5_yarn_pseudo
- garbagetown.cdh5_yarn_pseudo was installed successfully
- adding dependency: williamyeh.oracle-java
- downloading role 'oracle-java', owned by williamyeh
- downloading role from https://github.com/William-Yeh/ansible-oracle-java/archive/master.tar.gz
- extracting williamyeh.oracle-java to /etc/ansible/roles/williamyeh.oracle-java
- williamyeh.oracle-java was installed successfully

Ansible Galaxy の依存性解決の機能で Oracle JDK をインストールする playbook も落ちてきているのが分かると思います。便利ですね。

続いて localhost に対してプロビジョニングを行う playbook を書きます。CDH 5 は今のところ Oralce JDK 7 でないと動かないので、変数で指定します。

[vagrant@localhost ~]$ vi main.yml
[vagrant@localhost ~]$ cat main.yml
- hosts: 127.0.0.1
  connection: local

  roles:
    - garbagetown.cdh5_yarn_pseudo

  vars:
    - java_version: 7

あとはこの playbook を実行するだけです。pycrypto に関する警告が出ますが、ひとまず無視してください。

JDK と CDH5 のインストール、Hadoop 周りのディレクトリ作成に少し時間が掛かりますが、15 分くらいで完了すると思います。

[vagrant@localhost ~]$ ansible-playbook main.yml
[WARNING]: The version of gmp you have installed has a known issue regarding
timing vulnerabilities when used with pycrypto. If possible, you should update
it (i.e. yum update gmp).

PLAY [127.0.0.1] ************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [127.0.0.1]
(snip)
TASK: [williamyeh.oracle-java | get JDK 1.7 tarball (as RPM file)] ************
changed: [127.0.0.1]
(snip)
TASK: [garbagetown.cdh5_yarn_pseudo | Install CDH 5 with YARN on a Single Linux Node in Pseudo-distributed mode] ***
changed: [127.0.0.1]
(snip)
TASK: [garbagetown.cdh5_yarn_pseudo | Create the directories needed for Hadoop processes] ***
changed: [127.0.0.1]

TASK: [garbagetown.cdh5_yarn_pseudo | Start YARN] ***************************** 
changed: [127.0.0.1] => (item=hadoop-yarn-resourcemanager)
changed: [127.0.0.1] => (item=hadoop-yarn-nodemanager)
changed: [127.0.0.1] => (item=hadoop-mapreduce-historyserver)

PLAY RECAP ******************************************************************** 
127.0.0.1                  : ok=17   changed=15   unreachable=0    failed=0

サンプルの実行 (5分)

以上で疑似分散モードの YARN 環境ができたので、Installing CDH 5 with YARN on a Single Linux Node in Pseudo-distributed mode の "Running an example application with YARN" に従ってサンプルアプリケーションを実行してみましょう。

まず、HDFS 上にログインユーザがジョブを実行するためのディレクトリを作って権限を与えます。

[vagrant@localhost ~]$ sudo -u hdfs hadoop fs -mkdir /user/$USER
[vagrant@localhost ~]$ sudo -u hdfs hadoop fs -chown $USER /user/$USER

続いて、サンプルアプリケーションで grep するために、ローカルファイルシステムから HDFS 上に適当なファイルをコピーします。ここでは Hadoop の設定ファイルを HDFS 上に put しています。

[vagrant@localhost ~]$ hadoop fs -mkdir input
[vagrant@localhost ~]$ hadoop fs -put /etc/hadoop/conf/*.xml input

最後に、環境変数を設定してサンプルアプリケーションを実行します。

[vagrant@localhost ~]$ export HADOOP_MAPRED_HOME=/usr/lib/hadoop-mapreduce
[vagrant@localhost ~]$ hadoop jar /usr/lib/hadoop-mapreduce/hadoop-mapreduce-examples.jar grep input output23 'dfs[a-z.]+'
(snip)
15/02/22 13:51:39 INFO mapreduce.Job:  map 0% reduce 0%
15/02/22 13:51:56 INFO mapreduce.Job:  map 100% reduce 0%
15/02/22 13:52:18 INFO mapreduce.Job:  map 100% reduce 100%
15/02/22 13:52:20 INFO mapreduce.Job: Job job_1424612668205_0002 completed successfully
15/02/22 13:52:20 INFO mapreduce.Job: Counters: 49
(snip)
    File Output Format Counters 
        Bytes Written=244

MapReduce ジョブが終わってログがずらっと出たら、出力結果を確認します。

[vagrant@localhost ~]$ hadoop fs -ls output23
Found 2 items
-rw-r--r--   1 vagrant supergroup          0 2015-02-22 13:52 output23/_SUCCESS
-rw-r--r--   1 vagrant supergroup        244 2015-02-22 13:52 output23/part-r-00000
[vagrant@localhost ~]$ hadoop fs -cat output23/part-r-00000
1   dfs.safemode.min.datanodes
1   dfs.safemode.extension
1   dfs.replication
1   dfs.namenode.name.dir
1   dfs.namenode.checkpoint.dir
1   dfs.domain.socket.path
1   dfs.datanode.hdfs
1   dfs.datanode.data.dir
1   dfs.client.read.shortcircuit
1   dfs.client.file

HDFS 上にコピーした Hadoop の設定ファイルから、サンプルアプリケーションに渡した正規表現に合致する文字列を grep できていることが分かります。

まとめ

  • Cloudera の QuickStart VM は、とても便利だが、一般的なご家庭にあるマシンでは動かすのは厳しい
  • Cloudera の Quick Start Guide は、とても丁寧に書かれているが、動作モードや OS ごとに読むべき箇所が異なり、初心者が目的のドキュメントに辿り着くことは困難
  • Hadoop を 30 分で試そうと思ったら Ansible にハマって三日くらい掛かったけど気にしない
  • Ansible Galaxy の依存性解決は便利

以上です。

Hadoop を 10 分で試そうとしたら 2 時間 49 分かかった話

みなさんビッグデータしてますか?本日は懺悔のブログです。

経緯

世間から遅れること五年、そろそろぼくもビッグデータしたいなと思って Hadoop 周りを調べてみたところ、エコシステムがもりもり成長中で Web 上の情報は新旧入り乱れているわ、書籍の情報はあっという間に古くなるわで、ビッグデータ界の Hello World 的な WordCount を試すのもひと苦労という有様でした。

そんな折、"2014年版 Hadoopを10分で試す(1) | Tech Blog" というブログを発見してキタコレ!と試してみたところ、いろいろあって 結果的に 10 分では試せなかったので、冗談半分で

などとツイートしたところ、なんとご本人様に補足され、

という窒息するほど土下座したい案件となりましたので、本日ここに「ビッグデータ素人がノーガードで突撃した場合、どこにどれくらい時間が掛かるのか」などを紹介することで、懺悔の言葉と代えさせて頂ければと思います。

試した手順と掛かった時間

以下の環境で試しました。

  • Windows7 64bit
  • メモリ 8GB
  • プロキシサーバ有り社内 LAN
  • 7-ZipVirtualBox はインストール済み

ダウンロード

Google Chrome で以下のサイトにアクセスして VirtualBox 版の VM をダウンロードしました。

"Download for VirtualBox" ボタンをクリックすると E メールアドレスやらを求められるので、素直に入力して Submit ボタンを押したところ、いきなり JavaScript エラーが発生。

f:id:garbagetown:20150211000553p:plain

"geoplugin_city が定義されていない" というエラーのようですが、自宅の Chrome で試してみると再現しないので、なんらかの拡張機能とプロキシサーバの組み合わせがまずいのかもしれません。

そもそも Chrome なんて気取ったブラウザを使っているのが良くないので、安定の Internet Explorer でアクセスしたら無事に VM をダウンロードすることができました。

f:id:garbagetown:20150211001613p:plain

スクリーンショットを撮り直してみたところ、残り時間 2 時間 52 分でした。他の仕事をしながら気長に待ちましょう。

展開

ダウンロードした VM7-Zip で圧縮されているので、展開して中身を取り出します。

f:id:garbagetown:20150211002416p:plain

7-Zip で開いたらデスクトップなどの適当な場所にコピーしましょう。マシンスペックにもよると思いますが、自分の環境では 15 分くらい掛かりました。

f:id:garbagetown:20150211002553p:plain

インポートと起動

仮想マシンイメージが取り出せたら、VirtualBox にインポートします。ここでは残り時間 1 分などと表示されますが、実際は 3 分くらい掛かります。

f:id:garbagetown:20150211012304p:plain

インポートが完了したら、いよいよ VM を起動します。5 分くらい掛かります。

f:id:garbagetown:20150211012512p:plain

プロキシの設定とサンプルアプリケーションの準備

VM が起動すると Firefox が立ち上がるのですが、なんだか画面が変です。

f:id:garbagetown:20150211012839p:plain

プロキシサーバが設定されていないので画像などが取得できていません。機能的な影響はありませんが、モチベーションに影響するのでプロキシサーバを設定しましょう。

なお、quickstart.cloudera は localhost を見るのでプロキシ対象外に指定する必要があります。

f:id:garbagetown:20150211013213p:plain

プロキシの設定が完了したら、ブックマークバーから Hue を選んで cloudera/cloudera でログインします。

f:id:garbagetown:20150211013939p:plain

Hue にログインしたら、"2014年版 Hadoopを10分で試す(1) | Tech Blog" を参考に Hue のインストールウィザードを進めてサンプルアプリケーションをインストールします。10 分くらいあればインストールできると思います。

f:id:garbagetown:20150211014247p:plain

サンプルアプリケーションの実行

いよいよ Hadoop を試します。Hive クエリを実行してみましょう。

f:id:garbagetown:20150211014800p:plain

Hive クエリが MapReduce ジョブに変換される様子がログに出力され、処理が完了すると自動的に結果画面が表示されます。

f:id:garbagetown:20150211015009p:plain

エンジニア的にはおおおスゲーと素直に喜べますが、ふだん見慣れている SQL に似た Hive クエリだけに、えらいひとには Hadoop の威力よりも MapReduce の遅さの方が目立ってしまうんじゃないかなあと余計なことも思いました。

Hive と比べると Impala はすごく速いです。他にも Sqoop や Pig などのサンプルもあって遊ぶには持ってこいですが、お仕事で使う場合はこれらツールの特色をきちんと理解して、冗長化などにも気を付けながら採用を検討する必要があり、それなりに敷居は高いと感じました。

その頃タスクマネージャは

いっぱいいっぱいでした。

f:id:garbagetown:20150211023038p:plain

まとめ

  • Hadoop 周辺は進化の速度が速く、Web や書籍の情報をもとに検証環境を構築することがむずかしい
    • 最初は Apache Hadoop, Cloudera, Hortonworks, MapR の違いも分からない
    • スタンドアロン、疑似分散、完全分散とか言われても困る
    • MRv1 と YARN は何が違うのか分からない
  • CDH QuickStart VM を使えば、仮想マシン起動開始から 10 分で CDH に含まれるいろいろなツールを試すことができる
    • ただし仮想マシンを起動するまでに 3 時間以上かかる
    • あとメモリめっちゃ食う

あれこれ悩みながらの手作業だと 3 時間どころか 3 日掛かっても環境を作れないので、取っ掛かりとして QuickStart VM を試すのは良いと思います。

ただし、仮想マシンの使用メモリが 4 GB に設定されているので、メモリを 8 GB 以上搭載しているマシンでないと厳しいです。

OS やメーラ、ブラウザ、IDE などを立ち上げて開発することを考えると 8 GB マシンでも際どいので、現在は VMHadoop 専用端末にインストールして VirtualBox のブリッジアダプタで社内 LAN に繋いでいます。この辺りの手順も気が向いたら書くかもしれません。

それではみなさん良いビッグデータを。