Slide 1

Slide 1 text

2014/08/29 YAPC Asia 2014 Tsuyoshi Torii (@toritori0318) Bascule Inc. 作られて 消えていく 泡 ように儚いクラスタ 運用話

Slide 2

Slide 2 text

自己紹介 • 鳥居 剛司 Tsuyoshi Torii • @toritori0318 • 株式会社バスキュール • Node.js / Python / Perl / Ruby • 二児 父

Slide 3

Slide 3 text

DEV Ops

Slide 4

Slide 4 text

主にTVとスマートフォンを 同期して云々〜 といった仕事をしています

Slide 5

Slide 5 text

BloodyTube 血液型対抗レースに視聴者が参加して番組を構成する完全インタラクティブTV バスキュール 企画・提供・制作 視聴者 スマホから 参加状況がテレビに反映される 優勝チームに リアル店舗で利用できるPontaポイントが提供される B2O2O(Broadcast to Online to Offline)マーケティング施策にもチャレンジ http://pieces.bascule.co.jp/2014/bloodytube/en/

Slide 6

Slide 6 text

https://www.bascule-go.com/product/

Slide 7

Slide 7 text

About MIES • Sonischooter – リアルタイム同期/タイムライン/Elastic Socket.ioクラスタ • Harvestmoon – ユーザアクション(投票/投稿など)を受付/集計 • Persona – MIES/コンシューマユーザ統合 – SNS連携 • Kanten(tofuクローン) – 画像変換 • ELF – 視聴ログ集計/解析 • Punisher – TV案件用ベンチマーククラスタ

Slide 8

Slide 8 text

今日話すこと

Slide 9

Slide 9 text

•TV案件 特徴 •性能評価とか監視とか •運用改善 話そ 1 •運用改善 話そ 2 •今後改善していきたいこと

Slide 10

Slide 10 text

今日話さないこと

Slide 11

Slide 11 text

•フロントエンド 話 •アプリケーションレイヤ 話 •闇 – キャパシティガ〜 – クラウドフロントガ〜 – イーエルビーガ〜 – ジーエーイーガ〜

Slide 12

Slide 12 text

TV案件 特徴

Slide 13

Slide 13 text

運用サイクル

Slide 14

Slide 14 text

運用例 • 1週間前にティザーサイト公開 – ロールごとに最小インスタンス数で構築 • 放送日前日〜当日 – インスタンスを数十台〜数百台起動 – 放送時間に張り付き監視 – 終了後バックアップ • 当日〜数日後 – 全て インスタンスを一括削除

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

TV連動運用 • 基本 「放送時間」 – 案件によって異なる • ティザーサイトがある場合も • 1回きり/2−3回/毎日/毎週 • 想定ユーザ数バラバラ • コストも割とシビア • 本番稼働しているサーバ(特に放送時間中) に対して変更を行うこと あまりない(*1) (*1)サーバに限る かつ 条件付き

Slide 17

Slide 17 text

負債回収

Slide 18

Slide 18 text

• 特に忙しい時期 – 期末期初/年末年始 • 作ったも 本番終了後に削除 • 0から作り直す/まとまって空いている期間 がある で技術的負債を返済しやすい環境 であるといえる ※あくまで現時点 話

Slide 19

Slide 19 text

ここまでが TV案件 特徴に ついて

Slide 20

Slide 20 text

性能評価/監視 話

Slide 21

Slide 21 text

性能評価

Slide 22

Slide 22 text

アクセスパターンについて

Slide 23

Slide 23 text

• 曜日/時間帯/企画内容からユーザ規模が ある程度想定できる • アクセスパターンをある程度把握できる で、 ど 部分に負荷が集中しやすいか事前に特 定できる • 本番怖い

Slide 24

Slide 24 text

本番怖い

Slide 25

Slide 25 text

一発勝負

Slide 26

Slide 26 text

Punisher

Slide 27

Slide 27 text

Punisher • NodeJS製ベンチマーククラスタ • スクリプトをJavascriptで記述 • 機能 – リアルタイムで開始/停止が可能 – リアルタイム集計(タスク集計 み) – AWS全リージョン対応 • 1コマンドでAWS全リージョン インスタンスを起動/ 分散デプロイ – スポットインスタンス(半)自動入札

Slide 28

Slide 28 text

書いた理由

Slide 29

Slide 29 text

状況を完璧に再現したい

Slide 30

Slide 30 text

シナリオ例 • 30分間に30万人が以下 処理を行う 1. ログイン • 内8割がゲストユーザ/2割がSNS接続ユーザ 2. APIサーバに情報取得 3. 非同期で30秒ごとにhogehogeAPI実行 4. Socketサーバに接続 • 内8割がwebsocket/2割がxhr-polling • 30万接続した状態でブロードキャスト送信 1. 5-15秒後にAPIサーバに対して投票処理 2. etc…

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

(良い)副作用 シナリオを書くことによって 事前にあぶない部分が 判明する

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

安心感

Slide 35

Slide 35 text

監視

Slide 36

Slide 36 text

監視(放送当日以外) • Nagios/Munin • インスタンス タグから自動でコンフィグファイ ルを作成するような自前ツール • メール & IRC > HipChat > Slack • もう少しオシャレにしたい – Sensu〜♪

Slide 37

Slide 37 text

監視(放送日当日) • 負荷が来る日時が予めわかっている – 放送時間に張り付き監視 • 全体的な監視 – CloudWatch – Proteus-Monitor – ソケットクラスタ管理ツール(独自) • ロールごと 個別監視 – top – vmstat – tail –f error.log – App::RedisTop(*1) (*1)https://github.com/toritori0318/p5-App-RedisTop

Slide 38

Slide 38 text

Proteus-Monitor

Slide 39

Slide 39 text

Proteus-Monitor • リアルタイムで各サーバ CPU/Load/Mem/Net/etc…が確認できる • サーバ一覧で確認できる • 設定がお手軽 • Nodeが動的に追加/削除される • 過去 指標 残らない • 名前でフィルタできるようにパッチをあててい る

Slide 40

Slide 40 text

ソケットクラスタ管理ツール

Slide 41

Slide 41 text

ここまでが 性能評価/監視 話

Slide 42

Slide 42 text

運用改善 話 そ 1

Slide 43

Slide 43 text

そ 前にMIES 話 • 最初から「MIESを作るぞ!」という目的があった わけで ない • 案件をこなしていくうちに「こ 部分 共通化でき そう」「こ 部分 汎用化しておくと開発楽だよ 」といった感じでエンジニアが自発的にアイデ アを出し、一つ一つカタチにしていったら自然に 出来上がっていた • 当初 機能重視で開発 • 一つ一つ サービス 独立していて疎結合

Slide 44

Slide 44 text

•3人 –TD or 独自アプリケーション(1名) –TD or MIESコア開発運用(1名) –MIESコア開発運用(1名) Server Team

Slide 45

Slide 45 text

サービス 言語 デプロイ/スケール Person Sonicshooter (リアルタイム同期系) Node.js App::Rad(*1) + Capistrano Harvestmoon (アンケート受付) Python Fabric Persona (認証) Python App::Rad + Capistrano Kanten (画像変換) Perl Yoga(*2) (*2) https://github.com/toritori0318/p5-Yogafire (*1) http://d.hatena.ne.jp/tori243/20120622/1340386116

Slide 46

Slide 46 text

俺が、俺がSPOFだ!

Slide 47

Slide 47 text

問題 • サービス毎 秘伝 タレ – 開発環境/デプロイ/構築/スケール管理 • 1サービス毎に運用出来る人が一人 • 運用コスト – スクリプト化して いるが手順がバラバラ – 他 人が手順を知らない or 知る が大変 – 工数がかかる – お金がかかる

Slide 48

Slide 48 text

解決したいこと • 全て サービスで仕組みを共通化 – 開発フロー/デプロイ/クラスタ構築/スケール管理 • これらを同じインタフェース(コマンド)で統一したい • 引き継ぎしやすくなる • CIしやすくなる • 誰でもミス無く簡単に運用できる • コストダウンに繋がる

Slide 49

Slide 49 text

解決策

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

• 開発フロー/デプロイ – Vagrant + vagrant-aws + chef-deploy • プロビジョニングツール – Chef+Berkshelf • クラスタ管理 – AWS CloudFormation • スケールコントロール – AWS AutoScaling

Slide 52

Slide 52 text

MIES-Provision-Task

Slide 53

Slide 53 text

MIES-Provision-Task • Rakeタスク – 基本的に vagrant/aws-cli ラッパー • Vagant + vagrant-aws + vagrant-amiで統一化 • プロビジョニング Vagrant-chef-solo-provisioner • デプロイ chef-deployリソース • クラスタ管理 CloudFormation • スケール管理 AutoScaling

Slide 54

Slide 54 text

ざっくり補足

Slide 55

Slide 55 text

開発フロー

Slide 56

Slide 56 text

開発フロー • VagrantfileにVM リストを設定(*1) • Chefレシピ(nodes)もVMに合わせて作成(*1) • vagrantコマンド(Rakeでラップ)でVM起動/プロビジョニング /ssh/削除/イメージ保存を行う • 複数サーバへ デプロイ 行わず、AMIを作るだけ 操作を行う (CloudFomation用 AMI) • CloudFormationテンプレート ロール毎に用意しておき、Rakeタ スク内でマージ • クラスタへ 反映 CloudFormationでAMIを更新することで行う (*1) 管理単位 「環境(+ロール)」

Slide 57

Slide 57 text

VM管理例 • local • aws_hm_dev • aws_hm_stg • aws_hm_prd_wap • aws_hm_prd_redis Chefレシピ/AMIもこ 単位で管理

Slide 58

Slide 58 text

イメージ保存

Slide 59

Slide 59 text

イメージ保存 • vagrant-ami – vagrant-aws 設定を共有できる – Packer 不採用 – fakepackerというRakeタスクを作成(後述) % vagrant create-ami --name my-ami \ --desc "My AMI” --tags role=test,environment=dev *参考 http://d.hatena.ne.jp/toritori0318/20130820/1377018423

Slide 60

Slide 60 text

スケール管理

Slide 61

Slide 61 text

スケール管理 • CloudFormation パラメータで指定 • Rakeタスクでも用意しておく(後述)

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

インフラ共通化

Slide 64

Slide 64 text

Chef cookbooks • 全サービスである程度共通化したbase-cookbookを用意 – ユーザ周り – openssh/ntp/timezone/nrpe/etc… – ssh周り 設定 – Alias or symlink( sv=“supervisorctl” / dstat-full=“dstat –Tclmdrn” ) – 最低限 カーネルパラメータ – xbuild (node/python/perl/ruby) / fluentd / munin-node / supervisord – ディレクトリ(アプリケーション/アプリケーションログ/etc…) • ベースAMI作成する時にこれらを適用する

Slide 65

Slide 65 text

Supervisor • Python製デーモン管理ツール • 一度に複数デーモンを操作/自動リスタートなど 対応 • グループ機能を利用 – 例 • supervisorctl restart all # supervisor全管理プロセス • Supervisorctl restart wap: # nginx / webapp • Supervisorctl restart redis: # redis_6379 / redis_6380 / … • Supervisorctl restart worker: # ワーカー全般

Slide 66

Slide 66 text

補足終わり

Slide 67

Slide 67 text

No content

Slide 68

Slide 68 text

Rakeタスク

Slide 69

Slide 69 text

Local VM Task • rake local:up • rake local:provision [deploy=1] • rake local:spec • rake local:destroy • rake local:ssh

Slide 70

Slide 70 text

AWS Task • rake aws:create_baseami • rake aws:up vm= • rake aws:provision vm= [deploy=1] • rake aws:spec vm= • rake aws:destroy vm= • rake aws:ssh vm= • rake aws:create_ami vm= • rake aws:link_instance vm= id= • rake aws:unlink_instance vm=

Slide 71

Slide 71 text

AWS Task • rake aws:fakepacker vm= – up > provision > spec > create_ami > destroy

Slide 72

Slide 72 text

AWS CloudFormation Task • rake aws_cf:generate_cf_json env= • rake aws_cf:create_stack env= • rake aws_cf:update_stack env= [=] • rake aws_cf:delete_stack env=

Slide 73

Slide 73 text

タスクTips • 任意 クックブックを指定 – rake aws:provision vm=hoge chef_json=nodes/base.json • 差分実行 – rake aws:up vm=hoge ami=ami-xxxxxxxxx • 複数タスク実行 – rake aws:up aws:provision aws:create_ami vm=hoge – rake aws:up aws:ssh vm=hoge

Slide 74

Slide 74 text

タスクTips • rake vms

Slide 75

Slide 75 text

No content

Slide 76

Slide 76 text

解決

Slide 77

Slide 77 text

ここまでが 運用改善 話 (そ 1)

Slide 78

Slide 78 text

運用改善 話 そ 2

Slide 79

Slide 79 text

問題 • 同時並行案件が増えてきた… – アプリレイヤーで 複数対応しているが、インフラ …?

Slide 80

Slide 80 text

問題 • 案件による規模 違い – 案件A:ティザー2週間+本番2回:規模10万人 – 案件B:毎週金曜レギュラー:規模1万人 – 案件C:本番1回:規模100万人 • コスト問題 • 単発番組/レギュラー番組 – 他 案件用に改修入りそうだけどレギュラー番組 で動いてる に影響出たらどうしよう…

Slide 81

Slide 81 text

解決案 • AWSアカウントを案件毎に分けて、別クラスタ を構築出来るようにする – 1クラスタにしない理由 • 規模によって別構築したい • 一度本番稼働している環境をいじる が怖い – 1アカウントで管理しない理由 • オペレーションまざる が怖い

Slide 82

Slide 82 text

No content

Slide 83

Slide 83 text

手順共通化したし 行ける で …!

Slide 84

Slide 84 text

現実 • AMI移動 ( or BaseAMI作り直し) • Keypair設定 • AWSキー更新(*1) • アプリケーション 改修 – MySQL/Redisサーバ/インスタンス 数 • 案件/インスタンスタイプに合わせたワーカー数設定 – アプリケーション(gunicorn/cluster/starman)・SQSワーカー など • これら 再設定が終わったらchef実行し直す… • まーめんどい (*1) IAMロール 使わない

Slide 85

Slide 85 text

さらなる解決案

Slide 86

Slide 86 text

案件ごと コンフィグレーションを 一元管理してしまおう

Slide 87

Slide 87 text

Omniscient

Slide 88

Slide 88 text

Omniscient • サービス全体 コンフィグレーションを管理 • 管理軸 – 案件毎/環境毎(dev/staging/stress/production) • アプリケーションコンフィグ(おまけ) – サービス毎 エンドポイント – サービス毎 オプション設定 • インフラコンフィグ – AWS情報 – キャッシュ/Redis/RDS/などDB エンドポイント – ワーカープロセス 数 – 自社製RedisCluster コンフィグ設定

Slide 89

Slide 89 text

Omniscient概要図 クラスタ起動。同時に インスタンス 情報を Omniscientに登録 定期的にOmniscient 情報をPullし、更新され たらサーバに反映 クラスタ起動。同時にイ ンスタンス 情報を Omniscientに登録。 アプリ側 取得して反映

Slide 90

Slide 90 text

移行コスト改善〜♪

Slide 91

Slide 91 text

Serfも検討したが… • Serf – オーケストレーションツール – ゴシッププロトコロルを用い、クラスタ全体に何ら か メッセージを伝搬 • 検証 – 複数軸で管理しようとした時、逆に複雑に • よい方法があれ 〜

Slide 92

Slide 92 text

ここまでが 運用改善 話 (そ 2)

Slide 93

Slide 93 text

さらに改善して いきたいこと

Slide 94

Slide 94 text

やりたいこと一覧 • Docker化 – 開発環境配布 – サービス環境配布 – プロダクション? • MIESサービス統合管理 • Omniscientゲートウェイ計画 • Rakeタスク Golang化

Slide 95

Slide 95 text

まとめ

Slide 96

Slide 96 text

• TV案件で 24時間365日稼働サー ビスと がん るところ/手を抜け るところが違う • 要件に合った運用改善〜 • まだまだ改善したい〜 • 本番怖い

Slide 97

Slide 97 text

おまけ情報 • Rakeタスク/サンプルファイルなどブログにお いてあります でご参照下さい(若干古い) – http://d.hatena.ne.jp/toritori0318/20130916/1379355060 – https://github.com/toritori0318/vagrant-aws-sample

Slide 98

Slide 98 text

ご清聴ありがとう ございました