HTTPキャッシュに学ぶ、無理のないドキュメント更新運用
LAPRAS株式会社でSREをしていますyktakaha4と申します 🐧
私は 2021 年の 1 月に LAPRAS に入社 したのですが、
入社以来ほそぼそとやってきた、ドキュメンテーションに関する取り組みについて一年ほど運用し一区切りがついたので、その話をしたいと思います✍
ことのおこり
現在弊社には正社員・業務委託あわせて 18 名程度のエンジニアが在籍 していますが、
私が入社した頃はエンジニアが7名程度、かつ全体の人数に対して在任歴の長い人が多かったこともあり、
開発者が参照するドキュメント管理について、比較的牧歌的な運用がなされていました 🐑
具体的には、開発環境の構築方法が古い手順のまま放置されていたり、オンボーディングに使うドキュメントが口伝されていたりと、
ドキュメント自体は存在するものの、それらが 古くなっていたり一覧化が不十分であることが検知できず、時間経過に伴い利用できないものになってしまう という課題がある状態でした
元々弊社には ホラクラシー という組織体系が導入されカルチャーとして浸透していたことから、
自信がおこなっている業務や役割について明文化をおこなうことは積極的におこなわれていましたが、
そうして作られたドキュメントは割と一過性の熱量で書かれやすいのと、書いた本人がそのドキュメントを完成する頃には対象に対する理解や知識が十分深まっているため、
その後ドキュメントを継続更新するモチベーションが下がり、結果陳腐化が発生してしまう…という状況であったように思います☔
また、新入社員側としては、皆が参照しているのがどのドキュメントであるか、それが勝手に編集してよいものかどうか分からないと、
仮にドキュメントに誤りを見つけたとしても修正するかどうかが人の性格に依存しやすい問題もありそうです
というような課題に対して、2021年の3月頃にCTOの rocky さんから打診があり、 ライブドキュメント
という名前のロール(ホラクラシー組織における役割的なもの)にアサインされました🐴
当時打ち合わせたときの esa が出てきたので引用
これに対して、 なるべくみんなに負荷をかけず、かつ死なずに運用されるドキュメント更新の仕組みづくり を考えていくことになりました…
設計
価値の高いドキュメントの定義
ドキュメント管理について先達を尋ねると、クラウドネイティブ時代の運用を考える〜ドキュメント駆動運用へ〜というよさげなスライドが見つかったので、まずはこちらを起点に考えていきました
特に問題を整理する上で助けられたのは、p26 で言われている、ドキュメントは 費用性
のものと 資産性
のものに大別できるという考え方でした💰
-
費用性ドキュメント
- 反復利用、部品再利用性の低いドキュメント
- 差分更新の効果が低く、作成直後をピークに以後陳腐化していくドキュメント
-
資産性ドキュメント
- 反復利用・部品再利用性の高いドキュメント
- 変更差分の継続更新により陳腐化回避を実現しているドキュメント
例えばバグトラッカーへの記録や本番データパッチのログのようなドキュメントは、最初は費用性ドキュメントとして日々の業務に対して逐次作成されますが、
それらが継続的におこなわれる過程で少しずつ変化しながら洗練されていき、最終的にはバグ起票〜クローズまでの運用マニュアルであったり、本番作業手順書といった資産性ドキュメントとして状態が固定され、
以降はそのドキュメントの変更差分を継続更新して価値の高い状態を長期間維持することが重要だ…ということのようです
(自分の認知なので、作者の意図と違っていたら 🙏 です…)
https://www.slideshare.net/opelab/20151031-54589738 より引用
話を引き受けた時は、ぼんやりと 内容の正しいドキュメントを管理する仕組みが必要そう といったイメージしかなかったのですが、
このスライドを読んで以来 継続更新されている新鮮なドキュメントを増やすことが結果的に正しさと価値を生むのだ と感じ、
実際の仕組みもそうした価値観が浸透したものにしたいと考えるようになりました⏳
新鮮なドキュメントの管理手法
ドキュメントの新鮮さを管理する仕組みを作る という方針が固まったところで、早速具体的な運用を考えてもよかったのですが、
兼ねてから 全てを新し再設計するよりも、既に世の中にある考え方を拝借してきたものの方がきっと広く受け入れてもらえるはず…
と思っていたので、
なにかいいネタ元は無いかと思案していました🍣
そんな中、当時数人の知人とおこなっていた輪読会の中で Web配信の技術 という配信にまつわる要素技術について解説する本(良書です。オススメ)を扱っていたのですが、
読み進める過程で HTTPキャッシュのメカニズムって今回実現したいことと似てる気がするな〜
と考えるようになりました
以下、謎の言説を展開していきます…👺
共有キャッシュの話
HTTPキャッシュの目的は、オリジンの負荷の低減や帯域の節約の結果として、 クライアントがあるリソースを手に入れるのにかかる時間を短くする ことにあるものと思います
加えて、それがCDN等により提供される共有キャッシュであれば、複数のクライアントでキャッシュを共有することで スケールアウトに対応できる という特性もあります
ただそこにはトレードオフもあり、キャッシュとオリジンの内容に乖離がある場合 不正確な内容を参照するリスクがあるという懸念があります🐿
対してオリジンのWebサーバに直接リソースを要求した場合は、 時間がかかり、スケールも難しいが正確な内容 を得ることができます
図にすると以下のような感じでしょうか
HTTPキャッシュの概念図
この構図について、 クライアント→開発者
、共有キャッシュ→ドキュメント
、オリジン→ソースコードやドメイン知識
と読み替えてみるとどうでしょうか
開発者はコードリーディングや実際に業務をおこなうことで、プロダクトのシステム・ドメイン上の性質を 正確に知ることができますが、各自で一定の時間を費やす 必要があります
一方で、システム構成図や業務知識の用語集といったドキュメントの読み合わせをすると、 複数人がより早い時間で知識を得ることができますが、内容が古かったり不正確である リスクを受け入れなければいけません
ドキュメントの概念図
似てませんか?
似てますよね!!
Fresh/Staleなキャッシュの話
ドキュメントの更新方法や、古くなったドキュメントをどう取り扱うべきかについても、HTTPキャッシュから示唆を受けました💵
以下に、HTTPキャッシュにおけるリソースの更新サイクルの概観を説明します
実際は、オリジンより返却するHTTPレスポンスヘッダによって多様なコントロールが可能ですが、記事の要旨に沿ったユースケースを前提に紹介します
キャッシュストレージに格納される際、リソースはFresh / Staleのうちいずれかの状態を取ります🍇
Stale状態になったリソースは、オリジンに対して内容が最新であるか再検証をおこない、内容を最新化した上で再度Fresh状態に遷移します
また、最新化がネットワークエラー等に失敗した場合でも、一定期間の間はStale状態のキャッシュ利用を許容する…といった指定も可能です
-
Fresh(新鮮)
- キャッシュされている内容が利用に十分な鮮度をもっており、オリジンからの再取得が不要であることを示す
-
max-age
ディレクティブ等により示される有効期限を過ぎるとStale状態に移行する
-
Stale(陳腐化)
- キャッシュされている内容が古く、オリジンへのRevalidate(再検証)が必要であることを示す
-
stale-while-revalidate
ディレクティブが指定されている場合、一定期間Stale状態のキャッシュを返却するが、バックグラウンドで非同期にキャッシュ更新を実施する -
stale-if-error
ディレクティブが指定されている場合、Revalidateが失敗した場合でも一定期間Staleキャッシュを返却する
図にすると以下のような感じでしょうか
特に、 内容の新鮮さをキャッシュ生成からの経過時間で評価する 、 キャッシュが古かったとしても一定のポリシーを定めた上で極力再利用する といった考え方については、
開発者に極力負荷をかけずに更新運用を継続したい…という今回のユースケースに合致しているように感じます🍍
キャッシュの状態管理の概念図
上記のような設計を参考にしつつ、実際の更新運用を検討していきました
運用
最終的に ライブドキュメント として規定した運用について、全社展開にあたり作成したマニュアルから抜粋します
運用フロー
運用全体のフローについて示します🛀
ライブドキュメント運用フロー図
まず、 ライブドキュメントロール
と その他のロール(例えばアプリケーション開発者)
という2つの役割が登場します
ライブドキュメントロールは、HTTPキャッシュサーバーのように ドキュメント鮮度の管理
について責任を持ちます
対してアプリケーション開発者のロールは、ドキュメントの利用者であると共に ライブドキュメントの要求に伴いドキュメントを更新
することに責任を持ちます
鮮度の管理と更新の責務を分離することで、特定の人物だけに最新化の負荷がかかってしまったり、更新頻度にぶれが起きないようにできます🦈
2つのロールが、以下の手順でドキュメントの作成と管理を協力しておこないます
- アプリケーション開発者ロールは、自由にドキュメンテーションをおこなう
- アプリケーション開発者ロールは、複数人で共有して鮮度管理をおこないたいドキュメントを選出し、ドキュメントツールのタグ機能等を用いて
#live-documentタグ
を付与する。また、インデックスドキュメント
に追記をおこなう - ライブドキュメントロールは、
#live-documentタグ
が付与されたドキュメントの最終更新日が一定期間に収まることを定期監視する - あるドキュメントの最終更新日が一定期間を超過した場合、
Staleドキュメント管理シート
に追記をおこない、Validateプロセス
を実施する - プロセスの結果に応じて、アプリケーション開発ロールへの最新化要求をおこなう
弊社ではドキュメント管理に esa を利用しています。またソースコードに関するドキュメンテーションはGitHubリポジトリ上のREADMEに記載しています
esaには タグ 、GitHubには トピック とそれぞれドキュメント分類機能が備わっているので、それらを利用して #live-documentタグ
を設定します
タグのついているドキュメントは必然的に共有物である認識がされますので、個人メモ的な階層に格納されていても許可不要で更新してよくなりコミュニケーションコストが下がります
#live-documentタグがついている様子
ドキュメントの更新状態の監視については各社の会議体に合わせた運用でよいものと思いますが、
弊社ではホラクラシーにおいて規定しているタクティカルミーティング という定例会で、月次にてチェックをするようにしています
ドキュメントがStaleしているかどうかは月次でチェック
インデックスドキュメント
インデックスドキュメント
は、 #live-documentタグ
が設定されたドキュメントのみを集約したドキュメントです📉
本ドキュメントを参照することで、社内で現在どのような内容についてドキュメンテーションがされているかひと目みて分かります
インデックスドキュメント
インデックスドキュメント
の更新運用は以下のように規定しています
個人的趣味からRFCを意識した書き方にしてみています
このドキュメントの位置づけ
- ライブドキュメントロールの責務において、Productサークル内で
Freshなライブドキュメント
を集約しています- 本記事に関連して、利用者の裁量において以下をおこなうことが めっちゃ推奨されます(RECOMMENDED)
- リンク先のコンテンツの内容を更新する
- リンク先のコンテンツを分割・統合する
- この時、追加で以下の作業を しなければなりません(MUST)
- 分割先のコンテンツ、または統合先のコンテンツに
#ライブドキュメント_SWE
タグを設定する- Indexに新規のコンテンツへのリンクを追加する
- この時、追加で以下の作業を しなければなりません(MUST)
- 新規追加したコンテンツに
#ライブドキュメント_SWE
タグを設定する- Index更新の事実をライブドキュメントロールに通知する
- Slackにて
@role-product-live_document
に対してメンションして教えて下さい!- また、利用者の裁量において以下をしてはいけません(MUST NOT)
- Indexからコンテンツのリンクを削除する
- タグの削除はライブドキュメントロールのドメインによりおこなうものとします
- この時、ライブドキュメントロールに対して削除の提案をすることができます(MAY)
- Slackにて
@role-product-live_document
に対してメンションして教えて下さいライブドキュメント_SWE
タグを設定できないURLのリンクを新たに追加すること
- Slackにて@role-product-live_document
に対してメンションして教えて下さい
Staleドキュメント管理シート
Staleドキュメント管理シート
についても紹介します🍴
実体は以下のようなカラムをもったスプレッドシートで、ライブドキュメントロールとアプリケーション開発ロールを含むその他ロールが共同で更新します
Staleドキュメント管理シートのイメージ図
弊社では最終更新日から3か月を超えたものを本ドキュメントに月次チェックして追記&週次でStale状態の解消をチェックする運用としていますが、これも各社のドキュメントに対する重要度にあわせて設定するとよいと思います
管理シートに記載したドキュメントがFreshになったかどうかは週次でチェック
Validateプロセス
は以下のような形で運用します
-
- ライブドキュメントロールにてStaleしたドキュメントを追記し、以下カラムを更新
- 記入日
- 記入者
- ドキュメントURL
- 記入者コメント
- ドキュメント内容を確認し、現状の業務と照らして今後も維持が必要かどうか一旦の判断結果を記載
- 記入者の判断
- Validate: 維持が必要のため、Freshなドキュメントにすることを担当ロールに対して要求
- Invalidate: 維持が不要のため、
#live-documentタグ
を削除してよいか担当ロールに確認
- 担当ロール・担当者
- ライブドキュメントロールにて指定した任意の人物
-
- 担当ロールが更新
- 担当者の判断
- Validate: ドキュメントを必要に応じて最新化した上で、最終更新日を更新
- Invalidate:
#live-documentタグ
を削除
- 担当者コメント
- 担当者の判断列の更新に際してのコメント
- 担当者完了
-
- ライブドキュメントロールにおいて担当者完了までチェックがおこなわれていることを検証の上、記入者完了をチェック
運用における重要なポイントとして、 Staleドキュメントを内容が古いことを把握しながら利用する ことがあります
修正担当者を割り当てて依頼することと状況確認までは確実にやる代わりに、修正が完了していない人に対して繰り返し要求したり、ペナルティを課すことは望ましくありません
社内にドキュメントが蓄積していくにつれて、更新負荷は高くなり最新への追従も徐々に難しくなります
そうした現実を受け入れた上で、例えば 新入社員が入ってきた時にオンボーディング系のドキュメントがStaleしている時は優先してFresh化する
といったトリアージをしたり、 Staleのまま放置されるドキュメントが増えた時に同期で更新する会を設定する
といったテコ入れをするとよいでしょう⛳
評価
といったオペレーションを2021年3月から開始し、1年間運用した結果どのようになったか調べてみました📈
比較のために、 運用1年前からの数値についても示します
#live-documentタグ
が指定されたドキュメントの、月ごとの平均更新回数は以下となりました
運用開始前はドキュメントの更新が無い月もあったようですが、タグが指定された記事数が3倍程度になったにも関わらず、更新頻度を伸ばすことができているようです
タグのついた記事数(左軸)と記事あたりの更新回数(右軸)
ある月において、 #live-documentタグ
が指定されたドキュメントの何割がFreshな状態(最終更新日が3か月以内)を維持できていたかみてみます
運用前は半分程度のドキュメントの最終更新日が3か月より古い状態でしたが、直近では70〜80%、先月は全てのドキュメントがFresh状態にできていたようです🍎
タグのついた記事数(左軸)とFreshな記事の割合(右軸)
記事を更新している人に偏りがあるかもみてみます
直近では、半数ほどのエンジニアがドキュメントを更新しており、更新回数もある程度の頻度が担保されていそうです🍮
記事を更新した人数(左軸)と更新者あたり更新回数(右軸)
本質的には、最終更新日が新しいからといって必ずしも実態に即したドキュメントであるとは限らないはずですが、
自分以外の複数人がドキュメントについて定期的に確認をおこなっている という状態は、
新入社員にとってはドキュメント管理に対する安心感を与えますし、既存社員にとっても取り組みが可視化され相互協力する意欲が自然に生まれるように感じました
現在は、直近で入社したSWEの kumamoto さんに運用を徐々に引き継いでいるところですが、
手作業の部分が多かったり、運用の効果測定の部分で課題もあるので、改善や変更をすすめてもらえたら嬉しいなと思っています💕
あと、エンジニア以外でも、オンボーディング関係のドキュメント管理に課題を感じていた法務のいいださんに使ってもらったりといったことも社内で起きており、そうした面でもやってよかったなと思います
うれしいぞ
おわりに
Googleが公開しているSRE本にはサービス信頼性階層という示唆に富む図があり、その一番基礎の部分には Monitoring
と書かれています
価値提供の根底にはまず監視がある という価値観は様々な分野に適用できる考え方だと思いますので、今後も肝に命じてやっていきたいと思います…!
https://sre.google/sre-book/part-III-practices/ より引用
そんな弊社で働くことに興味を持たれた方、よければこちらもご覧ください
文中でも紹介したCTOのrockyさんとのカジュアル面談を希望される方はこちらから
Discussion