devops を繋ぐ監視サービス Mackerel がどんな仕組みで動いているか気になりませんか? あの機能の裏側はどうなってるの〜!? 知りたくて夜も眠れないあなたに、アラーティングからロール内異常検知まで、グラフ表示から Google Cloud インテグレーションまで、Mackerel の裏側を全部教えちゃいます! これを聞けばあなたも Mackerel 開発者だ!
1まかれるあなとみあ―Mackerel のしくみを理解する 30 分―
View Slide
2.。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆).。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆)
3.。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆)id:ne-sachirouMackerel のアプリケーションエンジニア 2019/09〜仕事で使ってる言語 : Scala, TypeScript, Go, Python, (Bash, Perl…)仕事で使ってるエディタ : Emacs with Evil and lsp-mode今嵌まってる言語 : Clojure, Babashka, Clojerl (Clojure on Erlang VM)幼なじみ : Ruby.。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆)
4SRE (Site Reliability Engineer)CRE (Customer Reliability Engineer)アプリケーションエンジニアMackerel のエンジニア達
5SRE (Site Reliability Engineer) : サービス動作の信頼性を担保するCRE (Customer Reliability Engineer) : 顧客に対するサービスの信頼性を担保するアプリケーションエンジニア : サービスのアプリケーションを開発するMackerel のエンジニア達
6SRE (Site Reliability Engineer)CRE (Customer Reliability Engineer)アプリケーションエンジニア ←ここMackerel のエンジニア達
7Mackerel とは
8
9
10エンジニアをワクワクさせる「直感的サーバー監視サービス」エージェントあるいはインテグレーションで簡単に導入できる美しく、かつ使い易いグラフ作り易いダッシュボード簡単に設定できて障礙時に役に立つアラート監視サービス自体の運用は Mackerel チームにおまかせMackerel とは
11メトリックの投稿と閲覧ホストにメタデータをつけて管理するアラーティングや各種通知機械学習を利用したロール内異常検知外形監視AWS, Azure, Google Cloud とのインテグレーションMackerel の主な機能
12ホスト ∈ ロール ∈ サービス
13Mackerel の仕組みproxyWebコンソールバッチAPIロール内異常検知外形監視AWSインテグレーションAzureインテグレーションGoogle Cloudインテグレーションdiamond本体
14最近の仕組みの更新ハイライト!Redis が EC2 から ElastiCache に移行しました多くのサーバーが EC2 から ECS Fargate に移行しましたデプロイの方法も Capistrano 2 から CodePipeline へ移行していっていますGoogle Cloud インテグレーション用のコンポーネントが増えましたAngularJS が React に移行しつつありますMackerel の仕組み
15proxy
16proxyproxyWebコンソールバッチAPIロール内異常検知外形監視AWSインテグレーションAzureインテグレーションGoogle Cloudインテグレーションdiamond本体
17(※AZ 冗長は省略した図。以降のページでも同じ)proxyNLB Nginx本体へ
18アプリケーションエンジニアが操作する機会はあまり無いインターネットからの全てのリクエストを受け、URL を見て適切なサーバーへ振り分けるTLS を終端するIP address を固定する。閉域からこの IP address へだけ通信を許可する運用が可能一部の静的ファイルを配信するproxy
19proxyNLB Nginx本体へElastic IP でIP address を固定適切なサーバーへ振り分ける
20本体
21本体proxyWebコンソールバッチAPIロール内異常検知外形監視AWSインテグレーションAzureインテグレーションGoogle Cloudインテグレーションdiamond本体
22Mackerel の全て (全てではない) のロジックが詰まっている巨大なコードのかたまり。サーバーは Scala (Play Framework)、フロントエンドはTypeScript (s/AngularJS/React/)言語やライブラリの更新は、軽いものは当番が dependabot や renovate も活用して上げる、重いものは issue を立て計画してがんばる (他のコンポーネントでも同様)だいたいコンテナ (ECS Fargate) で動いている同一のコードが以下の 3 種類のサーバーへデプロイされる• Web コンソールサーバー• API サーバー• バッチサーバー本体
23本体 / Web コンソール & API サーバーproxydiamondPostgreSQLRedisALB ECS FargateWeb コンソールサーバーAPI サーバー
24Web コンソール (mackerel.io でサインインすると表示される Web UI) のリソースを配信するWeb コンソールからの操作を受け付け、処理を行う共有グラフや公開グラフを配信するECS Fargate で動作する。Jenkins から ECR へイメージを置き、CodeDeploy から B/G デプロイする (API サーバーも同じく)Redis は容量を確保する為に 2 台に垂直分割してある (API サーバーも同じく)本体 / Web コンソールサーバー
25API リクエスト (メトリック投稿等多数) を受け付け、処理を行うhttps://mackerel.io/ja/api-docs/本体 / API サーバー
26本体 / Web コンソール & API サーバーproxydiamondPostgreSQLRedisALB ECS FargateWeb コンソールサーバーAPI サーバー
27色々な定期バッチ処理 (ホスト死活監視、外形監視の実行、課金処理等多数) を行うEC2 (現行) から Lambda & ECS (新) へ移行中本体 / バッチサーバー
28本体 / 現行バッチサーバーdiamondPostgreSQLRedisALBcron (EC2) EC2
29EC2 上で動く cron が HTTP リクエストを発行し、ALB の背後にある EC2 上の Scala コードがバッチ処理を行うcron 用の EC2 を 2 台置く事で AZ 冗長を確保。バッチは冪等であるか、あるいは Redis を介してロックを取る本体 / 現行バッチサーバー
30本体 / 現行バッチサーバーdiamondPostgreSQLRedisALBcron (EC2) EC2ロックを取得冗長化されたリクエスト
31本体 / 新バッチサーバーdiamondPostgreSQLRedisECS FargateLambdaClaudWatchEvents
32(※移行中なので大幅に変更されるかもしれない)cron は CloudWatch Events に置き換わる。冗長性は CloudWatch Events に任せる素早く終わるバッチは Lambda (container) で、時間のかかるバッチは ECS Fargate で処理するこの移行が完了すると、本体は全てコンテナで動作する事になる!本体 / 新バッチサーバー
33本体 / 新バッチサーバーdiamondPostgreSQLRedisECS FargateLambdaClaudWatchEvents時間のかかるバッチ素早く終わるバッチ
34AngularJS から React へ移行中https://speakerdeck.com/susisu/hatena-engineer-seminar-number-13状態のスパゲッティーが解消されていってめでたい本体 / フロントエンド
35diamond (時系列 DB)
36diamond (時系列 DB)proxyWebコンソールバッチAPIロール内異常検知外形監視AWSインテグレーションAzureインテグレーションGoogle Cloudインテグレーションdiamond本体
37Graphite 互換の時系列 DBMackerel に投稿されたメトリックは diamond に保存されるGraphite 互換の式を提供する。式グラフや式監視で使えるTypeScript (Lambda) & Go (Lambda, ECS)diamond (時系列 DB)
38diamond (時系列 DB)ALBECS FargateLambdaDynamoDBRedis ClusterS3KinesisDataStream読み込み書き込み
39• 坪内佑樹、他「HeteroTSDB: 異種混合キーバリューストアを用いた自動階層化のための時系列データベースアーキテクチャ」2018 http://id.nii.ac.jp/1001/00192569/• 時系列データベースという概念をクラウドの技で再構築する / The rebuild of time-series database on AWShttps://speakerdeck.com/yuukit/the-rebuild-of-time-series-database-on-aws• サーバレスアーキテクチャによる時系列データベースの構築と監視 / Serverlessconf Tokyo 2017https://speakerdeck.com/itchyny/serverlessconf-tokyo-2017• AWS で実現した Mackerel 時系列データ1分粒度長期保存の裏側 / Mackerel Meetup #11 Tokyohttps://speakerdeck.com/astj/mackerel-meetup-number-11-tokyo• Mackerel の時系列データベースにおける Redis Cluster の利用と Amazon ElastiCache への移行について /AWS Purpose-Built Databases Week https://speakerdeck.com/astj/aws-purpose-built-databases-weekdiamond (時系列 DB)
40メトリック投稿グラフ表示アラーティング本体で実現される主な機能の仕組み
41メトリック投稿の仕組みAPIRedisdiamondPostgreSQL異常検知メトリック
42メトリック投稿の仕組みAPIRedisdiamondPostgreSQL異常検知グラフ定義保存メトリック
43メトリック投稿の仕組みAPIRedisdiamondPostgreSQL異常検知保存グラフ定義保存メトリック
44メトリック投稿の仕組みAPIRedisdiamondPostgreSQL異常検知保存ホスト数記録死活監視メトリック監視グラフ定義保存メトリック
45メトリック投稿の仕組みAPIRedisdiamondPostgreSQL異常検知異常検知 保存ホスト数記録死活監視メトリック監視グラフ定義保存メトリック
46メトリック投稿の仕組みAPIRedisdiamondPostgreSQL異常検知異常検知アラート保存ホスト数記録死活監視メトリック監視グラフ定義保存メトリック
47グラフ表示の仕組み
48グラフ定義グラフ表示の仕組み
49直近のメトリックは Redis Cluster に、少し前のメトリックは DynamoDB に、古いメトリックは圧縮されて S3 にある。(diamond の各資料を参照)diamond の中のデータは「メトリックキー × 時刻 → メトリック値」グラフ定義を元にメトリック値を取得し表示するには…グラフ表示の仕組み
50diamond の中のデータは「メトリックキー × 時刻 → メトリック値」ロール (ホストの集合) のグラフを表示する場合:グラフ定義 := ロールのグラフ定義 ∪ ホストのグラフ定義グラフの線 := ロール自身の持つグラフの本数 ∪ ロールに紐づくホストメトリックキー ∈ グラフ定義 × グラフの線メトリック値 := diamond(メトリックキー × 時刻)グラフ表示の仕組み
51diamond の中のデータは「メトリックキー × 時刻 → メトリック値」ロールグラフを表示する場合:グラフ定義 := ロールのグラフ定義 ∪ ホストのグラフ定義グラフの線 := ロール自身の持つグラフの本数 ∪ ロールに紐づくホストメトリックキー ∈ グラフ定義 × グラフの線メトリック値 := diamond(メトリックキー × 時刻)グラフ表示の仕組み
52グラフの画像を共有する機能 (Slack 通知、共有グラフ等) では Web コンソールサーバーでグラフを描画するSVG を作り java.awt で画像を作っているグラフ表示の仕組み
53アラーティングの仕組み
54アラーティングの仕組みホストメトリック監視 ホストメトリックの移動平均 (1〜10 分) が閾値を超えるとアラートサービスメトリック監視 サービスメトリックの移動平均が閾値を超えるとアラート式による監視 式の値が閾値を超えるとアラートホスト死活監視 エージェントからメトリックが送られてこなくなった事を検知するチェック監視 エージェントから OK/NG が送られてくるロール内異常検知 ロール内のメトリックの異常な動きを機械学習により検知する (後述)外形監視 顧客の Web サイトへ HTTP/HTTPS リクエストを投げ、レスポンスによってアラーティングする (後述)
55メトリック投稿の時に、diamond とは別に Redis にも直近のメトリックを保存する。この平均が閾値を超えるとアラートを発報Graphite (アラーティングの機能が無かった) を使っていた時期の実装を使い続けているアラーティング / メトリック監視の仕組みAPI Redis
565 分毎にバッチが走り、diamond に式の結果を問い合わせる。結果が閾値を超えていたらアラートを発報するアラーティング / 式による監視の仕組みバッチ diamond
57毎分バッチが走り、最後にエージェントがシステムメトリックを投稿してきた時刻が古過ぎるとアラートを発報するアラーティング / ホスト死活監視の仕組みバッチ Redis
58ロール内異常検知
59ロール内異常検知proxyWebコンソールバッチAPIロール内異常検知外形監視AWSインテグレーションAzureインテグレーションGoogle Cloudインテグレーションdiamond本体
60ロール (似た働きをするホスト達) 内のメトリックの異常な動きを機械学習により検知するPython (Batch, ECS)ロール内異常検知
61https://www.slideshare.net/syou6162/mackerel-148068652ロール内異常検知
62ロール内異常検知ALBバッチAPI DynamoDBECS FargateBatch予測学習モデルを保存するdiamond API
63ロール内異常検知
64外形監視
65外形監視proxyWebコンソールバッチAPIロール内異常検知外形監視AWSインテグレーションAzureインテグレーションGoogle Cloudインテグレーションdiamond本体
66外形監視バッチ RedisALB NATGatewayWebコンソールAPI
67顧客の Web サイトへ HTTP/HTTPS リクエストを投げ、レスポンスによってアラーティングしたり、レスポンスタイムをメトリックとして記録する機能独自の DB は持たない。毎分バッチサーバーから外形監視用のデータが送られてくる。これを Redis に enqueue し、ECS タスクにて分散して処理する (AWS インテグレーションとAzure インテグレーションも同様の仕組み)ユーザーが Web コンソールで外形監視を設定した時に、その設定が妥当か検査する機能も持つ (AWS インテグレーション、Azure インテグレーション、Google Cloud インテグレーションも同様)Go (ECS)外形監視
68外形監視バッチ RedisALB NATGatewayWebコンソールバリデーションenqueueAPI結果Elastic IP でIP address を固定
69AWS, Azure, Google Cloud インテグレーション
70AWS, Azure, Google Cloud インテグレーションproxyWebコンソールバッチAPIロール内異常検知外形監視AWSインテグレーションAzureインテグレーションGoogle Cloudインテグレーションdiamond本体
71AWS インテグレーションバッチ RedisALBWebコンソールAPIAWS
72顧客の AWS CloudWatch からいい感じにメトリックを取得する仕組みは外形監視とほぼ同じ (バッチ間隔は 5 分毎)Go (ECS)AWS インテグレーション
73AWS インテグレーションバッチ RedisALBWebコンソールAPIAWSバリデーションenqueue結果
74顧客の Azure Monitor からいい感じにメトリックを取得する仕組みは外形監視とほぼ同じ (バッチ間隔は 5 分毎)Go (ECS)Azure インテグレーション
75Azure インテグレーションバッチ RedisALBWebコンソールAPIAzureバリデーションenqueue結果
76Google Cloud インテグレーションバッチALBWebコンソールAPIGoogleCloudSQS
77顧客の Google Cloud Monitoring からいい感じにメトリックを取得するSQS を使って enqueue するようになった (キューにはキューを使う)「いつのメトリックを取得するべきか」をデータに含めて euqueue することでリトライ可能になったGo (ECS)Google Cloud インテグレーション
78Google Cloud インテグレーションバッチALBWebコンソールAPIGoogleCloudSQSバリデーションenqueue結果
79Mackerel の運用を支える Mackerel
80Mackerel の運用を支える Mackerel
81Mackerel の運用を支える MackerelSLI / SLO を Mackerel で監視
82https://speakerdeck.com/astj/noops-meetup-tokyo-number-8監視設計の話も載っているので御覧下さいMackerel の運用を支える Mackerel
83Mackerel の運用を支える Mackerel
84Mackerel の運用を支える Mackerel開発の様子を Mackerel で可視化
85mackerel.io