Slide 1

Slide 1 text

#sapurimeetup CQRS+ESをKinesis,Spark,RDB,S3でやってみた スタディサプリ小中高の Observability @yuya-takeyama Yuya Takeyama スタディサプリ/Quipper Product Meetup #3

Slide 2

Slide 2 text

今日の話、ざっくり...

Slide 3

Slide 3 text

01 02 03 04 05 Agenda | スタディサプリの紹介 自己紹介 スタディサプリ小中高におけるマイクロサービス化の現状 Observability とは スタディサプリ小中高における Observability の現状

Slide 4

Slide 4 text

01 スタディサプリの紹介

Slide 5

Slide 5 text

スタディサプリ (対象学年が小中高校生) (ToC向け、ToB向け) スタディサプリ ENGLISH 国内向け学習サービス

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

02 自己紹介

Slide 8

Slide 8 text

@yuya-takeyama ➔ 2015年9月~: Web Developer at Quipper ◆ Rails/Backone.js/React.js/React Native などなど ➔ 2018年4月~: SRE at Quipper ◆ Kubernetes をはじめとしたインフラの構築・運用 ◆ マイクロサービス化のために必要なツール等の検証・導入・実装 ◆ その他インフラ周りのあらゆること

Slide 9

Slide 9 text

03 スタディサプリ小中高における マイクロサービス化の現状

Slide 10

Slide 10 text

何故マイクロサービス化するのか ➔ スタディサプリ小中高は Global の Quipper とコードベースが共通 ◆ 各国ごとにプロダクトのあり方が多様化しつつあり、ある国での変更が別 の国の機能に影響し得る ➔ 各国の各チームがそれぞれ Ownership を持って、スピード感を持って開発の サイクルを回すため ◆ 開発だけでなく、必要なインフラ (データベース、キュー等) も各チームでで きるよう、セルフサービス化の推進 ◆ 自分たちで作ったものを自分たちで運用していく自律分散型の組織に (DevOps)

Slide 11

Slide 11 text

スタディサプリ小中高・マイクロサービス化の現状 ➔ 2018年12月に Microservices 基盤として Kubernetes での本番運用を開始 ➔ まだまだ Microservices と呼べる状況ではない ◆ Heroku や Deis で動かしていたものを Kubernetes に載せ替え ◆ マイクロなサービスはまだ 10 もないぐらい (開発中含む) ◆ モノリシックな Rails が 5 つぐらい ● まだほとんどの機能はモノリス内で完結している ● ごく一部の機能の裏側でマイクロなサービスが動いている ◆ フロントエンドが 3 つぐらい

Slide 12

Slide 12 text

スタディサプリ小中高・マイクロサービス化の現状 ➔ Monolith からの Microservice の切り出しは一部で進行中 ◆ 学習データサービスの切り出し (Elixir/Go) ➔ 一部新機能については Microservice を作って Monolith に結合している ◆ データ系プロダクト (講義のレコメンデーション、講義検索) (Python/Flask) ◆ 学校向け機能 (生徒データの名寄せ) (Ruby/gRPC) ◆ 顧客ターゲットが全く異なる新規事業プロダクト (Ruby/Go/gRPC/GraphQL)

Slide 13

Slide 13 text

04 Observability とは

Slide 14

Slide 14 text

Observability (可観測性) ➔ サービスの状況をが外からどれだけ見えるか、という性質 ◆ ゼロイチではなく、グラデーション ➔ Microservices じゃなくても重要だが、Microservices だとより重要 ◆ アーキテクチャが複雑になる分、起きる問題も複雑 ➔ 3 Pillars of Observability ◆ Metric ◆ Logging ◆ Tracing

Slide 15

Slide 15 text

05 スタディサプリ小中高における Observability の現状

Slide 16

Slide 16 text

Metric ➔ 様々なレイヤに渡る Metrics ◆ AWS ◆ Kubernetes Node (EC2/Linux) ◆ Kubernetes Pod ◆ Protocol/Language/Framework/Middleware ➔ スタディサプリ小中高では Datadog を使用 ◆ Metrics の収集、Dashboard の作成、アラートの送信 (Slack)

Slide 17

Slide 17 text

Nginx を使ったサービスごとの req/sec

Slide 18

Slide 18 text

Unicorn の Pod ごとのメモリ使用量

Slide 19

Slide 19 text

Protocol/Language/Framework/Middleware のメトリクス ➔ HTTPやgRPC のリクエスト数、レスポンスステータスの内訳、エラー率 ➔ プロセスモデルに応じたメトリクス (pre-fork したプロセスごとのメモリ使用量) ➔ 基本的に Datadog が勝手に拾ってくれる訳ではない ◆ 恐らく Prometheus 等の別ツールにおいても同様のはず ➔ スタディサプリ小中高では Prometheus Exporter と Datadog の Autodiscovery を活用

Slide 20

Slide 20 text

Prometheus Exporter ➔ Prometheus 向けにメトリクスを主力するための API フォーマット ◆ GitHub 上などを探せば様々な Protocol, Language, Framework または Middleware の Exporter が見つかる ➔ Quipper では Ruby のサービスで prometheus_exporter や grpc_prometheus といった gem を利用 ➔ https://prometheus.io/docs/instrumenting/exporters/

Slide 21

Slide 21 text

Datadog Autodiscovery ➔ Datadog agent が様々な API からメトリクスを自動的に収集するための機能 ➔ Kubernetes においては Pod の annotations から API の URL や、収集時の 設定を discover する ◆ サービスが増えていっても、簡単にメトリクスの収集対象に加えられる ➔ Prometheus Exporter からの収集にも対応 ◆ そのほかにも Nginx, Go, gunicorn, Envoy 等様々なものからメトリクスを 収集できる

Slide 22

Slide 22 text

Datadog Autodiscovery のための annotations の記述 metadata: annotations: ad.datadoghq.com/api.check_names: | ["prometheus"] ad.datadoghq.com/api.init_configs: | [{}] ad.datadoghq.com/api.instances: | [ { "prometheus_url": "http://%%host%%:9394/metrics", "namespace": "prometheus_checks", "metrics": ["*"] } ]

Slide 23

Slide 23 text

➔ サービスをまたいでログを集約し、検索可能な状態にする ➔ GCP の Stackdriver Logging を利用 ◆ 標準出力・エラー出力に書くだけで勝手に fluentd で収集 ➔ ログが JSON だった場合、構造化ログとして記録される ◆ Kubernetes 上のアプリケーションから Stackdriver Logging に構造化ロ グを送る ➔ Request ID を元に関連するログをまとめて検索できる ◆ Sentry 等のエラー集約基盤でも Request ID を記録しておくことで、エ Logging

Slide 24

Slide 24 text

Stackdriver Logging 上での構造化ログの検索

Slide 25

Slide 25 text

Sentry 上の X-Request-ID からログを検索

Slide 26

Slide 26 text

➔ ログフォーマットの統一化 ◆ Request ID や User ID のような共通の項目のフィールド名を統一化する ことで、複数サービスをまたいで効率よく検索可能にする ◆ JSON を出力すればいいので、言語に関係なく統一化が可能 ◆ Web Developer の @reizist さんがとあるサービスでいい感じのフォー マットを提案してくれたので、あとは他のサービスにも展開するだけ? Logging 今後の展望

Slide 27

Slide 27 text

Tracing ➔ 複数サービスをまたいだリクエストにおいて、ボトルネックを可視化 ◆ 特に Microservices においては重要な要素 ➔ スタディサプリ小中高においては Jaeger を検証したりしたが、運用が大変なの で Stackdriver Trace 等のクラウドサービスを検討中 ◆ 現状はまだほぼできていない

Slide 28

Slide 28 text

Jaeger によるサービス間通信の可視化 https://www.jaegertracing.io/docs/1.8/

Slide 29

Slide 29 text

Stackdriver Trace によるサービス間通信の可視化 https://cloud.google.com/trace/docs/viewing-details

Slide 30

Slide 30 text

まとめ ➔ Microservices 化し、組織が自律分散型になっても安定してスケールしていけ るよう、統一的に Observability を確保 ➔ Metric は Datadog の Autodiscovery 等を活用して、言語やフレームワークご とに統一的に収集 ➔ Logging は Kubernetes クラスタ全体から Stackdriver Logging に集約し、今 後は構造化ログのフォーマットの統一化等を行なっていきたい ➔ Tracing はまだ活用できていないが、Stackdriver Trace 等を検討中 ➔ その他、Envoy/Service Mesh でもこの辺色々やっていきたい... 興味あれば懇親会で