Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How to support Gunosy's high traffic

y_matsuwitter
November 18, 2015

How to support Gunosy's high traffic

Presentation for TECH VALLEY#6 @Geechs

y_matsuwitter

November 18, 2015
Tweet

More Decks by y_matsuwitter

Other Decks in Programming

Transcript

  1. Gunosyの⾼高負荷アクセスを⽀支える技術 @y_̲matsuwitter Gunosy  Inc. 2015.11

  2. 2 ©Gunosy Inc. ⾃自⼰己紹介 n  Gunosy  Inc. –  開発本部執⾏行行役員 n 

    業務 –  開発全般のマネジメント –  Go⾔言語布教係 n  担当(過去) –  iOS/Android –  Web –  Infrastructure(AWSのみ) n  最近の興味 –  Streaming処理理系の関連製品 –  RNN 松本  勇気  @y_̲matsuwitter
  3. 3 ©Gunosy Inc. Dockerエキスパート養成読本 好評発売中

  4. 4 ©Gunosy Inc. Gunosyについて n  情報キュレーションサービス –  iOS/Androidアプリ –  Web

    n  現在1100万DL突破 n  Go⾔言語を約2年年前に導⼊入
  5. 5 ©Gunosy Inc. 本⽇日のアジェンダ 2013年年  Ruby時代のGunosyAPI l  負荷対策の模索索 l  Rails、そしてSinatraへ

    2014年年  TV  CMとGo導⼊入 l  新技術の検証と導⼊入 l  Go⾔言語と負荷対策 l  トラフィックを⽀支える⼀一つ上を⾏行行く負荷対策 2015年年  似⾮非Microservices時代 l  機能毎・画⾯面毎のサービスを構築、協調しながらの機能拡⼤大 と負荷対策、冗⻑⾧長化 最後に:負荷対策に⼤大切切なこと 2年年近くに渡るGo⾔言語運⽤用を中⼼心とした負荷対策の歴史について
  6. 6 ©Gunosy Inc. 2013年年  Ruby時代のGunosyAPI

  7. 7 ©Gunosy Inc. 初期のGunosyのAPI構成 Railsサーバ群でコストを避けつつスケールする仕組みが必要だった n  ユーザーは数⼗十万⼈人程度度 –  ピーク帯に性能問題が発⽣生 n 

    構成 –  Ruby  on  Rails  w/  unicorn –  RDS –  ELB n  課題 –  定常のピーキーなアクセスに耐え切切れ ない状態 Railsを⽤用いたシンプルなWebサーバ群 Nginx Rails MySQL Redis ELB
  8. 8 ©Gunosy Inc. 基本的な処理理効率率率改善施策 n  基本はDBに対するIOか ら疑う n  メモリを効率率率的に使え ているか

    n  CPUを使いきっている か n  同時コネクションを受 け⼊入れられる設定に なっているか ボトルネック検証 n  ページキャッシュ –  ページまるごとを RedisやVarnishへ n  DBキャッシュ –  RDBの中⾝身を必要 に応じてRedisへ –  場合によっては定 期的にプリセット キャッシュの導⼊入 n  Railsの処理理のオーバー ヘッドをSinatraを組み 合わせカバー n  場合によってはRackア プリを直接書く 汎⽤用化するためのオーバー ヘッドを削減していく FWのオーバーヘッド 基本的な対応のみでも通常の負荷は対応可能 Rubyを⽤用い、出来る限りサーバを⼩小さく、コストをかけないよう設計
  9. 9 ©Gunosy Inc. 2014年年  TV  CMとGo⾔言語導⼊入

  10. 10 ©Gunosy Inc. テレビCMの開始 1 Ruby  on  RailsとSinatraベースのAPI 3 ⼤大幅なUI変更更

    2 2014年年3⽉月に控えていた課題 n  これまでとは⽐比にならないユーザー獲得の可能性 –  サーバ全体の性能を上げる必要 n  配信するデータ量量の⼤大幅増加 –  ユーザーが⾒見見れる記事数が数倍以上 n  通知の配信頻度度も増加 n  1台あたり200req/sec –  将来に備え1000req/sec程度度まで性能を上げておきたい n  費⽤用をかけることでスケールする可能性 –  ただし、費⽤用分の運⽤用を回すリソースは不不⾜足気味(インフラエンジニア0名) 短期間・少リソースで性能を向上させる必要性 前述のRubyサーバでは今後の展開に対して性能が⼤大きく不不⾜足していた。
  11. 11 ©Gunosy Inc. Go導⼊入の決定と理理由 n  ⽐比較的安定して多くの リクエストを捌いた n  Goroutineとchannelに よる⾮非同期処理理の楽さ

    n  CPUの使い切切りやすさ n  ⽐比較的省省メモリ ⾼高パフォーマンス n  依存関係は全てバイナ リに含まれる n  クロスコンパイルによ り、⼤大抵のマシン上で 動作する 独⽴立立性の⾼高さ n  Einhornなどと組み合わ せ安全な再起動 n  GoogleやSoundcloud による運⽤用実績 n  Githubでのライブラリ 増加数が急増  =>  利利⽤用 も増えてるといえる 安定運⽤用の実績 少リソースでの性能改善、性能に対する⽬目標達成 Nginx-‐‑‒luaやHaskell、node.jsなどと⽐比較しつつ簡易易なロジックを実装・評価
  12. 12 ©Gunosy Inc. ⼀一つ上を⾏行行く負荷対策 データフローに注意しないと不不整合が起きやすい諸刃の剣でもある Goの⾔言語特性を活かした2つの負荷対策 プロセスキャッシュ ChannelをQueueとした⾮非同期処理理 メモリ空間の効率率率的利利⽤用 Goroutineとchannelの活⽤用

    n  DBアクセスをしないAPI –  APIプロセスに主要な配信デー タを搭載 –  DB  =>  Goのオブジェクトへの デシリアライズコスト削減 n  データフロー –  サーバ起動時と定期的なキャッ シュデータ更更新 –  internal  apiを⽤用意し社内利利⽤用 n  Channelのキャパシティを利利⽤用 –  ⼀一定量量のメッセージをブロック せずに渡せる –  httpハンドラ外のgoroutineで dequeueし処理理 n  直列列化と処理理効率率率を両⽴立立 –  特定のログを吐く、キャッシュ を⽣生成するなどを効率率率化
  13. 13 ©Gunosy Inc. Goとプロセスキャッシュについて Goのメモリの扱いを上⼿手く利利⽤用し、データを効率率率的に配信する n  DBのアクセスコスト –  ネットワークコスト – 

    デシリアライズコスト n  Goのメモリ空間を活かす –  全てのハンドラで共通のメモリ空間 n  syncパッケージでの安全なアクセス –  sync.RWMutex –  競合アクセスを避け、効率率率的に利利⽤用 n  Goroutineを利利⽤用したデータの更更新 Goroutineとsyncパッケージを活かしたオンメモリでのデータ保持 DB Golang   Process OnMemory Database Sync Goroutine For Sync HTTP Server API
  14. 14 ©Gunosy Inc. GoroutineとChannelによる簡易易MessageQueue Goの特徴を利利⽤用して簡単に仕組みが構築可能 n  Channelのキャパシティを活⽤用 –  Goのchannelはキャパシティを⼤大きく 設定すればその分ブロックせずに保持

    しておいてくれる n  Goroutineで簡易易worker –  Channelからmessageを取得し処理理し 続けるgoroutineを⽤用意 –  httpのハンドラはchannelに投げてす ぐレスポンスを返す –  重い処理理はworker  goroutine内にて。 時間のかかる処理理を⾮非同期に、かつ直列列に流流していく Message Message Message Message Message Message Channel   For  Queue Worker   Gorou8ne HTTP   Handler   Enqueue dequeue Heavy  Tasks
  15. 15 ©Gunosy Inc. 2015年年  似⾮非Microservices時代  

  16. 16 ©Gunosy Inc. 予測できない負荷 1 並列列開発 3 機能毎に求められる要件が⼤大きく変わる 2 2015年年の挑戦

    n  ニュースとは違うユーザーの⽣生態系 –  アクセス傾向やDB負荷はサービスごとにバラバラ –  参考になる予測値があまりない n  マンガや占い、チャット旅⾏行行予約といったシステムはそれぞれ要求が違う –  Websocketによるチャット –  読了了などの細かいアクセスログ送信 –  パートナーAPI連携…etc n  複数のサービスを⼀一気に開発している –  ⼀一つのシステムに載せることに対する限界 n  ⼀一つのサービスの課題を他のサービスにできるだけ響かせたくない 施策を⾼高速に回すための⼯工夫と負荷対策の両⽴立立が必要 GunosyをPlatformとし、様々な機能を載せる
  17. 17 ©Gunosy Inc. 似⾮非Microservices化 機能の追加とサービスのスケーラビリティを可能な限り両⽴立立 n  各種サービスに合わせたツール選定 –  場所によってはNSQなど変わったプロ ダクトも利利⽤用している

    –  チューニング内容はサービス内容に依 存する n  共倒れリスクの低減 –  場所によっては外部API依存が強い –  各サービス間の共倒れのリスクを減らす –  撤退も簡易易に⾏行行える n  複数チームで同時開発 厳密にAPI連携したMicroservicesではなく、画⾯面単位での分割 Gunosyマンガ Golang  +  DynamoDB 専⽤用の管理理画⾯面含む Gunosy占い Golang  +  MySQL +  外部API連携 Gunosy  Main  API Golang  +  Redis  +   MySQL
  18. 18 ©Gunosy Inc. Opsworksでの効率率率化 サービスの効率率率的な構築をApp側開発者も参加して実施 n  ミドルウェア選定から構築までのコスト減 –  GUIで必要なものを選ぶだけで良良い – 

    各種の最適設定は予めある程度度⽤用意 n  メトリクス収集なども共通化 –  必要なメトリクスもGUI指定 –  アラート等⾃自動で設定 複数のサービスを効率率率よく適切切なアーキテクチャで構築する
  19. 19 ©Gunosy Inc. 最後に:  負荷対策に⼤大切切なこと

  20. 20 ©Gunosy Inc. ⽬目標を明確にする 1 ツールを⾒見見極める 3 ボトルネックを正しく⾒見見極める 2 負荷対策に⼤大切切なこと

    n  コストを最⼩小にするのか n  レスポンスを最速にするのか n  同時アクセス耐性を⾼高めるのか n  計測と勘所の⾒見見つけ⽅方は兎に⾓角⼿手数をこなす –  SlowクエリやCPUの利利⽤用状況(iowaitが⾼高い、など)の⾒見見⽅方 –  リソース配分の適切切な考え⽅方 n  新しければいいわけでもない –  ツールの特性を正しく理理解して使うこと n  銀の弾丸は無い n  問題に突き当たる前に新技術を知っておくべき、対策に⼊入ってから調査では遅い。 システムを正しい向きに広い視点で最適化していくことが⼤大切切 GunosyをPlatformとし、様々な機能を載せる
  21. 21 ©Gunosy Inc. まとめ n  ボトルネックの把握 n  Redisによるキャッシュ –  DBレイヤキャッシュ

    –  Viewキャッシュ n  オーバーヘッドを減らす –  Rails  =>  Sinatra –  素のRack n  ⾔言語特性を活かす –  並列列処理理の強さ –  実⾏行行速度度 n  プロセスキャッシュ –  DBアクセス削減 –  デシリアライズ削減 n  Goroutineとchannel –  簡易易な⾮非同期処理理 Queue –  重い処理理を逃がす n  画⾯面単位での分割 –  WebViewと機能単 位でのサーバ分割 –  ドメインごとに最適 なアーキテクチャ選択 –  Opsworksでの構築 効率率率化 ※正しいMicroservicesで はない 2015 Microservices 2014 Golangの導⼊入 2013 RubyによるAPI ユーザーの増加、機能の増加それぞれに合わせた最適化を図る 適切切な技術を選び適切切にスケールさせていく