nkmrtty’s blog

https://nkmrtty.com/

お手軽ツイート収集基盤(Docker+Elasticsearch+Kibana+Logstash)

タイトルの通り、Elastic Products on Dockerでツイート(Sample Tweet API)の収集基盤を作ったお話。

内容としてはココの話をDockerでやっただけです。

confファイル書くだけでsampleのツイートを収集できるので非常にお手軽。いままでPythonで頑張っていたのは何だったのだ......

なお、本記事の手順で構築した基盤ではCPUの使用率がCore i5 6500で200%弱(topコマンドの値)になるので自宅のPC等で利用するのはおすすめしません。

Elastic Products on Dockerの細かい設定方法等についてはElasticの公式ドキュメントを熟読してください。

今回の環境

  • Ubuntu 16.04.4 LTS
  • Docker version 17.12.1-ce, build 7390fc6
  • docker-compose version 1.18.0, build 8dd22a9
  • Elastic Productsのバージョンは6.2.2で統一
  • Twitter APIの各種キーは事前に取得済

ディレクトリ構成

.
├── docker-compose.yml
├── elasticsearch
│   └── data
└── logstash
    └── pipeline
        └── twitter.conf

各種設定ファイル

Gistにアップロードしてます。Logstashでは標準でTwitterのストリームデータを扱うためのプラグインが提供されているのでそれを使います。

Easy tweets collection system = Docker + Elasticse ...

起動

docker-compose up -dで楽々起動。localhost:5601でKibanaにアクセスできます。

メモ

  • 今回はElasticsearch、Kibana、Logstatshを一元管理していますが、使い勝手的にはLogstashは用途ごとに別々で起動したほうが使いやすいと思います。
  • 生データのツイートをそのままElasticsearchに投げているのでCPU、ディスクともに負荷がすごいです。ココらへんを参考に必要な属性に絞ってElasticsearchに投げるのが良いかと思います。

最後にツイートが溜まっていく様子を眺めます。おわり。

GPGPU環境作り改

先日、表題の通りの記事を書いたわけですが、この手順だとnvidia-settingsコマンドを使ったGPUオーバークロックができなくてずっと困っていた(半年ぐらい)。

nkmrtty.hatenablog.com

DeepなML使ったDataのマイニングにも十分興味はあるのですが、Goldのマイニングにも興味があってそれまでは専用設定がすでにされたUbuntuイメージを使っていたわけです。

今回、やっと自分で構築した環境でGPUオーバークロックができるようになったので改めてUbuntuクリーンインストールされた状態からの手順についてまとめます。

GPUオーバークロックについては自己責任でお願いします。

想定環境

基本的にローカルでの作業になります。

前準備

NvidiaドライバとCUDAをそれぞれDLしておく。

Nouveauドライバの無効化

/etc/modprobe.d/blacklist.confに以下を追記。ほぼ前回と同じ。

blacklist nouveau
options nouveau modeset=0

反映させて再起動する。

$ sudo update-initramfs -u
$ sudo reboot

Nvidiaドライバのインストール

Alt+Ctrl+F1Virtual Consoleを起動する。

X-serverを止めます。

$ sudo service lightdm stop

ドライバをインストールします。

$ sudo /path/to/NVIDIA-Linux-x86_64-384.90.run

再起動後、nvidia-smiコマンドが動作すればドライバのインストールは完了です。

ダミーディスプレイの設定

詳しくは省略しますが、以下の呪文を唱え、再起動します。

$ sudo update-grub
$ sudo nvidia-xconfig -a --allow-empty-initial-configuration --cool-bits=31 --use-display-device="DFP-0" --connected-monitor="DFP-0"

すると、なんと不思議なことに

オーバークロックができるようになります。こんな感じで。

$ nvidia-settings -a "[gpu:0]/GPUPowerMizerMode=1"
$ nvidia-settings -a "[gpu:0]/GPUFanControlState=1"
$ nvidia-settings -a "[fan:0]/GPUTargetFanSpeed=80"
$ nvidia-settings -a "[gpu:0]/GPUGraphicsClockOffset[3]=100"
$ nvidia-settings -a "[gpu:0]/GPUMemoryTransferRateOffset[3]=100"

簡単に説明すると、nvidia-smi0番目のGPUに対して、

  • 冷却ファンのスピードを80%に固定
  • コアクロック+100MHz
  • メモリクロック+100MHz

です。

このコマンド、SSH経由では実行できないのが今の悩み。調べている範囲ではDISPALY=:0とすればいいだけらしいんですが、この手順で作成した環境ではムリでした。だれか教えて。

CUDAのインストール以降

ここからChainerのサンプル動かすまでは前回の記事と同じ手順です。

感想

パッケージマネージャに頼るな。暖房いらない。

mysqlの文字列まわり

男は黙って utf8mb4 and utf8mb4_bin

[mysqld]
character_set_server=utf8mb4
collation_server=utf8mb4_bin

あとUNIQUE制約下で文字列末尾の空白の存在が無視されるのも仕様? そういうのは基本不正な文字列なので無視すればいいんだけどとりあえずDBに突っ込んどきたいときに対処が面倒くさい

初Docker?

Amazon Route 53でDynamic DNSを行うためのDockerイメージを作成した。

イメージ作成からまともにDocker触るのはこれが初めて。

イニシャルコストが高いのは否めないけど、細々とした動作をさせるのには楽だなぁ。

GPGPU環境作り

(2017/12/16更新)GPUオーバークロックができる手順についてまとめました nkmrtty.hatenablog.com


環境作るたびにいろんなガイド見比べてる気がしてるから自分でまとめる。CUDAがNvidiaドライバのバージョンを指定してくるので、各レポジトリを追加してCUDAをインストールする、という流れが一番手間が少ないようだ。

今回の環境

  • Ubuntu Desktop 16.04.3 LTS
    • インストール直後を想定
  • GeForce GTX 1060 x1
  • GeForce GTX 1050Ti x1

前準備

デフォルトのグラフィックドライバを無効化する。デフォルトのドライバが使用されているかどうかは以下のコマンドでわかる。

$ lsmod | grep -i nouveau

無効化するスクリプト/etc/modprobe.d/blacklist-nouveau.confを作成する。

blacklist nouveau
options nouveau modeset=0

反映させて再起動する。

$ sudo update-initramfs -u
$ sudo reboot

レポジトリの追加

NvidiaドライバとCUDAのレポジトリを追加する(Nvidiaドライバのレポジトリはいらないかも)。 CUDAについては、Nvidia DeveloperからdebファイルをDLしておく。バージョン等は適当に読み替えてください。

$ sudo add-apt-repository ppa:xorg-edgers/ppa
$ sudo dpkg -i cuda-repo-ubuntu1604-9-0-local-rc_9.0.103-1_amd64.deb
$ sudo apt-key add /var/cuda-repo-9-0-local-rc/7fa2af80.pub
$ sudo apt update

CUDAのインストール

今回はnvidia-384が一緒にインストールされた。

$ sudo apt install cuda

パスの設定もしておく(必須なのかよくわからない)

export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH

cuDNNのインストール

cuDNNをダウンロードして所定の場所にインストール。

tar xzf cudnn-9.0-linux-x64-v7.tgz
sudo cp -a cuda/lib64/* /usr/local/lib/
sudo cp -a cuda/include/* /usr/local/include/
sudo ldconfig

rm -R -f cuda cudnn-9.0-linux-x64-v7.tgz

動作テスト

Chainer動かすまで。

$ sudo apt install git python3-venv python3-dev
$ python3 -m venv chainer
$ source chainer/bin/activate
$ pip install cupy chainer
$ git clone https://github.com/chainer/chainer.git
$ cd chainer/examples/mnist/
$ python train_mnist.py --gpu=0

メモ

  • 記事作成時点の最新ドライバはnvidia-387
  • nvidia-384以降、GTX 1050Tiの消費電力量が表示されないバグ?があるっぽい(参考)。レポジトリから選べるドライバだとnvidia-381以前なら正常に表示される。しかし、CUDAインストール時にnvidia-384に置き換えられちゃうのでとりあえずこのままで。

S3+CloudFrontによるhttpsなWebサイトの公開

個人サイト(https://nkmrtty.com)を自前のサーバからAWSに移設した際のログ。

独自ドメインをRoute 53で管理

Naked domain (Zone apex)を用いてサイトを公開するためにはドメインの管理をRoute 53上で行う必要がある。

これはS3のバケットを独自ドメインで公開する場合、バケットのエンドポイントへのCNAMEレコードを設定する必要があるため。しかし、RFC1912の規定によりNaked domainに対してCNAMEレコードを作成することができないとされている。

この制限に対してRoute 53では独自のAliasレコードを提供しており、このレコードを用いることでS3やCloudFrontのエンドポイントとNaked domainのマッピングが可能。

外部で取得したドメインをRoute 53で管理するための手順については公式ガイドを参照。

S3バケットの作成

基本的な手順についてはAWSのガイドにある通り。

今回、CloudFrontを経由してS3のバケットを配信するのでバケットのポリシー設定やS3のエンドポイントに対するDNSレコードの設定は不要。 作成するリージョンもCloudFrontを噛ませているので安いとこ選べばいいと思います。

SSL証明書の作成

独自ドメインを用いる場合、独自ドメイン用のSSL証明書が必要となる。この証明書じゃなきゃダメみたいな事情が無ければAWS Certificate Manager (ACM)で作成するのが楽。

今回の構成で使用する証明書をACMで作成する場合、以下の点に注意。 1. バージニア北部(us-east-1)リージョンで作成 2. 所有ドメインの特定のメールアドレス(e.g., admin@example.com)に対して、認証用のメールを受信できる環境が必要

厄介なのは2.で、このためだけにわざわざメールサーバを構築するのは面倒なのでAmazon Simple Mail Service (SES)を使って一時的にメールを受信できる環境を構築する。

SESの設定

特に難しいことはなく、公式のガイドに沿ってadmin@example.comでメールを受信できように設定をすれば良い。

ACMを用いたSSL証明書の取得

公式ガイドに従って証明書を取得する。認証のメールが届くまでに結構時間がかかるので気長に待つ。

CloudFrontによるS3バケットの配信

公式ガイドに従って設定する。今回は最終的に独自ドメインを使用するのでCNAMEの設定は忘れないように。SSL証明書の設定ではACMで作成した証明書を使用するように設定。まともに使えるようになるまでかなりの時間がかかるので気長に待つ(Q&A参照)

DNSレコードの追加

CloudFrontのデプロイが完了したら、Route 53のコンソールから対象のディストリビューションに対するDNSレコードを追加する。手順は公式ガイドの通り。

Q&A

所有ドメインまたはCloudFrontのエンドポイントにアクセスした際にS3バケットのURLにリダイレクトされてしまう

/*でInvalidationしてしばらく放置しておくと解決する。おそらく、CloudFrontのコンソールにおいてS3バケットを配信元として設定する際にバケットの仮想ホスト形式のURLが用いられているおり、CloudFrontのデプロイ時に適切なエンドポイントへのリダイレクトがキャッシュされてしまうのが原因。

料金で突然死しない?

今回の構成で各サービスの最小枠を最大限使用したとして、1.2 USD / month。個人サイトで転送量がTB近くなるとかDBやPHP使いたいとかならAmazon Lightsailを使うのが良いんじゃないでしょうか。

ちなみに、記事執筆時点の各サービスの料金は以下の通り

  • Route 53
    • 0.50 USD / host zone / month
    • 0.400 USD / 1M queries / month *クエリ数ベースの料金は実際のクエリ数に応じて案分計算されるみたい
  • S3 (バージニア北部)
    • 0.023 USD / GB / month (for first 50TB)
    • 0.005 USD / 1K PUT requests / month
    • 0.004 USD / 10K GET requests / month
  • CloudFront
    • 0.140 USD / GB (Transfar to Japan)
    • 0.012 USD / 10K HTTPS requests (from Japan)
  • SES(メール受信)
    • 無料(1000件まで)
  • ACM
    • 無料
    • ACMの鍵管理用にKMSが利用されるがこちらも基本無料