Edited at

YAPC::Asia 2015 聴講メモ: 1日目版

More than 3 years have passed since last update.


全体的なまとめ

インフラ中心にセッションを選んだのもあったけど、Consulの話が連続していた


11:00 世界展開する大規模ウェブサービスのデプロイを支える技術


TL;DR

GH:EのWebHookやGitをうまく使うことでシンプルで安定したデプロイを、スケーラビリティをもった形で実現している

Consul + Stretcherが気になったので次のセッションはそれを聞くことにした


MiiVerseのデプロイ


  • Pull型のデプロイ方式


    • Capistrano2とGit


      • 数台規模なら問題ない

      • リージョンをまたぐデプロイが遅い

      • 数百台から同時にGit pullするとGitサーバーが死ぬ


        • プロダクトごとにロールを分けて分散

        • ホストごとにランダムsleepというかっこいいやりかたw

        • Gitスレーブサーバーを各リージョンに置く


          • 10分に一度lsyncdで監視、変更があったらrsyncで同期

          • lsyncdのディレクトリ監視上限(デフォルト)にあたってしまった









  • Mackerelの活用


    • APIでロールを管理・取得


      • MackerelにCapistranoと同じロールを設定する

      • Mackerelのメトリクスをみてオートスケール





  • 手作業することもある


Gitリポジトリの同期


  • 開発フロー


    • タスク管理、コードレビューなどはRedmine上でやっていた

    • 最近GH:Eを導入し、RedmineでやっていたコードレビューはGH:E上に移行している

    • メインのタスク管理は今でもRedmineで

    • デプロイは自前Gitサーバー、GH:Eはレビュー甩という役割にわかれている


      • それゆえ、現状はpushするときに2つのリポジトリーにpushする必要がある

      • GH:E上ではPRをマージしない運用


        • GH:E上でコミットが進んでしまうと、それをpullしてpushして、、が煩雑になるため








同期の改善方法について


  • hesokuri


    • 運用にあわなかったので見送り



  • ghm


    • リポジトリーの同期や、特定のサーバーへの同期一時停止も可能

    • 同期が並列化されていないため、規模が大きくなっていくにしたがって遅くなっていく


      • 同期が終わる前にデプロイされてしまう問題が起きた

      • 同期の開始、終了をSlackで通知するようにして運用でカバー



    • 結局採用は見送った



  • 独自実装することにした


    • Perl5で実装。他のシステムと同じ言語にした

    • 現在はMiiVerseサブシステムのみで運用

    • REST APIで操作できる


      • マスター昇格、スレーブ降格や、同期開始などがAPI経由でできる



    • 同期システムはマスター(GH:E)のリポジトリーからpull、スレーブのリポジトリーにpush


      • WebHookでGH:Eから同期システムに通知

      • DBから同期先のリポジトリを取得

      • 同期先に対してpush



    • ポイント


      • WebHookで連携できるのでGH:E以外でも使いやすい

      • スケーラビリティを確保できた

      • 同期はgitコマンドだけて行うため安全(fetch, pull, push)






今後のデプロイ手法


  • デプロイにおける2つの手法


    • デプロイ対象をすべてコミットしておく


      • ビルドしたものも置くのでリポジトリが肥大化する



    • ソースだけ入れておいてビルドは各環境で


      • 各環境の際に振り回される

      • ビルドが長くなる






Consul + Stretcher


  • 配布物をS3などに置く


    • デプロイ手順(manifest)も一緒に

    • Gitに負荷がかからない



  • Consulのイベントでデプロイ対象に通知


    • 並列実行できる



  • 流れ


    • GH:Eにpush

    • WebHook経由でJenkinsでビルド

    • JenkinsからS3に成果物をアップロード

    • Consulからデプロイイベント発行

    • デプロイ対象のConsulノードが、S3からmanifest,成果物を取得してデプロイ



  • ベンチマーク


    • 100台へデプロイ


      • モジュールインストールなし、コード更新とプロセス再起動だけ

      • Cap2だと1100秒以上

      • Consul+Stretcherは49秒。40倍高速化


        • モジュール更新有りでも200秒ぐらい







  • 今後の展開


    • サブシステムはオートスケールをMackerelと連携してうまく使いたい

    • MiiVerse本体でも使いたい




13:10 Consulと自作OSSを活用した100台規模のWebサービス運用


TL;DR

Consulはいろいろ機能があるが、使いたい機能だけつかうこともできる。あと、S3はすごい。


Lobiインフラの変遷


  • AWS−>オンプレ->AWS


    • EC2がかなり多い


      • 役割も多岐にわたる

      • 言語はPerlがメインだがNode.js, Goも使う

      • ミドルウェアもいろいろ



    • AWS移行の悩み


      • 内部DNSがなかった

      • hostsを自前生成、時前更新

      • DNSは運用したくない(今はRoute 53でできる)

      • ホストの追加・更新の頻度が高い、オートスケールもしたい

      • 内部DSNの役割として Consul を採用






Consul


  • Agent


    • クラスタ内のノード上で動作する

    • DNS, HTTPインターフェイスを提供

    • Agent同士が通信



  • Server


    • Raftでリーダー選出

    • 最低3台が推奨



  • サービスディスカバリ、ノードディスカバリ


    • サービスはJSONで定義する

    • サービス、ノードはDNSに問い合わせできる


      • リストは順不同

      • UDPで問い合わせすると4つ以上あっても3つまでしか返ってこない。TCPなら全件取れる



    • 死活監視に失敗したものを取得することも可能



  • 死活監視


    • スクリプトで死活監視可能。exitコードで判断



  • KVS


内部DNSとしてConsulを使う


  • 53ポートが必要になるがAgentをRootで動かしたくない

  • dnsmasqでフォワードしてConsulに問い合わせるようにしている


本番環境


  • サーバーは3or5台


    • Agentと同居も可能だが、DiskIOがきつくないホストで




高可用性


  • リーダーが落ちるとその間DNSが使えなくなる。再選出には2-3秒


    • Stale modeを使えばリーダー未選出でも取得できるようになる



  • 運用中のUpgrade


    • Rolling Upgrade




安定性


  • Agentは安定している

  • オペミスはあるのでKVは定期バックアップ。あとで入れ直せないようなユーザーデータなどは入れない


Spot instanceで動画変換


  • 圧倒的に安い

  • ElasticTranscoderの1/10ぐらいで使える


  • ホスト名を一意にしたいのでインスタンスIDを使う

  • DeployにはStretcherを使う

  • デプロイ完了前に監視が始まると不要なアラートが飛んでしまう


  • push型デプロイしていたが、オートスケールに対応できない

  • 各ホストからrsyncさせるとビルド中のものがもってかれる

  • 各ホストからgit pullするとビルド成果物をGitに置く必要がある

  • AWSじゃなくても動くもの

  • rsyncしてコマンド実行するというフローを踏襲

  • Consulイベントで通知


Conway's Law of Distributed Work


コンウェイの法則


システムを設計する組織は、その構造をそっくりまねた構造の設計を生み出してしまう



メモ


  • テキストチャット、通話、コードレビュー、共有ストレージ、ドキュメント共有など、あらゆる方法で

  • コミットメッセージを伝わるように書く

  • メールはコラボレーションに向かない

  • リモートワーク中心でもon-site Meetupする


    • セッションの機会をつくったり、ランチに行ったり。お互いを知る機会



  • リモートワークでは常にアウトプットする。ちょっと多いぐらいに


    • 自分が考えていること、思ったこととかを伝える機会がリモートだと起こりにくい



  • 仕事以外のコンテキストで話せる場所をつくる(#generalなど)

  • リモートワークにおいてもCAP定理が成り立つ。すべてを満たすことは難しい

  • リモートワークで働きすぎる問題


    • 自分のスケジュールを厳密に管理するように意識する

    • 自分の責務をチームに対してはっきりさせる




うっかりをなくす技術