page_adsence

2018年4月25日水曜日

Macのローカル環境でSparkのWeb UIをみる方法

何度か調べているので、忘れないようにメモしておく。

AWSとかでEMR使っている場合は、SparkのWebUIはデフォルトで利用出来るようになっているのですが、
ローカル環境で使おうとすると、WebUIのURLは出てくるけど、アクセスすると応答なしになってしまいます。
なので、ローカルで実行する時にはSparkSessionを作成する時に、UIを有効にする設定をしないといけない。

val spark = SparkSession.builder.config("spark.ui.enabled", value = true)

公式ドキュメントを見ると、デフォルトが true になっているけど、上記を指定せずにローカルで実行したら None になっていた。

2018年2月24日土曜日

デブサミ2018に行ってきました

去年に引き続き、デブサミに行ってきました。
山手線が混んでいて、行くだけで疲れましたが・・・。
今いる会社はレポートさえ書けば平日でもこういったイベントに行かせてくれるので非常にありがたいです。
早速聞いてきたセッションの概要と感想を書いていきたいと思います。

技術選定の審美眼

結論

技術の変化は振り子ではなく螺旋である。
その差分を読み取る能力と、それを可能にした技術が重要。
すべてを習得するのは不可能なので、スルーするかしないかを決める。
コスト構造が変わるものはスルーしない。

感想

初めて和田卓人さんのセッションを聞きました。
自分はそんなに聞き取り能力高くないのですが、非常にわかりやすいセッションだった気がします。
このスライドに関しては初演ということもあり、時間切れで最後まで聞くことはできませんでしたが、
非常に面白かったですし、新しい技術が次々出てくる時代で、どうやって取捨選択すればいいのかを迷っていた自分にはとてもよい内容でした。

データを活かす組織の作りかた、事業に寄り添う分析・機械学習基盤の育てかた

結論

データ分析・機械学習基盤を作るための3ステップ
- まずは存在するデータを分析してみる
- 難易度低めところに部分的に導入してみる
- 考えを広げ、価値のあるデータの集め方や、それらを使って新しい価値の想像をしたりといい循環が回るようにする

感想

もともとデータを活かす文化が会社にはあって、それを土台にしつつデータ分析基盤を作ったというような印象。
当然データ基盤だけ作っても意味はないので、データを使う文化を作っていくのはとても大変そうだけど、一番大事なことかなと。

Spinnakerで実現するデプロイの自動化

結論

学習コストは高いけど結構便利。
Blue/Greenデプロイ出来てないなら試してみて。
バグがあったり、コンポーネント間の関係が複雑で原因特定大変だけど、いいツール。

感想

Spinnakerというツールはここで聞くまで知らなくて、面白いツールあるんだなーと。
まだまだバグがあるみたいですが、活用事例が出始めているので、これから使ってみてもいいのかなと思いました。

マルチクラウドで構築する大規模解析サービス~戦略とポイントについて

結論

各クラウドベンダーの特徴を把握して、いいとこ取りが出来ればマルチクラウドはあり。
クラウド間の差分を吸収する統一的なインターフェースを利用することで、利用者がマルチクラウドであることを意識しないといけないケースを減らす。
ハマりどころがあるので、注意が必要。

感想

マルチクラウドって複数クラウドベンダーをちょっとずつ使っているのかと思いきや、AWSとGCPで同じような形で構成していて、どっちかのクラウド環境が落ちても、もう片方のクラウド環境で対応することが出来て、高可用性を実現しているとのこと。
最初の環境構築の部分はすごく大変そうだけど、構築してしまえば結構いけそうな感覚が持てた。
デプロイにはSpinnaker使っていて、意外と行けているらしい。

将棋プログラムPonanzaにおける強化学習、ディープラーニングとその先

感想

ちょっと内容が難しすぎて、機械学習をまだ勉強できてない身では難しすぎて全然話についていけなかったです・・・。
とりあえずAlphaGoZeroすごいってことと、将来的にはAIを作るAIが出てくるのではっていうことでした。

総括

選んだセッションのせいというのがあるとは思いますが、結構Dockerを本番環境まで当たり前のように使っている会社が多くなってきたなーという印象を持ちました。
Dockerは手元の開発環境で使うにはお手軽で非常に便利なのは実感出来ているのですが、セキュリティとかをどう考えればいいのかがよくわかっていなくて、未だに本番環境では使えていません。
この辺はもっと勉強しないといけないなーと。

去年に続き今年もデブサミに参加したのですが、やっぱり人がすごいいっぱいいてめちゃくちゃ疲れました・・・。
でも、新しい発見とか勉強になったセッションもあったので、年一で刺激を受けるにはいい場所だと思います。
来年も行けるかどうかはわからないですが、とりあえず来年のデブサミまで一年間頑張って勉強していこうと思います。
それでは。

2018年2月14日水曜日

Amazon Linux 2のイメージを使ってみる

背景

現在業務でAmazon Linuxを使っているのですが、Amazon Linux 2に移行したらどうなるのかなーと思ったのと、
個人的に会社の環境をコンテナ化していったらどうなるかなーというのを試してみたかったのがきっかけ。
そのためにまず Amazon Linux 2 のイメージを落としてみようと思いました。

とりあえず調べてみる

どうやらAmazon Linuxのイメージの取得方法は2種類あるらしい。
最近DockerHubから落とせるようになったって話題になっていたので、DockerHubから落とせるのは知っていたのですが、
AWS ECRからも落とせるみたいですね。

それぞれ、ダウンロードする為に必要なものは下記の通り。

  1. AWS ECR からDockerイメージをダウンロードする方法
    -> AWSのアカウントが必要

  2. DockerHubから取得する方法
    -> DockerHubのアカウントが必要

AWS ECRからダウンロードするのはAWSのアカウントが必要になるので、会社で試しにやってみたのですが、結構面倒でした。
DockerHubで落としてくる方が断然楽なので、こちらをオススメします。

やってみる

DockerHubのアカウントの発行に関しては、事前に済ませている前提で進めます。

  1. ターミナル上でDockerHubにログインする

    docker login
    

    ログイン時のユーザー名を入力する

    Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
    Username: (DockerHubのユーザー名。メールアドレスではない。)
    

    ログイン時のパスワードを入力する

    Password: (DockerHubのログイン時に使用するパスワード)
    

    認証情報が合っていればログインに成功した旨が表示される

    Login Succeeded
    
  2. DockerHubからimageをpullしてくる

    docker pull amazonlinux
    
  3. Amazon Linux 2 のコンテナに入ってみる

    docker run -it amazonlinux /bin/bash
    
  4. OSの確認

    # cat /etc/os-release
    NAME="Amazon Linux AMI"
    VERSION="2017.09"
    ID="amzn"
    ID_LIKE="rhel fedora"
    VERSION_ID="2017.09"
    PRETTY_NAME="Amazon Linux AMI 2017.09"
    ANSI_COLOR="0;33"
    CPE_NAME="cpe:/o:amazon:linux:2017.09:ga"
    HOME_URL="http://aws.amazon.com/amazon-linux-ami/"
    

以上でAmazon Linux 2のイメージをダウンロードしてくることが出来ました。
AWS ECRからダウンロードするのは面倒だけど、DockerHubから落としてくるのはめっちゃ楽でした。
あと、Amazon Linux 2って言っているけど、ec2-userがいるわけでもないし、普通にalpineのイメージと大差ない感じでした。
まぁベースイメージとしてはこんな感じなのかなぁという気がしないでもない。

2017年9月10日日曜日

Jenkins公式のDockerイメージを使って、プラグインインストール済みのJenkinsイメージを作る

Dockerを使ってJenkinsサーバを立てようと思ったのですが、プラグインをインストールした状態のイメージを自分で作りたくて色々調べたので、その結果を書いていこうと思います。

まず最初に見つけたのが下記のリポジトリのものです。

blacklabelops/jenkins

docker-composeで立ち上げる際に、env_fileを食わせてやることで、プラグインインストール済みのJenkinsサーバが立ち上がるらしいのですが、インストールしたいプラグインを入れても、なぜか上手くいかなかったので別のを探すことに。

引き続き調べていたら、Jenkins公式の配っているイメージでもプラグインをインストール出来ることがわかったので、それを試してみました。

jenkins

FROM jenkins
COPY plugins.txt /usr/share/jenkins/ref/
COPY custom.groovy /usr/share/jenkins/ref/init.groovy.d/custom.groovy
RUN /usr/local/bin/plugins.sh /usr/share/jenkins/ref/plugins.txt

こんな感じで書くとプラグインがインストール出来ると書いてあるのですが、依存関係を自動で解決してくれないので、依存しているプラグインを全部自力で順番通りに書かないといけないということで、ちょっとだけやってみたのですが、現実的ではないということでこれも諦めました。

Jenkinsのコンテナ作って中に入って色々見ていたら、気になるシェルスクリプトを見つけたので、試しに使ってみることにしました。

FROM jenkins
RUN /usr/local/bin/install-plugins.sh git github

こんな感じで、インストールしたいプラグインIDを空白区切りで列挙します。
記載が終わったらビルドして新しいJenkinsのイメージを作ります。

docker build . -t jenkins

続いて、docker-compose.ymlに下記のように指定します。

jenkins:
  image: jenkins
  container_name: jenkins
  ports:
   - "8080:8080"
   - 50000
  volumes_from:
    - volumes
  environment:
    - JAVA_OPTS="-Djenkins.install.runSetupWizard=false"

volumes:
  image: busybox
  container_name: jenkins_data
  volumes:
    - /var/jenkins_home

この中でJenkinsの初回起動時のウィザードを出さないようにしています。
で、

docker-compose up -d

で起動します。

http://localhost:8080/

にアクセスして、Jenkinsのプラグイン管理の画面に行くと、ちゃんとインストールされてました!
DockerHubの方のページには書いてなかったので気づけなかったのですが、githubの方にはちゃんと書いてありました・・・。

jenkinsci/docker

なんにせよこれでプラグインの依存関係を気にせず入れれるようになりました。

2017年8月4日金曜日

IntelliJとVisualVMでScalaのベンチマークを取る

Scalaで作っているAPIサーバがあるのですが、自分が作った部分がリリースされた直後、APIのレスポンスが悪くなりアラート連発という事態が発生。
今回のリリースで対象のAPIサーバをいじったのは自分だけ。
しかし、ソースはレビュー済みで、切り戻し後にもう一度確認してみたのですが、誰が見ても特に重そうという処理はしてなさそうという結論に至りました。

そこで、修正前後のベンチマークを取って比べてみようということに。
最初は「sbt-jmh」を使ってベンチマークを取ろうとしたのですが、うまく行かず・・・。
Javaでプロファイルするのに使っていたVisualVMというものがあって、もしかしたらそれでScalaのプロファイルも出来るかもというアドバイスを貰ったので、早速調べてみると比較的最近の記事が出てきました。

Scalaで書いたProcessing のプログラムを VisualVM でプロファイルする

上の記事を見てScalaのプロファイル取れることがわかったので、早速導入してみた。

VisualVMの入手とインストール

  1. VisualVM にアクセス
  2. Download ボタンをクリック
  3. Mac OS X Application Bundleをクリックしダウンロードしてくる
  4. 落としてきたdmgファイルダブルクリックしてインストール

IntelliJのプラグインの入手と設定

  1. Preferences -> Plugins -> Browse repositories -> 検索窓に「VisualVM Launcher」と入力し、「Install」ボタンをクリック
  2. プラグインのインストールが完了すると、「Restart IntelliJ IDEA」ボタンに切り替わるので、IntelliJを再起動する。
  3. Preferences -> Other Settings -> VisualVM Launcher のメニューをクリックし、
    VisualVM executable: に 「/Applications/VisualVM.app/Contents/MacOS/visualvm」 と入力
  4. それ以外の部分はそのままにして、OKをクリック
  5. 通常の「Run」や「Debug」と同じ様に、「Run With VisualVM」か「Debug With VisualVM」を押すと、アプリが起動する。
    ■ Before

    ■ After
  6. メニューの方も変わっている
    ■Before

    ■After
  7. 後は勝手にVisualVMが起動するので、必要な部分を見ればOK

以上で設定は完了です。

2016年7月4日月曜日

IntelliJを使ってGo言語の開発環境を整えてみる for Windows

会社のPCは現在Windowsなので、Windows上でGo言語の開発環境を作ってみた。
OS:Windows7
IntelliJ:15.0.6
今回行う事は大きく2つです。
1. Windows上へのGoのインストール
2. IntelliJ側のプラグインのインストールと設定
では早速Goのインストールから始めようと思います。

Go SDKのインストール

  1. 下記のサイトからGoのインストーラー「go1.6.2.windows-amd64.msi」をダウンロードしてきます。
    https://golang.org/dl/
  2. インストーラーを起動し、インストールを開始します。
    インストーラーはデフォルトだとインストール先がC:\Goになっているので、
    別のディレクトリに入れたい場合は、任意のディレクトリを指定して下さい。
  3. インストールが完了したら、コマンドプロンプトを起動し、goのバージョンを確認します。
    > go version
    バージョンの確認が出来たらプロンプトは閉じても問題ありません。
    ※この時点でPathやGOROOT等の環境変数は自動で設定されています。
これでGoのインストール作業は完了です。
では引き続きIntelliJ側の設定を行っていきます。

IntelliJのPluginインストール

  1. IntelliJを起動します。
  2. 「Welcome to IntelliJ IDEA」の画面右下の「configure」→「Plugins」をクリック
  3. 画面下側の「Browse repositories…」をクリック。
  4. 画面上部の検索窓に「GO」と入力し、「GO」と書いてあるものをインストールします。
  5. プラグインのインストールが完了すると、再起動を求められるので、IntelliJを再起動します。

  6. 再起動したら、「Welcome to IntelliJ IDEA」画面で「Create New Project」をクリック。
  7. 画面左側のリストにGoがあるので、GoをクリックしてNextをクリック
  8. Procjet SDKの画面で「Configure...」をクリック
  9. Goをインストールしたディレクトリを指定し、OKを押下、Project SDKにGoと出てれば、Nextボタンを押下する。
    (Go言語をインストール時に何も変更指定なければ、C:\Goにインストールされているので、そのままOKを押せば問題ない)

  10. Procjet NameとProject locationを任意の場所にしてFinishをクリック
  11. 開いたプロジェクトでGo Fileを追加して、Hello World的なのを書いてみる。
    package main
    
    import "fmt"
    
    func main(){
     fmt.Printf("Hello World!")
    }
  12. 書いたら実行(メニューバーのRun -> Run ‘go run XXXXX.go’)
  13. コンソールにHello World!と出れば成功!
古い情報とかだとjarファイル落としてこないといけないとか書かれていますが、
基本的にはGoをインストールとIntelliJの画面内の操作で完結するようです。

おまけ

最初はIntelliJのバージョンが15.0.4のものを使っていたのですが、
なぜかGo SDKのディレクトリを指定しても、下記の様なエラーが出てしまって使えませんでした。
「The Selected directory is not a valid home for Go SDK」
IntelliJのバージョンと、Pluginのバージョンが合っていないのかとも思ったのですが、
PluginのREADMEを確認する限りでは問題ありませんでした。
go-lang-idea-plugin
取り敢えずIntelliJの最新バージョンが出てたのでアップデートしてみたら使えるようにはなったのですが、
これで根本原因が解決出来たのかは不明です・・・。

2016年6月29日水曜日

Nginxのstable版とmainline版に関して

開発環境でNginxの1.9を利用していたのですが、インフラ屋さんに1.10と1.11が出てますけど、どっちにしますかと言われたので調べてみた。
yumでインストールしたNginxのバージョンが1.9だったので、何も考えずに1.9を使っていたのですが、どうやらNginxはナンバリング方法がちょっと特殊っぽい。

Nginxのバージョン1.10と1.11のリリースノート

図を見てもらうだけで大体理解出来ると思いますが、
現在Nginxでは「mainline版」と「stable版」の2つをリリースしている。

mainline版(1.11が最新)

新機能の追加、仕様変更、バグ修正等が行われる。

stable版(1.10が最新)

mainline版からフォークされたもので、mainline版で行った重要なバグ修正のみをstable版にマージするようになっている。

といった形になっています。
記事を軽く読んだ限りですと、バグ修正もmainlineに先に取り込まれるので、mainlineを使った方が安定するようです。
なのでインフラ屋さんにはmainline版である1.11を使ってもらうようにお願いしました。
取り敢えずNginx使おうと思って始めたので、バージョンをあまり気にしていなかったのですが、きちんと確認するべきですね・・・。

2016年6月15日水曜日

docker-composeのextra_hosts

docker-composeのリファレンスを読んでいたら、extra_hostsなるオプションがあった。
自分が初めてDocker使った時にあったのかどうかは調べてないのですが、こんな便利なオプションを見逃していたなんて・・・。
dockerコンテナは基本的に起動時にIPを動的に割り当てているため、毎回コンテナ上のhostsファイルが書き換わってしまい、独自の設定を入れる方法がなかった。
力技でやる場合は、ENTRYPOINTとかのシェルスクリプト内でhosts書き換えたりする程度しか思いついていなかった。

早速使ってみた。
※ローカルにphpやmysqlという名前のイメージがある状態で行っています。
適当なディレクトリにdocker-compose.ymlを作って、下記の内容を記述します。
$ vi docker-compose.yml
mysql:
  image: mysql
  container_name: mysql
  hostname: mysqldb
  ports:
    - 3306:3306

php:
  image: php
  container_name: php
  hostname: php
  extra_hosts:
    - test1.com:111.111.111.111
    - test2.com:222.222.222.222
  links:
    - mysql
この状態で
$ docker-compose up -d
してから、コンテナ内に入る。
$ docker exec -it php bash
で、hostsファイルを確認する。
# view /etc/hosts
172.17.2.103    php
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.2.95       mysql mysqldb
172.17.2.95       mysql_1 mysqldb mysql
111.111.111.111   test1.com
222.222.222.222   test2.com
こんな感じで、記載される様になります。
便利!

※但し、大量のhostsを記載する場合はdocker-compose.ymlのファイル内が長くなってしまうので、
その辺はある程度長くなってしまったら力技の方がいいのかもしれないです。
extra_hostsもファイル指定出来ればいいんですけどね。

2016年5月25日水曜日

PHPのバージョンアップに伴うPHP関連の調査メモ

PHPを5.2系から5.6系にバージョンアップするにあたって、諸々調査してみました。
  • php.ini関連(主にAPC- > APCu + OPCacheへの移行に関して)
  • php-fpmの設定値に関して
  • mysqlndの利用可・不可

php.ini関連(主にAPC- > APCu + OPCacheへの移行に関して)

APCはPHP 5.5以降では利用できなくなってしまったため、APCu + OPCacheに乗り換える必要があります。
乗り換えるにあったって、諸々調査したのでその結果を残しておこうと思います。

APC(Alternative PHP Cache)

まずAPCとは「Alternative PHP Cache (APC) は、PHP の実行コードをキャッシュする仕組みで、 フリーかつオープンに使用できます。PHP の中間コードのキャッシュ・最適化を行うための、フリーでオープンかつ堅牢なフレームワークを提供するということを目標としています。」(PHPの公式から抜粋)
と書かれていますが、実際は中間コードのキャッシュだけではなく、インメモリ型のKVSとして利用することも可能です。
※但しネットワーク越しのアクセスは不可

APCu

APCu is APC stripped of opcode caching.
→ APCuはAPCのオペコードキャッシュを除いたものです。

The first APCu codebase was versioned 4.0.0, it was forked from the head of the APC master branch at the time.
→ APCuの最初のコードはバージョン4.0.0で、APCのマスターブランチをフォークして作成されています。

PHP 7 support is available as of APCu 5.0.0.
→ PHP 7はAPCu5.0.0が利用出来る様になっています。

APCu can provide a compatibility mode, such that it can provide a drop in replacement for the applicable parts of APC.
→ APCuは互換性モードを提供しており、APCの一部の機能の下位互換を持っています。

公式から抜粋して訳してみたのですが、合っている保証はありません。
要するにインメモリ型のKVSの機能のみを提供するもので、APCからフォークされて出来ているみたいです。

OPCache(Zend OPCache)

OPCacheは「OPcache はコンパイル済みのバイトコードを共有メモリに保存し、PHP がリクエストのたびにスクリプトを読み込み、パースする手間を省くことでパフォーマンスを向上させます。」
と記載されている通りの機能です。
1点問題になるのは、OPCacheはシンボリックリンクを解決した状態でキャッシュされるため、
シンボリックリンクを変更しても、キャッシュは更新されないという問題がある。

http://kohkimakimoto.hatenablog.com/entry/2014/09/13/154342

また、opcache_resetもCLIから実行するとCLI側のオペコードキャッシュしか消えないようです。
そしてWebから実行されたopcache_resetはWeb側もCLI側も消えるという・・・。
この辺は自分でも検証してみようと思います。
結果は後日追記する予定です。

http://tech.gmo-media.jp/post/136590171029/php-53-to-php-56

php-fpm(FastCGI Process Manager)の設定値に関して

「PHP の FastCGI 実装のひとつで、 主に高負荷のサイトで有用な追加機能を用意しています。」 各サーバのスペックに応じてチューニングする必要のある部分は下記の所になります。(下記はデフォルト値です)
項目名設定値
pm.max_children50
pm.start_servers5
pm.min_spare_servers5
pm.max_spare_servers35
pm.max_requestsコメントアウト

この辺の値を変更する必要があるのですが、一律で変更出来るものではないので、
各自負荷テストを行った結果を反映させる必要があります。

mysqlndの利用可・不可

mysqlnd「MySQL Native Driver」とは「MySQL Client Library」に変わる新たなライブラリです。
mysqlndにしかない機能も多数あるので、移行出来るものならしたいものですが、そうはいかない世の中でした。
php5.5以降からmysqlndがデフォルトで利用される様になったのですが、mysqlndで16バイト長のパスワードが設定されているMySQL Serverに接続しにいくと、エラーが出てしまい接続出来ないという現象が発生します。
現状稼働しているMySQLに接続しにいかないといけないとかがあると、一手間必要になってしまいます。
どういった事が必要になるかというと、mysqlndでは41バイト長のパスワードハッシュでないと接続出来ないので、
バージョンの古いMySQLのバージョンだと、16バイト長のパスワードハッシュになっているので、それを41バイトハッシュに書き換えてやる必要があります。
影響範囲の洗い出しが簡単で、DB停止とかが出来るのであれば、変更可能だとは思いますが、そうでない場合は簡単には踏み切れないですね・・・。
PHP5.2(libmysql)とPHP5.6(mysqlnd)で、それぞれ16バイトと41バイトのパスワードが設定されている時にどういった挙動になるかを表にしてみました。
PHP5.2.17(libmysql)PHP5.6.18(mysqlnd)
MySQL5.1 [16byte Password]OKNG(mysqlnd cannot connect)
MySQL5.6 [16byte Password]OKNG(パスワード不一致)
MySQL5.1 [41byte Password]OKOK
MySQL5.6 [41byte Password]OKOK

基本的にはパスワードさえ41バイト長のものに変えてしまえばログイン出来るのですが、
注意点としては、MySQL4.0以前のクライアントが残っていると41バイト長のパスワードは受け付けられないので、ログインできなくなります。(下記の様なエラーが出るみたいです)
> mysql -h localhost -u root
Client does not support authentication protocol requested
by server; consider upgrading MySQL client
とはいえ、MySQL5.7では16バイト長のパスワード(OLD_PASSWORD)のサポートがなくなるみたいですので、早めに移行するに越したことはないですね。
既存のデータベースに引っ張られない様なシステムの構築する場合は、積極的に使っていきたいと思います。

現状利用しているphpのモジュール一覧を取得する。

phpのモジュール一覧を確認しようと思ったのですが、オプション忘れたので調べた。

言わずと知れたphpinfoのコマンド版
php -i
今回知りたかったロードしているモジュール一覧
php -m

phpの公式にコメント付きで書いてあるので、詳細はそちらで。
http://php.net/manual/ja/features.commandline.options.php