YAPC::Asia 2015 1日目
Consulと自作OSSを活用した100台規模のWebサービス運用
- @fujiwara
- Agenda
- 最近のロンチサービスは使い方はいろいろだけど全てにConsulが入っている
Lobi
- Playdog、ゲームのストリーミング配信SDKの開発など
- '10〜、ap-northeast-1登場以前のAWSで始まった
- App2, DB2の4台とか
- '13.11 ~ AWS東京リージョン Maxで100台くらい
- AppのASG、SDKのASG、画像変換のASG、ストリーミング、バッチサーバ、ログ集約/解析(Norikra)、動画変換ASG
- モダンになるまえからやってるのでマネージドサービスより役割の違うEC2が多い
- ホストの種類が多い
- Perl(アプリ), Node.js(ストリーミング), Go(ストリーミング)
ミドルウェアいろいろ
AWS移行後の悩み
Consul
- 本番運用しているのは会場で3%くらい
- Agent
- Server
- クラスタ内の特定の奇数台で動いている
- うち1台がLeader
- 一人だとLeadarになれない、過半数(→最低でも2/3台)の賛成で選出される
- Raft
- クラスタ内の特定の奇数台で動いている
Service / Node Discovery
- サービス内のnode
- Service Definition of App
- :8500にRESTポート
- 最近外部DNS連携が出来るようになりました
Health Checking by script
- ユーザ定義のヘルスチェックコマンドを実行
- KVS
- memcachedのフラグにあたるユーザ定義を付けれる
- パフォーマンスはリーダーノードに向かって40000qps
- 他のノードはリーダーに問い合わせるので下がる
- かなり早い、遠慮なくGETできます
- PUTは427qps、そんなに頻繁に置かないはずなので深刻ではないハズ
- stale modeにするとリーダ以外でも応答できる
内部DNSとしてConsulを使う
- :8600に向けないといけない
- /etc/resolv.confではポート指定は無理
- 無理やり:53に向けるにはroot特権が必要で怖い
- :53は再帰問い合わせしないといけない、Consulはcache機能がないので難しい
- dnsmasq, bindなどからConsulをフォワードする
- resulv.conで
(node+service).consul
を検索ドメインに指定- node/service名だけで検索できる
- BINDは夏休み取りたいので使いません
Deployment Table
- Server node: 本番では最低3台、5台が推奨
- 3と4では耐障害性は変わらない
- 2CPU、RAM20MB、2MBストレージ、くらいの消費
- RAMとストレージはKVS次第
- Serverには専用ホストが必要か
- たぶん不要
- ディスクIOが激しいとRaftでリーダーが入れ替わりがちなのでIOの穏やかな所が良い
- デーモナイズ機構がないのでdaemontoolなんかでお願いします
- start_join
- consul serverには固定サーバ
- Atlas連携
- 大統一理論
- Atlasのトークンで全部引っ張れる
- 10ノードまで無料、それ以降は40USD/m、join自動化のためだけには高い
Server nodeのフェイルオーバーは自動、リーダーが落ちたら再選出が終わるまでDNSが引けなくなる
運用中のUpgrade
- クラスタは一回立てると落とせない
- ローリングアップデート方式
- 0.2時代からproductionに入れて1年運用してますが、agentが落ちたりクラスタが崩壊したりした記憶はないです
- Quorumが満たせないレベルまで減るとクラスタが崩壊します、データが飛んでしまう
- KVSは定期的にバックアップ、ユーザデータは絶対に入れないように
- Quorumが満たせないレベルまで減るとクラスタが崩壊します、データが飛んでしまう
オートスケール環境で使う
- Lobiの動画変換機能(ElasticTranscoder)
- S3に上げてキックしたら変換してくれる
- ちょっとお高い
- 1投稿2分で25円、1万人分で25万円
- S3に上げてキックしたら変換してくれる
- モンストにSDK導入しました
- 家が立つレベルでお金が飛んでしまう!!!
- →SPOTで変換する
- cc.88xlarge(32core) = 0.45USD/h
- 1/10〜1/100にまで削減
- ピーク時で45台くらいまでスケール、最低2台
スケールアウトはJobの量で
- リアルタイム性は低いので遅れてもOK
自動でuniqueなホスト名を付ける、join、Chef,デプロイ...
- user-dataでユニークホストを名付ける
- ChefのノードをConsulのKVに入れる
- Stretcherでdeploy
- Zabbixに登録
- OS起動時に登録するとアラートが飛んでしまう
Stretcherを利用したデプロイ
- 自作しました
- ConsulとSerfで動くデプロイツール
- これまでは中央サーバからのデプロイ
- このpush型はオートスケールに対応できない
- pull型で中途半端なときに持っていかれると困る
- gruntやGoの生成物を格納したくない
- デプロイのたびにAMI再生成はやりたくない、10デプロイ/日もできない
Stretcher
sorah/mamiya
とAWS CodeDeployとほぼほぼ同じですビルドしたものをtarにしてS3へ
YAMLの定義ファイルmanifestもS3へ
- 各ホストのConsulがtarとYAMLを読んでデプロイしてくる
Consul Event
- ビルドプロセスはStretcherには関与しない
各クライアントでtar.gzを一旦TMPDIRに展開して、ローカルrsync
Lobiでのデプロイ例
- tgz 200MB
- CPAN 110MB
- nade_modules 10MBx5
- Go app binaries 8MBx5
- static files(S3に逃したい)
- ビルドで1分
- パックとアップロードで1分
- イベント通知から10~30秒
- S3は200MBを100並列で取得してもびくともしない、おそろしく頑健
- ロールバックで威力を発揮
- 元のmanifestだけ送ればOK
Chef/Serverspecの通知を一覧したい
- 100台で失敗すると100行エラーが出て阿鼻叫喚
Consul KV Dashboard
Blocking query
- 次のリクエストが来るまでリクエストを待たせる機構
オートスケールでのデプロイのtips
- 最新のmanifestをConsulのKVに格納
- AMIに残ってる古いアプリが起動すると事故る
- 最新のデプロイID出ない場合は起動しない
- 初回起動時のみ、daemontoolを起こす前にKVとローカルの値を比較する
- 最新のデプロイID出ない場合は起動しない
bash-completionでsshのホスト名補完
- known_hostsを参照するときのfunctionを.bash_profileで上書きしてKVを参照するようにするとすっきりする
まとめ
- Consulは機能豊富、だが使いたい機能だけ使えば良い
- KV, Event, Health Check...
- consul-templateで動的LB設定
Q&A
- rsyncが滑った時(消せないファイルがある)はStretcher全体がabortするように設計
- ためにし1台、のときはeventを1台に送る
- consul-lockを使えばn=5にすると5台ずつ完了を待って実行していく
- あとはグループを分けるとかしてBlue-Greenっぽい挙動を作る感じ
- 同じアプリをポート番号だけ変えて複数持つ、みたいなケースにも使える?
- SRVレコードを引くとポート番号を含めたディスカバリができる
- サービス名、サービスIDは一意に
- StretcherとかDashboardはどれくらいで実装?
うっかりをなくす技術
- @karupanerura
人間は失敗する生き物である
- ヒューマンエラー
- 安全工学とかですごい研究されてる
この観点から見たアプリケーション開発
Agenda
- ヒューマンエラー
- どのようにして気づくのか
- どのようにエンジニアリングでなくしていくか
Huan Error
- We neet safe code.
- アプリをクラッシュさせたくない
- うっかり間違えるし、すごい工数が発生するときもある
- ヒューマンエラー≒うっかりミス
- ファクター
- 人的要因
- うっかり
- そもそもの間違い
- 安全工学的には意識レベルを意図的に高める
- 指差し確認、体と声を動かしながら意識を高める
- NKY
- マネジメント要因
- ワークフロー改善、ドキュメンテーション、自動化で対策
- 環境要因
- 理解しづらいもの{コード、仕様、手順}
- フェイルセーフにする、ミスに気付けるようにする
- 人的要因
near-miss
- ヒヤリハット
- 実際に顕在化してないミス
- ハインリッヒの法則
- 1つの重大なインシデントの裏には30個の小さなインシデントがあり、そこにはさらに300のニアミスがある
- それらはほぼ同じ要因で起きている
- ニアミスの要因をなくしていけば、大きなミスも無くせる
- 実際に損害を出さないので、非常に気づきにくい
- どうやって集める?
- github issues
- 一覧できることが重要
- コードレビュー
- 他の開発者の視点を取り込める
- 認識が違っていたらマズい合図
エンジニアリングによるアプローチ
環境要因はエンジニアリングのアプローチが非常に有効
break
- 五反田のおにやんまのうどんをバックに
easy to understand
- 読みやすいコード
- 説明的な命名
- 副作用を減らす
"Art of Readable Code"
- 読んで下さい!それでこの話は終わりです!
ドキュメント・コメント
- そのコードの読み手は、コードに書かれていないことはわからない
- なぜこのアプローチ・ワークアラウンドが必要なのか
- これらを書いておけば、正しい取捨選択に役立つ
副作用をなくす
Simple ways
間違いに気づきやすくする技術
型制約
strict.pm
- Perl5標準
- 未定義変数の参照をコンパイルエラーしてくれる
- soft referenceなどの危険な機能を制限してくれる
warnings.pm
- perlは非常にコンテクストに敏感
'3:' + 2; # => 5 (!?)
+
の手前をatoi
してしまう- こんなケースの時に警告を出してくれる
コードの静的解析
perlclitic
perllint
実行せずに間違いに気づく
swiftにおける
int?
guard.pm
- GoとSwiftの
defer
に相当
Poka-yoke
まとめ
- ニアミスをなくしてインシデントをなくす
- 簡単に使えること、間違いに気づきやすいこと
Q&A
- 一番うっかりが減ったアプローチは
- 静的型付け言語を触ると補完の強みも相まって想定外の挙動はかなり減った気がする
- コメントがコードを反映してない現象への対策
- コードをみんなでレビューして、その場でコメントをコードと同等にレビュー対象にしてもらう
- コードとコメントの整合性を機械的にチェックできる機構ができれば良い未来がありそう
- うっかりが出そうな、ニオうコードの傾向は
- 他の人の書いたAPIをどのように自分が叩くだろうか、といった考え方で触れてみる
- コードから連想する使い方をそのままぶつけてみる
- 静的解析ツールの、理不尽な指摘への対処
- perlcliticなんかは重箱の隅をつつく感じの理不尽な指摘がある
- それをほったらかしても問題が出ない、と経験的に確信が持てるものなら無視しても良いと思う
- たとえば
undef
を返すコードが怒られる- スカラコンテキストだと
undef
、リストコンテキストだと[undef]
が返って罠っぽい
- スカラコンテキストだと
- たとえば
- 自分は破るときは意図して破るようにしています
LT
良いオフィスランキング
- 941
- くしい
- '10~13 YAPC::Asia主催
- いろんな会社に訪問して紹介してます
- 941::BLOGのすごいところ
- 業界の知名度が抜群
もっと選択肢は有るよ!と昔の自分に言い聞かせたかった
良いオフィスランキング
- NHN Japan
- Gree
- 旧Cookpad
- 現Wantedly
- 旧Freakout
- ネクストイノベーション
- リッチマン・プアウーマンのモデル
- 超リッチ: Microsoft
- 頭おかしい: バーグハンバーグバーグ
Gitのつくりかた
- DQNEO
- どきゅねお
- 今月メルカリに就職しました
- "gitを理解する最良の方法、それはgitを自ら作ることです" --DQNEO
- gitはVCS、というよりコンテンツ管理システム
- キーバリューストア
- キーはSHA1ハッシュ
- バリューはzlib圧縮するされた何か
- キーバリューストア
- "hello world\n"
- blob 12\0hello world\n
- 圧縮して保存: git add
- 解凍して取得: git cat-file -p
- git checkoutは
SaaSで作る僕らの障害対応術
- @papix
- GAIAX
- みなさんびっくりどっきりメカで対応体制を作ってると思います
- 障害は、ただ治ればOKではありません
- 何故起きたのか、どう解決したのか、どう再発防止するのか
- 今回はSaaSを組み合わせた障害対応の仕組みを作ってみました
Mackerel::Webhok::Manager
- Meckerelを軸とした障害対応の仕組み
- Webhookを投げて再現
- 「今ホントにアラート飛んできた」
- Qiita:TeamとTwilioに通知
- Reactioを使って対応
- 障害はなくなりません
- (さらに障害アラート)
- 備えあれば憂いなし
cpm
- Shoichi Kaji
cpm
cpanm --dev App::cpm
Norikraで作るPHP検知システム
- Masanori Nagano
- PHPの例外を検知し通知するシステム
RSSをざっくりクロールしてゆるふわにパース
- 角田さん
- @ace_project
- Feedwind
- 事例(クロール)
- 配信元に連絡して解除してもらう
- 連絡がつかない場合はプロキシを使って乗り越えている
- 事例(パース)
Mojo::DOM
- パースできないやつにぶつかりサービスがダウン
<br<
<- (!?)- 壊れてるDOMをパースできなかった
- 今後のことも考えてゆるふわにパースするようにしました
- できるだけ集めてできるだけパースしてあげよう、という姿勢が大事なんでないかと思います
Slack+Hubotでお前の一番好きな二次元嫁キャラと一緒に仕事をする
- @sairoutine
- さい
- 趣味プログラミングしてますか?
- 結構やってますね、ほいほいほいほい
- だいたい一人でやるので寂しいですよね?
- 事例: @marisa
- 自分と@marisaでチームを作りました
- Botとふたりきりのチームってとこ、ミソですよ
- 他の人としゃべることがないようにしておく
- cronモジュールは全部やるのは面倒なので、jsonにまとめて食べさせます
tw ......
で投稿だけdeploy
、issue list
、trello add
- 一人なんで自分でやったほうが早い気がするけど、botが自分のために動いてくれる、嫁っぽい!
YAPC?雨事情
- @likk
- Mobile Factory
- 会社を出たら雨
- エレベーターを降りてから気づく、傘はオフィス
- 戻るの面倒臭い!
- 定時に五反田で雨が降ってたら通知したい
- tenki.jp
- newして東京の場所を指定すると画像が出てくる
- 拡大して五反田の位置をマッピング
GD::Image
で画像差分検知、差分がアレば雨とみなす
- エレベーターを降りてから気づく、傘はオフィス
- すごい過去にも遡れる!
- 歴代YAPCの雨事情を起こしてみました、懇親会だけ雨みたいな日も
- 雨通知アプリametto/熱中症検知アプリachitto
PUGS ON STACK
- HIRATARA
- Freakout
- PUGS
- ghc 7.8でビルド
- ghcはバリバリ非互換変更があり、最新ではビルドできない
- 7.10とstackでビルドできるようにしてPR送ったら速攻でリリースしてもらえました
- ベンチしてみたらめっちゃ遅い!
- 50ms or dieってことで最適化してみました
- モナド変換を潰したら早くなるので潰してみる
- Rakudo実装より早い!?
- 10000万回にすると逆転
PHPの話をします
gongoZ
- 肉体言語を作ったりEmacs内部で一句を見つけるelispを書いたりしてます
- PHP5.4のセキュリティサポートは'15 9/14までです
- 5.3の壁
- うち最大のものが
register globals
- 「安全でないコードを書くことが極めて容易になることを意味します。」
- 未だonのアプリの特徴
- includeしてきた変数と見分けがつかない
- うち最大のものが
- php.netにのってる
- register_globalsの影響を受ける変数を逐次定義
- 使ってはいけない、間違っています
- php.netにない隠された仕様
$_FILES
- 個別にマッピングされる
- 「その結果に驚くことでしょう。」
- ちゃんと書け
$_SESSIONS
も対象です- リファレンス渡しで来てる!!!