大規模アプリケーションの
インフラを再設計
eureka Go 2015/12/12
自己紹介
• Matsuo Kenji (@_yokoninaritai)
• eureka, Inc.
• インフラチームのマネージャー兼、情シス的な仕事してます。
• 元料理人で、上場したベンチャー企業2社でインフラと開発やってました。
• 入社していま6ヶ月です。
• 猫好きです。
目次
• pairs server configuration
• Blue-Green Deployment
• nginx + go application
• EC2 on MySQL
• Stress Tool
• Monitoring
• Analysis
pairs
Server Configuration
• ansible + serverspec
• nat server
• Terraform
• MHA
• apache + php → nginx + golang
• capistrano → blue - green deploy
• RDS → EC2 on MySQL and Aurora
• zabbix → mackerel
• etc…
Infrastructure as Code を心がけました。
SPOF を無くすように心がけました。
コストを抑えれるように一部でスポットインスタンスおよび、
リザーブドインスタンスを利用してます。
security には細心の注意を払う必要があったので、
できるだけpublicに出てるサーバを減らした。
Blue-Green
Deployment
deployフロー詳細
アプリの

ビルド
ami作成用

サーバ

立ち上げ
ミドルウェア

provisioning
deploy & 

serverspecテ
スト
ami化 & 

起動設定作成
auto-scaling-
group作成
serverspecテ
スト実施

(コケたらrollback)
green環境

サービスイン
blue環境

ステータスを

削除まちへ
deploy完了
build & ami作成
deploy実行
高速化のポイント
• ami作成の自動化
• github上で p-r merge後、buildサーバへ通知
• build → ami作成 までを実行
• deploy 時は、先ほど作成した ami を使って deploy
• amiの使い回し
• ミドルウェアに変更が入らない場合は、使いまわし。
• deployに必要なインスタンス起動回数が2 => 1回へ減る
• 1日1回、毎朝3時に作りなおす
これでもやっぱり
時間がかかる。
• インスタンスの立ち上げに時間がかかる。
• ELBが「In Service」になるまでが時間が
かかる。
時間のかかるポイント
• pairs 側は、pull 型 deploy を検討中です。
• マイクロサービスについてはECSを使った
Blue-Green Deployment を検討中です。
• 詳しくは弊社社員が発表した下記を参照してください。
• http://www.slideshare.net/takuyaonda3/
aws-55067427
nginx
+
go application
• application は supervisor を使ってデーモン化しました。
• nginx -> golang application は unix domain socket を
利用しました。
• graceful restart を実現する為に、Einhorn を利用しま
した。
unix domain socketにした理由
nginx -> golang application を tcp で接続していたら、
golang application間のコネクションが大量に発生して、
サーバのtcp のリソースが枯渇した。
TCP localhost:9000->localhost:26732 (CLOSE-WAIT)
TCP localhost:9000->localhost:27743 (CLOSE-WAIT)
TCP localhost:9000->localhost:27172 (CLOSE-WAIT)
TCP localhost:9000->localhost:26834 (CLOSE-WAIT)
TCP localhost:9000->localhost:27014 (CLOSE-WAIT)
TCP localhost:9000->localhost:27745 (CLOSE-WAIT)
TCP localhost:9000->localhost:27747 (CLOSE-WAIT)
TCP localhost:9000->localhost:27749 (CLOSE-WAIT)
TCP localhost:9000->localhost:27752 (CLOSE-WAIT)
TCP localhost:9000->localhost:27756 (CLOSE-WAIT)
TCP localhost:9000->localhost:27758 (CLOSE-WAIT)
チューニングポイント
台湾ではまだあまり回線速度が早くないので gzip 圧縮した
り、akamai を利用して出来るだけ低レイテンシーでレスポ
ンスを返すように心がけてます。
Einhornについて
• Einhorn の話しについては、Go Conference 2015
Winterで 弊社社員が発表した下記に詳しく書いてます。
• http://go-talks.appspot.com/github.com/yyoshiki41/
go-graceful-upgrade/main.slide#1
EC2 on MySQL
なぜRDSじゃないの?
• 微妙に痒いところに手が届かなかった。
• AWS 起因の障害に引っ張られたくなかった。
• ブラックボックスになってる箇所を減らしかった。
• バージョンアップになるべく早く対応したかった。
なぜAuroraじゃないの?
• 新規プロダクトではAurora使ってます。
• Aurora の 出るタイミングが絶妙すぎていまのデータを
使ってのテストが十分にできなかった。
• パフォーマンステストをしてみたら、EC2 on MySQL を
チューニングしたものでも十分にパフォーマンスが出せた。
比較
スペック:r3.2xlarge
VCPU:8
メモリサイズ:61GB
リージョン:東京
スペック:r3.2xlarge
VCPU:8
メモリ:61GB
リージョン:東京
プロビジョンド IOPS(SSD)
スペック:r3.2xlarge
VCPU:8
メモリ:61GB
リージョン:東京
プロビジョンド IOPS(SSD)
EC2 on MySQL Aurora RDS
sysbench を使ってベンチマーク。
EC2 on MySQL Aurora
EC2 on MySQL RDS
デメリット?
• fail overやbackup を自分で実装する必要がある。
• file system まわりも自分でチューニングする必要があ
る。
• 運用が大変
• 運用が大変
メリット
• 新しいバージョンをすぐに試す事ができる
• file system まわりのチューニングも楽しい。
• MySQL まわりで問題があっても調査がしやすい。
Stress Tool
Gatling を使った
負荷テスト
Gatling ?
• Scalaで書かれている 負荷テスト tool です。
• http://gatling.io/#/download からダウンロードして解
凍すれば使えます。
• recorder を使って簡単にシナリオ作成ができます。
recorder起動のしかた。
./bin 以下に recorder.sh があるのでこれを実行。
Gatling setup
PackageとWhitelist,BlacklistのあたりをいじっておけばOKです。
レコーディングデバイスの設定
・今回はめちゃ簡単なFireFoxでレコーディングします。
・環境設定 -> 詳細 -> ネットワーク -> 接続設定
・「手動でプロキシを設定する」を選択して、ホストを 127.0.0.1
のポートを 8000 にしてあげます。
レコーディング開始
・上記まで設定が終わったら、Gatlingのレコーダーに戻って start! ボ
タンでレコーディング開始です。
・ブラウザで遷移をしているとどんどんGatlingにリクエストが入って
きます。
・これでレコーディング完了です。
レコーディングされた
シナリオを確認
• ./user-files/simulations/ 以下に設定したシナリオ名のディ
レクトリができていてさらにその中に
RecordedSimulation.scala というscalaファイルが作成
されています。
• ./bin/gatling.sh で負荷テストを実行すると先ほど作成し
たシナリオでGatlingが打てるようになっています。
• シナリオをうまい具合にカスタマイズしてあげたりすると
楽しいGatlingライフになってきます。
• 負荷テストはとても大切。
• AWSだからこそ、インスタンスサイズを落
としてみて負荷テストした方がボトルネッ
クがはっきりわかる。
Monitoring
mackerelのいいとこ
• monitoring server を自前運用しなくていい。
• 外形監視が便利。
• 導入がとても簡単。
• 日本語でサポートしくれるので何かあってもすぐに連絡で
きる。
• 開発が活発。
• plugin の開発が簡単。
go application の監視
golang-stats-api-handlerでメトリクスを取得
mackerel-plugin-gostatsを作成
gostats.cpu_num.gomaxprocs 4 1449332314
gostats.goroutine_num.goroutine_num2537 1449332314
gostats.cgo_call_num.cgo_call_num 8133023 1449332314
gostats.memory.memory_alloc 55116600 1449332314
gostats.memory.memory_total_alloc 668213200288 1449332314
gostats.memory.memory_sys 244588504 1449332314
gostats.memory.memory_lookups 7882769 1449332314
gostats.memory.memory_mallocs 12301923213 1449332314
gostats.memory.memory_frees 12301325814 1449332314
gostats.memory.memory_stack 6619136 1449332314
gostats.heap.heap_alloc 55116600 1449332314
gostats.heap.heap_sys 174587904 1449332314
gostats.heap.heap_idle 93872128 1449332314
gostats.heap.heap_inuse 80715776 1449332314
gostats.heap.heap_released 43384832 1449332314
gostats.heap.heap_objects 597399 1449332314
go application の監視
slack に通知
Analysis
• fluentd → bigquery
• embulk → bigquery
BigQuery は安くて早い
BigQuery を使うポイント
• BigQueryは update/delete ができないのでview table
を作成。
• WHERE句には何を書いてもテーブルをフルスキャンして
しまうので、daily/monthlyのtableを作成。
• data を極力減らすように送る際に加工する。
• data をロストしても後でリカバリできるように、S3にも
ログファイルをあげてます。
re:dash を使った
解析
re:dash?
• 「Open Source Data Collaboration and Visualization Platform」です。
• 多くのデータソースに対応しており、クエリの定期実行や権限制限・APIといった機能
が豊富なことに加え、アップデートも活発なため最近注目を浴びています。
• データソースは、PostgreSQL(Redshift), MySQL, BigQuery, Graphite, MongoDB,
Elasticsearch, InfluxDB, Presto, Hive, Impala, URL, Google Spreadsheets, Python
コードに対応しています。
• AWSやGoogle Compute Engineの場合はセットアップ済みのイメージが用意されてる
ので、それを利用すると楽です。
エウレカでの利用
BigQuery / MySQL に接続して、様々な情報を取得して分
析に利用してます。
まとめ
• 怒涛の6ヶ月でした。(エンジニアとしてはかなり楽しかったです。)
• エウレカはやったもの勝ちなので新しいアプリケーションへを導入するのにも敷居が低
い。
• 今回構成がかなり変わって、勉強しなければいけない所が沢山増えたけれど手元で動か
すよりproduction で使う事で色々な発見がある。
• SPOFがほぼなくなった事により安心した年末が過ごせそう。
• やっぱ楽したいので楽できる所はアウトソースするのが吉。
• やっぱエンジニアとして楽しいの方がいいですよね。
CONFIDENTIAL
Thank you :)
Thank you :)
大規模アプリケーションの
インフラを再設計(裏)
eureka Go 2015/12/12
目次
• ついやりがちなネットワーク構成。
• テストがないシェルスクリプトは辛い。
• モバイルのエンドポイントはわけましょう。
• 突然押し寄せてくるコネクション問題。
• 終わらないレプリケーション。
• のtable schema と 消えないデータ
ついやりがちな
ネットワーク構成
入社時の構成
• vpcの中にsubnetが各コンポーネント毎に存在する。
• vpc間の接続ができない。
• 各サーバにEIPがあたって外にでれる為グローバルとの境
界線がいっぱい存在する。
• gateway serverが沢山あって運用大変。
変更した箇所
• public / app server / database の 3つに変更した。
• vpc間のピアリング接続することで通信が可能。
• nat serverを作成してpublicとprivateの境界はっきりさ
せた。
• gateway serverの台数が減らせた。
テストがない
シェルスクリプトが辛い
• build - deploy のスクリプトが シェルで書かれたがなぜ
かよくエラーでハマる。
• かなり秘伝のタレ化してて の処理が入ってる。
• この処理いらないと思ってけしたら動かなくなった…
perlbrew で perl を
install
が…未だにperl書いて
るのは僕だけですw
モバイルの
エンドポイントは
わけましょう。
• モバイルのアクセスのエンドポインを分けたら、一気に負
荷が下がった!!!
• これは勝つるって思った瞬間です。
突然押し寄せてくる
コネクション問題
終わらない
レプリケーション
のtable schema
と
消えないデータ
158個のtable が存在
します。
• `action_id` varchar(190) NOT NULL 
• えっ action_id って id じゃないんだ。
のカラム名
• PRIMARY KEY (`user_id`,`record_time`), KEY
`idx_user_id` (`user_id`)
• えっ idx_user_id 不要だと思うんですけど。
不要なindex
• user_information table が 600G !!!
• 各ユーザへのお知らせを1ユーザ毎に保存…
• そもそも不要なデータが消えてない…
• しかも圧縮されてない…
• ユーザが増えれば死ぬ未来しかみえない…
増え続けるデータ
CONFIDENTIAL
Thank you :)
Thank you :)

Eureka go 2015_12_12