km_output

お勉強と趣味のアウトプット

スタディサプリ/Quipper Product Meetup #3 ~SREチームが取り組むマイクロサービス化に向けたDevOps開発事例~に参加してきた。

スタディサプリ/Quipper Product Meetup #3 ~SREチームが取り組むマイクロサービス化に向けたDevOps開発事例~

参加してきたので簡易まとめ。

https://techplay.jp/event/737389

f:id:km_tech:20190718220542j:plain
Quipper,スタディサプリのシール

当日の公式レポート

quipper.hatenablog.com

Observability in StudySapuri

Yuya Takeyama

スタディサプリ、何故マイクロサービス化するのか

GrobalのQuipperとコードベースが共通→ある国での変更が別の国の機能に影響しうる

各国の各チームがそれぞれ独立して開発サイクル回したい

マイクロサービス化の現状

Kubernetesでマイクロサービス基盤を整えた

HerokuやDeisで動かしていたものを載せ替え

マイクロなサービスはまだ10もない状況

大きな二つの流れ
  • マイクロサービスとしてサービスを切り出す

  • 新しい機能をマイクロサービスとして作る

 データ系プロダクト(Python/Flask)など

Observability(可観測性)の大切さ

サービスの状況が外からどれだけ見えるかという性質

マイクロサービスだとより重要

 全体のアーキテクチャが複雑なため発生する問題も複雑

 正しく分析するために大切

Observability(可観測性)の三要素
  • Metric

  • Logging

  • Tracing

Metric

様々なレイヤに渡る

AWS,Kubernetes Node(EC2/Linux),Kubernetes Pod,Protocolなど

→Datadogで収集

Rubyで動いているサーバが多い

UnicornのPodのワーカーごとのメモリ使用量

Rubyのメモリブロード(断片化)→メモリ増加→プロセスkill→立ち上げ直し・・・

細かいメトリクスはDatadog等が勝手に拾ってくれるわけではない

  • Prometheus Exporter

オープンソース

GitHub上などに落ちている

https://prometheus.io/docs/instrumenting/exporters/

  • Datadog Autodiscovery

Prometheus Exporterからの収集にも対応

Logging

サービスまたいでログ収集、検索可能

GCPのStackdriver Loggingを収集

標準出力・エラー出力に書くだけで勝手にfluentdで収集

リクエストIDで検索するとエラー探せる

今後の展望

  • ログフォーマットの統一化

  • フィールド名の統一

Tracing

複数サービスをまたいだリクエストにおいて、ボトルネックを可視化

まだ活用できていない

Stackdriver Trace検討中

Canary release - フレームワークのアップグレードを安心して進めるためのリリース戦略

Fumiaki Matsushima

本番構成とデプロイについて

アーキテクチャはユーザ別

Git flowでmonorepo上で開発・・・ディレクトリごと別サービス、レポジトリは1つ

ディレクトリにKubernetes関連ファイルがある

overlaysで差分管理

Build,DeployはCircleCIから

ワークフローは約150ジョブから成る、差分のみ実行

Canary releaseとは

一部のユーザに新機能を先に公開しリスクを減らす

プロセスごと分離

プロセスを2系統上げていないといけない

やらないといけないこと

アップグレードに関わっていない人の方が多い

開始を停止するわけにいかない:全員に両方でテストが通るコードを書いてもらう

依存する社内gemも2系統で

2種類のライブラリバージョン管理ファイルを持つ

Ruby特有

ディレクトリ=サービス

シンボリックリンクを貼り、分岐を入れて楽をする

  • 割り振るルールを決める

同じユーザには同じ挙動をするべき

 問い合わせ対応、再現確認の手間を考えて

ログインしていないユーザの考慮

一度新しいバージョンが使われたら戻ってほしくない

CookieにCanary release用IDを振る

環境変数で何%くらいID振るか決める

初めのリクエストは古いほうにいくが割り切った

移行の流れ

0 , 0.1 , 1, 10, 50, 100

  • ロジック確認のため0は挟んだほうがいい

  • 確率通りか見る

エラー監視

Sentryにフレームワークのバージョンをタグとして付与、

そのタグがついている場合のエラー通知先を分離

リリース時、何が起きたか

本番で問題は起きなかった

  • ステージングはCanary releaseの割合を高めていた(エラー拾って対処できた)

  • 自動テストがしっかりできていた

改善点

段階リリースに時間がかかり過ぎた

新エラーの判別を楽したい

 バージョン依存の問題かどうか?の判断

まとめ

新しいサービスを簡単に足せるようになっていれば

Canary release単純な実装で実現できる

まだまだ俺たちのアップグレードはこれからだ!

gRPC in スタディサプリ ENGLISH

Yuta Kimura

gRPC導入経緯
  • 各サービスごとの通信を共通化するため

当初の構成では負荷分散されず・・・

AWSは外部通信に対してはHHTTP/2は対応しているが、

内部通信に対してHTTP/2は対応していない

上記が分かっていたのでCLBのTCPモードで負荷分散していたが、

負荷が増えるにつれて障害につながるレベルの負荷になった

gRPCの負荷分散
  • プロキシロードバランシング

  • クライアントサイドロードバランシング

方法検討

利点と難点

  • プロキシロードバランシング

 クライアント側に手を入れないで実現

 ロードバランサ、プロキシの性能に左右される

  • クライアントサイドロードバランシング

 余計な経路が発生せず高性能

 ロードバランシングの実装が各言語に寄ってしまう

 実装によって変わるためクライアント側の複雑性が増してしまう

結論
  • 現時点で高性能さはいらない、障害対応優先

  • 既存のコードに手を入れたくなかった

プロキシロードバランシングを採用

Nginx vs HAProxy vs Envoy
  • Nginx

利用実績はあったが事例がなく断念

  • HAProxy

検討時点でgRPCのサポートをしていなかった

  • Envoy

docが豊富、gRPCのサポートあり

→Front Procy

api前にenvoyが動作するサービスをデプロイ

ELBをenvoyに置き換えるイメージ

問題点

APIの前にCLBはHTTP/2に対応していない

=ELBを使わないとき、クライアント側に対象IP一覧を返す機能が必要

Amazon ECS Service Discoveryを採用

まとめ
  • gRPCの負荷分散が最初できていなかったのに問題として取り上げられなかった、のような 技術的負債が生まれてしまっていることはよくある

  • 新しいものを入れるときは影響範囲と切り戻しの範囲を考える

  • 自分が何をしているか共有しやすい形で進めるのがおすすめ。

  • Scrapbox便利

  • Envoyはまだまだ新しい!楽しい!

CQRS+ESをKinesis,Spark,RDB,S3でやってみた

Tsubasa Matsukawa

CQRSとは

コマンドクエリ分離原則

更新と参照を分ける考え方

コードがシンプルになる利点がある

※デメリット:設計に工夫が必要

Event Sourcing

イベントを主役とする

State Sourcingでは消えてしまう有用な履歴情報をすべて残せる

Eventをhookに色々な処理が書ける。

※デメリット

イベントの数が多くなると状態を計算する処理のコストが大きい

任意のタイミングでスナップショットを作るなどして回避

データの持ち方

学習ログをRDBに保存していた

都度集計し、クライアントが欲しい形に整形

→データが増えて重くなってきた

  • 学習者のグループを管理する要件が追加され、集計が重くなってしまった

  • ロジックが複雑になった

embulkを使ってデータ変換してみた
  • API軽くなったが、embulkでのバッチ処理(集計処理)がデータ量に応じて重くなってきた

  • 集計用の巨大なSQLをメンテするのはつらい

CQRS+ES,Kinesis,Spark,RDB,S3の構成へ

Sparkとは

Scalaで書かれた並列分散処理フレームワーク

リアルタイム処理に強い

EMRとは

マネージドクラスタプラットフォーム。

大規模分散処理基盤を手軽に立ち上げ&実行できる

→これらを組み合わせて効率よくCQRS+ESをやる

  • 保存場所

コマンド、クエリはRDB

EventはS3

S3は高性能かつコスパが良く、AWSの他サービスと連携しやすくていい!

データの伝播

状態を都度更新するので計算コストがかからない(データ量に応じて重くならない)

  • Spark

全イベントを利用した状態の復元、スナップショット作成

S3からデータ取得しやすくした

切り換えも安心安全

並行稼働させ、データに問題がないと確認できたら切り替える

まとめ

イベントはS3に置くのがオススメ