kmuto’s blog

はてな社でMackerel CREをやっています。料理と旅行といろんなIT技術

『WEB+DB PRESS Vol.132』を読んだ

vol.131を読み終えたら「vol.132を刊行しました」とメールが届いていた。怖い。

gihyo.jp

今回は実践的なコンテナ導入記が特集されていて、自分のメモ書きも多め。

  • サバンナ便り
    • テストダブル。テストに使う身代わり、スタブ・スパイ・モック・フェイクなどの総称。
    • メリット: テストしにくいものがテスト可能になる、テストの実行速度と決定性が向上する。
    • デメリット: テストが脆くなり、テストがコードの変化を妨げる。テストの偽陰性を招きがち。
    • 本物の忠実性を下げる代わりに速度と決定性を向上するトレードオフであることを理解する。LargeテストをMediumやSmallにサイズダウンさせるのに使い、MediumやSmallではなるべく本物を使うのがよさそう。
  • オブジェクト指向神話からの脱却
    • 「プログラミングの勉強を始めた人が必要以上にがんばってオブジェクト指向しようとする」わかる。
    • パラダイムは言語全体に適用するものではなく言語機能に適用するものであった、という論。関数型機能とオブジェクト指向機能を併せ持つ言語も今は多く、言語の分類に意味がない。
    • オブジェクト指向の古い定義は今ではそのまま適用できず、かといって新しい定義は人によってはっきりしないという共通認識がない状況にある。「良いプログラムのためにはオブジェクト指向」という神話やパラダイム論にこだわらず、利用する言語の言語機能をいかに活用し、開発特性をどう解決するかに集中すべき、と。
  • iOS16最前線
    • 同僚の方々の記事。最新16の新機能、SwiftおよびSwiftUIのアップデート、Swift Charts・App Intents・WidgetKitの解説。iOSは食卓のiPadだけで残りはAndroid、かつもともとモバイル系はあまり手を出してないという自分の背景で、「便利そう」というありがちな感想ですいません…。
  • コンテナ化実践ガイド
    • ヌーラボのBacklog SREをされている吉澤さんの記事。業務でもコンテナ周りの知識強化必要なので、とても参考になった。
    • サーバの増加や多様化で生じるトイル(プロダクションサービスを動作させることに関連する作業。手作業で繰り返し行われ、自動化することが可能なもので、長期的価値はなく、作業量がサービスの成長に比例して多くなる傾向がある)の問題。
    • コンテナ化のメリットはコンテナ技術自体(Dockerなど)がもたらすものと、オーケストレーションKubernetesなど)がもたらすものに分けられる。前者は開発者自身がイメージ作成定義できることやサーバ環境を共通化できること、後者はリソース割り当てを開発者自身が迅速にできることやヘルスチェック・スケールアウト/イン・ローリングアップデートなどを自動化できること。
    • デメリットは学習コストのほか、処理速度や応答速度などのパフォーマンスに影響が出たり、クラウドコストが上がったりすること。また、オーケストレーションの仕組みに合わせてデプロイや運用手順などを修正あるいは作り直しが必要になること。開発を継続する場合にはメリットが上回る。
    • コンテナ化しておくとマイクロサービス化しやすい。サービスのボトルネックがあるときもその箇所のサービスだけ数やリソースを増強できる。マイクロサービスはサーバレスにすることもできる。ドメイン境界を明確にするためにリファクタリングし、サービス分割する必要がある。データベースも分割する必要がある。順序はコンテナ化→マイクロサービス化でもよい。
    • 既存サービスのコンテナ化にあたっては、計画フェーズ・改善フェーズ・コンテナ化フェーズ・リリースフェーズに分けて考える。
      • レガシーなシステムでは暗黙の前提がコンテナ化の阻害要因になることがあり、アプリケーション自体を修正するための改善フェーズが必要。Backlogでも次々と要修正項目が発生。
    • 計画フェーズではスモールスタートで始め、実際に動かさないと不明なことも多いので事前調査期間も短めにする、ただし頻繁に関係者レビューを行う。
    • 現状調査。固定IPアドレスが必要、永続的なローカルディスクを必要とする機能やプロセス、自動化が難しい作業、はコンテナ化を阻害する可能性。
    • オーケストレーションツールやサービスの選択。AWSならECSやEKS。アプリケーションがクラウド上で動作しているならそのクラウドのマネージドサービスを推奨(ネットワーク設定やIAMを流用できる)。すでにオーケストレーションを導入済みならそれに乗る。
    • タスクの洗い出し。改善フェーズで実施すること、コンテナ化フェーズで実施すること。
    • 関係者との合意形成。システムの将来像の合意、プロジェクトのゴールについての合意。
    • スケジュール立案。改善フェーズ(要開発系エンジニア)・コンテナ化フェーズ(要インフラ系エンジニア)の進め方。ボリュームや人員バランス、オーケストレーションの利用機能などで考える。
      • 阻害課題が多く、改善フェーズのボリュームが大きすぎる場合はコンテナ化を先送りし、課題解決をまず進める。
    • 改善フェーズでは、サービス提供を続けながらコンテナ化予定のアプリケーションを改善する。コンテナ化する前に1つずつ解決して本番環境に投入することで、コンテナ化後の問題をコンテナ化時の問題のみに絞れる。現在のシステム状態とコンテナ化した後のシステム状態(ビルド結果やネットワーク設定など)をできるだけ近づける。ビルド結果をDockerイメージにしてpushするなど。改善範囲はコンテナ化を阻害するところのみに限定する。
    • オーケストレーションの運用コストが上がらないよう、アプリケーション側を改修する。スクリプトでのデプロイや運用手順の自動化、操作のワークアラウンドなどを解消する。
    • 古いIaCコードがあれば実情に合わせて更新する。ネットワークまわりのルールも整理する。IAMも整理する。
    • 固定IPアドレス依存の認証認可を置き換え(セキュリティグループ化など)。
    • 永続ディスクを要しないように変更(qmailという名を令和で聞くとは…)。監査ログをS3バケットにアップロードする箇所は、マネージドサービスのKinesis Data Firehoseを採用。
    • ワークアラウンドで対処しているウォームアップ処理・シャットダウン処理を書き直し。
    • いよいよコンテナ化フェーズ。アプリケーションの開発と差異が生じないよう、なるべく短期間で終わらせる。可能ならここだけでも人員を追加する。開発チームの開発内容を把握し、阻害課題になる実装がなされるのを防ぐ。
    • オーケストレーション未導入であれば小さなアプリケーションの本番環境に導入してみる。導入済みでも対象コンテナ化で未使用のものがあれば本番環境で検証していく。
    • コンテナイメージの作成。従来の作業や構築をDockerfileに置き換える。イメージビルドもCIにしておく。補助コンテナのサイドカーコンテナを導入する(BacklogではログアップロードのためのFluentdサイドカーコンテナ)。
    • オーケストレーションのプローブ設定。足りなければ追加、あるいは実装する。
    • デプロイパイプライン整備。マニフェスト作成、Kubernetesの場合はkubectlでのデプロイテスト。既存のデプロイパイプラインの修正、ローリングアップデートや冗長化のための設定。
    • 監視整備。Backlogの場合はMackerelからPrometheus+Grafanaに変更したとのこと。Fluentdやアラートも調整。
    • 性能テストでの検証。リソースや台数を変化させてみる、現在のサーバと比較してみる。オートスケールもテスト。
    • 外部コンポーネントオーケストレーションとの結合テスト。自動化しておく。
    • 最後のリリースフェーズ。コンテナ化されたアプリケーションを本番環境にデプロイし、コンポーネント接続を確認、リクエストを徐々に切り替え。切り戻し手順を整備しておく、短期間で終わらせる、役割分担を明確化して担当者未定作業を防ぐ。
    • 安全のためにメトリクスやログを監視しつつ段階的に切り替える。分け方は、機能単位、リクエスト数単位、それらの組み合わせ、など。Backlogではリバースプロキシで対処している。
    • 完全移行が終わるまで従来サーバとコンテナでデプロイパイプラインを共通化する。正常の判断をするためのメトリクスやログの確認手順を決めておく。デプロイ・運用・アラート対応のマニュアルを作り、関係者レビューを実施して整備する。
    • リリース後のチューニング。コンテナ数やリソースには余裕を持たせて開始し、徐々に減らして適正化していく。効果測定を行う。デプロイ時間・頻度、応答時間やエラー率。関係者ヒアリング。マイクロサービス化の検討。
    • Kubernetesのモニタリング等の理由でMackerelがなくなったのは残念なところではあるが、超力作のコンテナ化移行記事だった。
  • 22周年記念エッセイ 私が大切にしていること
    • 最近M1 GPUまで動かしたことでも有名な、Asahi Linuxを作っている朝日リナさんの記事が特によかった。
  • フロントエンドコンポーネント駆動開発
    • FigmaとStorybookの連携話。Adobe XDはあんまりイケてなかったし、Figmaのほうを覚えようかな。
  • Goに入りては…
    • sync/atomicによる排他制御の使い方。atoimc.Int32のような型が使える。CompareAndSwapを使ってリセットする。
  • Ruby 3標準添付ライブラリ紹介
    • Kconv(懐しい…)、NKF、Iconv、Encoding。記事にも書かれているけど、UTF-8以外の文字コードへの扱いがRubyは充実していて助かるんだよね。前職だとCP932はもとより、EUC-JPもISO-2022-JPもそれなりに関係して操作が必要なことがあった。
  • SREで開発を加速させる
    • パイプライン形式のSLI実装。同期書き込み型と非同期書き込み型それぞれのWebサービス構成に基づいて考えてみる。
    • 同期書き込み型の例構成: Userからの書き込みリクエストがUser→ALB→ECS→RDSと流れ、レスポンスがECS→ALB→Userと返る。
    • 非同期書き込み型の例構成: Userからの書き込みリクエストがUser→ALB→ECS→Kinesis Data Streamsと流れる。Kinesisに渡したところでUserにレスポンスを返す。処理のほうはKinesisからLambda、DynamoDBと渡っていく。書き込みリクエストが多い・書き込み時のデータに時間がかかる加工が必要などのサービスを想定。
    • ALB、ECS、Kinesis、Lambda、DynamoDBの監視項目を調べる。エラー率と処理時間に注目し、その他キャパシティ項目も考える。エラー率が可用性、処理時間がレイテンシというSLIで捉えられる。
    • 非同期書き込みでは、ALBから導かれる可用性・レイテンシはKinesisに渡すまでの時間や成功しか意味しない。SLIでは機能が提供される(たとえば動画が見られる状態になった)までの可用性やレイテンシを計測したい。例でいえばLambda・DynamoDBまで済んだところまでのレイテンシを考慮したい。
    • ストリーム処理やバッチ処理を伴うサービスを合わせて、パイプライン形式のサービスと呼ぶことにする。両者ではSLIの設計は異なる。
    • 新鮮さ: 時間の閾値よりも最近に更新されたデータの比率。最終的に処理されたデータの更新日時に対するSLI。サービスとして何が大事かを考える。例のケースではストリーム処理全体がどれくらいで終わり、ユーザーにデータを提供できるかでSLIを設計する。
      • HTTPアクセスログから算出した書き込みリクエスト処理時間 + CloudWatch MetricsでLambdaのIteratorAge + Duration
    • 正確性: 正しい値の出力につながったパイプラインへの入力レコードの比率。
      • 自分たちで定義したアプリケーション仕様の正確性であり、実装も自前となる。正解がわかっているproverデータを投入して成功したかを定期的に計測する。アプリケーション自体もテストしやすい状態にしておく必要がある。
    • カバレッジ: 時間ウィンドウ内に処理に成功した入力レコードの比率。例のケースでは、特定のタイムウィンドウ内で投入された処理対象データに対して処理したデータ量の比率を使う。値=カバレッジが低いと、処理があふれていて、新鮮さもすぐに悪化することになる。
      • KinesisのIncomingRecords、IncomingBytes、GetRecords.Records、GetRecords.Bytesを使う。Lambdaアプリケーションで受け取り/処理の件数をログ出力する。
    • パイプライン形式の場合、デファクトがないのでサービス要件と向き合って、本当に計測したい値が何かを考える。ステップごとのメトリクスを組み合わせて全体を計測できないか検討する。
    • X-Rayなどのトレーシングを使い、エンドツーエンドでの処理時間をトレースする方法もある。すべてのリクエストをトレースするのは高コストなのでサンプリング数は限定される。

『WEB+DB PRESS Vol.131』を読んだ

Software Designのほかに最新知識を追い掛けるのにWEB+DB PRESSを定期購読することにした。オフィスに紙のはあるんだけど、電子版でほしかったので自腹。

gihyo.jp

積ん読消化月間でちょっと読み飛ばしぎみ…(vol.132来てるし)。

  • サバンナ便り
    • t_wadaさん記事。
    • 「テストサイズ」という考え方。テストをSmall/Medium/Largeにサイズ分けする。
    • Small: 単一プロセス。高速・スケールするがネットワークやデータベースは使えない、プロセス外通信はテストタプルで置き換える。1件100ms未満、最長1分。おおむねユニットテストと同じ。テストタプルを使いすぎると実装の変化に弱くなり保守性が損われるので、必要十分な量のテストタプルを適切な箇所に使用するスキルが必要。
    • Medium: 単一に閉じた環境であれば外部リソース利用を許容。1件1秒未満、最長5分。テストの実行にDBとの接続が必要など。fake実装やコンテナ組み合わせなどのスキルが必要。
    • Large: リモートマシンアクセスも許容。最長15分。実際にデプロイして動かすなど。外部環境起因の物事を可能な限り抑える実装スキルが必要。
    • CIとの組み合わせを考えると、Smallテストの比率を上げ、Largeテストの比率を下げる。
  • 実装して学ぶHTTP/3
    • HTTP/3の概要、QUICサーバ実装、HTTP/3サーバ実装。
    • HTTP/2でストリーム、ヘッダ圧縮、バイナリフォーマット化、暗号デフォルト化、サーバプッシュという機能が入ったが、TCPTLSを使う限り、TCPのパケット到着待機時間、TLSの別途ハンドシェイクの時間という2つの時間の浪費が避けられない。
    • 対処として、UDPの上で通信部分を受け持つQUICと、HTTP機能を受け持つHTTP/3に分離した。HTTP/3はHTTP/2からはサーバプッシュとヘッダ圧縮のみを引き継ぎ、ほとんどはQUICが受け持つ。パケットの分割・組み立て、暗号化・復号は自前で実装することになる。
  • フロントエンドコンポーネント駆動開発
    • ページのアクセシビリティの話。最近Mackerelでもアクセシビリティ改善活動が行われていて、キーボード操作で完結できるような改善がなされてる。アクセシビリティツリーを意識する。Full accessibility tree機能を有効化して試す。ランドマークを意識する。VoiceOverで読み上げ確認をしてみる。
  • SREで開発を加速させる
    • masayoshiさん記事、サービス障害対応の話。
    • 開発をより効率的に進めるために、平均修復時間を減らす、障害の発生回数を減らす。
      • 平均修復時間を減らす: 準備する。経験・訓練・ロールバックダッシュボード。
      • 障害発生回数: 再発防止策。障害の振り返り。
    • 正常なときの動作を知る。技術を知り、サービスを知る。障害対応を知る。
    • 障害対応フォーメーション。山火事対応のICS(Incident Command System)の枠組を参考に、実作業の対応と調整、障害対応のステークホルダーとのコミュニケーション、障害対応自体のコントロール。オンボーディングでは書記役に入れてみるとよい。
    • 障害対応のドキュメント化。リンク集や担当の役割分担をテンプレート化しておくとよい。障害発生時にまずテンプレートをコピーして議事録や情報を集める。
    • 対応訓練。目的を絞った小さな訓練を複数設計し、定期的に実施する。テンプレートを確認してロールプレイする、DBのフェイルオーバーのような特定の実作業を訓練する、抽象度を上げて原因だけ(スロークエリ、AWS AZが落ちたなど)を決めて作業を作ってみる、擬似的な障害に対して原因の特定から行う(アプリケーションに一定の確率でエラーとなるバグを仕込んだり、AWSのセキュリティグループを変更してDBに接続できない状況にする、など)。カオスエンジニアリングだとこれらをステージングでなく本番環境で行うが、Observabilityがないと単に障害を起こすだけになってしまうので上級め。
    • 障害の振り返り(ポストモーテム)。非難しない、ポストモーテムを書くことを目的にするのではなくSLOを利用して信頼性のもとで開発速度を最大化することが目標。障害の原因・時系列やトリガ・再発防止アクションのほか、障害対応の仕方やユーザーへの告知内容などの対応自体も含める。
    • 過去のポストモーテムを活用して障害対応訓練をしてみる。
  • Goに入りては…
    • みんな大好き文字列連結。+は1桁遅い。bytes.Bufferかstrings.Builderがよさそう、Growメソッドを使って先に領域指定するなど。
  • 現場のPython
    • フリガナ振り。おおむね同じようなことは挑戦したことがあって(総ルビなどは書籍制作だと「たまによくある」要求ケース)、アプローチ的にも同じ感じではあった。辞書のメンテが難しいんだよねぇ……。
  • PHPで複雑さに立ち向かう
    • 非同期や並行処理の仕組み、実装の話。イベントループ、Promise、コルーチン。
  • Ruby3標準添付ライブラリ紹介
    • znzさん記事、rakeとthorの話。rakeは使っているけど、thorはそういえば使ってないな。Railsあんまり使っていなかったせいか。

Mackerel CREとして1ヶ月働いてみた

Mackerel Advent Calendar 2022 23日目の記事です。昨日は@genkiroidさんでした。

この日記をご覧になっていた方々には既知ですが、書籍制作プロダクション会社での書籍制作者&社内情シスという職種から、はてな社のMackerel CREポジションとして、先月の11月16日に転身しました。

kmuto.hatenablog.com

先達の皆さんがMackerelの活用方法や素晴しい思い入れを大いに示している中で場違いな気持ちが否めないのですが、「You書いちゃいなよ」と後押しされましたので、Mackerelの新人CREとして1ヶ月働いてのふりかえりをしてみます。

CREとは

Customer Reliability Engineer、顧客信頼性エンジニアと訳されています。提供しているサービスにおいて、顧客の抱える問題・課題を我が事として捉え、支援や提案で顧客の成功を支えていく役割を担います。Mackerelの場合、オンプレからクラウドへの移行、クラウドの各種サービスの連携、最近ではコンテナ化といった各シーンの監視で顧客の持つ疑問や課題を解決することが一例として挙げられます。

「CREは何をすべきか・どうあるべきか」というのは、実際のところCREというポジションを立てている各社それぞれに差異があって、「俺が、俺たちがCREだ」という状況ではあります。私自身は「文脈から意図を解釈し、伝わる形に翻訳できる」「オンプレやIaaSレベルの経験は豊富で、コードリーディングや開発もできる」というバックグラウンドを活用および強化して、実際にコードで改善もしながら顧客の真の課題を解決していきたいという目標を定めています。

入社しての感想

総じて「大変だけど楽しい」です。まだ不慣れというのを差し引いても、毎日これまでの3倍くらい脳を使っている気がしますね 😇

  • 情報量多い 😇
    • IT活用の過程で全社・グループ・チームでいろいろなサービスやソフトを使っている→入社から数日内でたくさんのアカウント作ったりパスワード設定したり→どの用途に何を使うのか混乱してきた…→今後続くCREメンバーが同じ苦労をしないようScrapboxに目的からサービスを探せる逆引きをまとめた
  • オンボーディングプランがいろいろと策定されている 😊
    • オリエンテーション・チームへの溶け込み→技術的実績解除、カスタマーサポート的実績解除、CREカスタマーサクセス的実績解除の目標→とりあえず少しずつ実績解除を進め中 、でも心理的安全性が高いですね
  • あらゆるスピード感がある 😊
    • エンジニアマインドが徹底している→相互の話の理解も決定も早いし、問題の提起・把握・相談・解決のサイクルもどんどん回していく印象→振り落されないよう毎日必死
  • 表参道怖い 🥺
    • 南青山エリア→「リーズナブルなゴハンどころ」というのが存在しない→厳しい 😇
  • 個人よりチーム、チームより組織、組織より全社
    • 個人の成長はもちろん必要なんだけど→チームに価値提供できるとよい→他チームに横断で提供できるとさらによい→全社に提供できると最高によい→CREカスタマーサクセスの場合は顧客に価値提供していくことも念頭に置くべきミッション

技術方面の実績解除

技術面では、1ヶ月のわりにはバックグラウンドを活かせた実績をいくつか立てられたかなと思っています。「些末すぎていちいち数えてないわー」と言えるようになりたい。

  • Mackerelのメール通知内容の(些末な)問題を修正した 👍
    • Mackerelのメール通知内容で気になるところがある→関係各所につないでもらい、修正したほうがよさそうとなった→対象リポジトリと作法を教えてもらう→PRをお送りする→マージいただいた
  • mackerel-agentのDebianパッケージの(些末な)問題を修正した 👍
  • 実験サービス向けのデモを作った 👍
    • 今月にMackerel開発リモート合宿が開催→ 経験浅すぎなので合宿メンバーにはならなかったけど、合宿テーマの中で実装されていたのが「それ、Mackerelの機能不足部分を埋めるピースにすごく良いのでは!?」と思えるサービスで、飛び入りで様子を拝見→サービス可能性の実例として、誰でも試しやすそうな一発ネタデモがあるとよさそう、と思い立って昼休みにデモアプリをシュッと実装(≒雑に実装)してみた→けっこうウケて良かった(サービスエヴァンジェリストの称号をいただいた)
  • テクニカルサポートを(ごく小さく)お手伝いできた 👍
    • テクニカルサポート方面のミーティングに継続的に参加→Mackerelプラグイン側とMySQL監視との間で奇妙な現象が生じていて悩んでいるという話題が出た→MySQL監視側(Perl)をコードリーディングして現象の原因を突き止めた

カスタマーサクセス方面の実績解除

こちらはさすがにまだやれることは少ないですね。来年は積んでいきたい。

  • 顧客打ち合わせに同席するようになった 👍
    • 顧客の方々との打ち合わせに同席→議事録を作成したり、感想戦で宿題を検討したり→会話の内容は理解できるが、こちらから振っていくにはカスタマーサクセス用語もクラウドも理解があらゆる足りないと痛感する。がんばりましょう 😇
  • ドキュメント品質改善の方向性を立てた 👍
    • ドキュメントの日本語品質が少々安定してない印象(表記の不統一など)→当初JustRight!を考えたが価値提供を考えるとチームや組織へ展開しづらいと思い直した→まずはOSSのテキストのlint系をスモールスタートで導入していこうという方向へ。来月から本格的に進行やっていこう

おわりに

自身がCREとしてやりたいことはたくさんあり、それに見合う知識や能力が不足というギャップが大きくて悶絶してはいますが、来年のアドベントカレンダーを書く頃にはもっと有意義なMackerel情報を提供できるよう精進していきます。

Mackerel Advent Calendar 2022、明日はCREチームの頼れる同僚 id:tukaelu さんです! 的確で迅速なサポート処理をいつも惚れ惚れと拝見しています!