リクルートの情報検索組織において検索APIの基盤をどうやってPaaS中心のシステムに移行したかを紹介する連載。今回は、AWS上のシステムをクラウドネイティブ化する際に用いるべき原理原則について解説する。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
リクルートの情報検索組織において検索APIの基盤をどうやってPaaS中心のシステムに移行したかを紹介する本連載「リクルート事例で分かるIaaS→PaaS移行のコツ」。連載第1回では、情報検索機能を提供する弊組織のスコープとそれを取り巻く環境の変化の歴史的いきさつを解説しました。第2回の今回は、「スコープがシャープに限定されることで、目的達成のためにどのようにクラウドサービスを採用したか」について、われわれのチームが導入した原理原則を交えて技術的な変遷の概要を紹介します。
全体の構成は、初めにサービスとシステムの概要を説明し、「システムにおける各コンポーネントがどのような課題を持ち、それを解決するためにどのようにクラウドネイティブ化したか」を具体的に解説します。次に、クラウドネイティブ化に際し、われわれのチームがその都度導入、参考にした原理原則に関して紹介します。
「クラウドネイティブ化によって各課題を解決する際、われわれのチームがどのように考えたか?」について、原理原則を紹介することによってお伝えできればと思います。内容は、ベーシックなものです。
また、なるべく情報検索に特化せず、情報検索以外のシステムのクラウドネイティブ化に参考になるよう心掛けて記載しました。
試行錯誤や失敗を繰り返し、先人の知恵である原理原則を借りて、あるシステムがクラウドネイティブ化した一例を提供できれば幸いです。
なお、本稿の想定読者は、クラウドサービスを採用する際の、試行錯誤の歴史的な変遷の事例を知りたい方、クラウドネイティブ化におけるチームが採用した原理原則に興味のある方です。
初めに、積極的にクラウドネイティブ化した時期における、提供サービスの背景について説明します。われわれのチームは、検索機能の品質向上をメインに担当するチームですが、同時にサービスを運用するチームでもあります。
われわれのサービスは、情報検索機能のAPIを提供することであり、マイクロサービスにおける1つのサービス/コンポーネントと考えることができます。基本的に、複数のサービスを同じコードベースの共通のシステムで提供していますが、マルチテナントではなく複数のシングルテナントです。われわれのシステムで提供されているサービスは、本記事執筆時で、次のような状態にあります:
本記事では、次の2点を主に扱います。
われわれのシステムは大別して、以下5つのコンポーネントから成り立っています。
各コンポーネントは新旧の世代で混在した状態です。そのような状態ですが、コンポーネント単位で気軽に入れ替えが可能な状態になるまでの事例紹介にもなればと思います。クラウドネイティブ化を進めることによって、各コンポーネントを互いに疎結合にすることが促進され、フレキシビリティを向上させることもチームの目標の一つです。
ここまでのサービス、システム、コンポーネントの関係は図1のようになります。幸い、われわれの扱う情報検索機能は、非常にシンプルな構成をとることが可能です。
連載第1回で触れたように、われわれのシステムの目標は明確になり、スコープが絞り込まれました。
目標は、サービスの改善や新規サービス追加の際、「短期学生バイトや入社直後の新卒の方でも動くAPIを作ることができ、そのAPIの品質向上に利用するデータやアルゴリズムの探索に集中」できることです。われわれのチームに参加してもらったエンジニアが、すぐさま検索サービスの提供や検索品質の改善に集中できるようにすることです。そして、「ユーザー体験やアルゴリズムの試行錯誤を重視した開発の比重が大幅に高まった」ので、それ以外の仕事に割かれるリソースを徹底的に削減し、「フォーマット化、もしくは、テンプレート化」できるようにスコープを絞ることでした。
目標とスコープを先に挙げた5つのコンポーネントに当てはめれば、それぞれに上げた目的に開発者が集中できることであり、フレキシビリティを向上させて試行錯誤を可能にすることです。
われわれのチームの目標とスコープを実現するため、旧世代のシステムから新世代のシステムに移行し、その過程で積極的にクラウドネイティブ化した技術的な変遷の内容と、その過程で採用した原理原則の紹介が、本記事の扱う内容です。
各コンポーネントにおけるクラウドネイティブ化の技術的な変遷を紹介します。何世代かのシステムの変移を、その過程で挙がった課題とその解決を中心に、比較的汎用(はんよう)性の高いコンポーネントを例に紹介します。また、現在検討中の未来像に関しても簡単に触れます。
当初、フェーズ1の状態にあったわれわれのシステムでは、CI/CD(継続的インテグレーション/継続的デリバリー)をJenkinsサーバで行っていました。Jenkinsサーバは、CI/CDに加え、ETL(データ連携、インデックス更新処理)や分析処理のコントロールだけでなく、ETLや分析処理における一部の処理の実行も担っていました。サーバは「Amazon EC2」上で動作し、サーバの構成管理を「Chef」で行います。
残念ながら、Jenkinsサーバは、後ほど紹介する「ペットと家畜」の「ペット」状態でした。Jenkinsサーバがなくなっても、辛うじてサービス自体は継続できますが、その後何もできない状態になります。多少の時間をかければ再構築も可能でしたが、手軽に交換、更新、破棄できる状態ではありませんでした。
特に問題となったのは、Jenkinsサーバが本来データ連携、インデックス更新処理、分析処理という個別のツールやサービスで行うべき処理をローカルの環境で実行していたことです。これは、データや実行時間の増加に伴ってスケールアウト/スケールインができない状態です。
また、後に触れる「単一責任の原則」に違反しているので、Jenkinsの構成自体も肥大化してしまいました。サービスの追加も肥大化に拍車を掛け、「一貫性」は辛うじて構成管理のリポジトリレベルで保持できている状態です。
結果として、もっとも重要な試行錯誤を気軽に試せる状態ではなくなってしまいました。
そこで、フェーズ2への移行とともに、CI/CDの実行環境をサーバレス化し、ETLや分析処理を切り離し、本来のCI/CDの機能、ETLや分析処理のコントロールの実行のみに変更しました。
サーバレス化は「AWS CodeBuild」「AWS CodePipeline」「AWS CodeDeploy」への置き換えです。特にCodeBuildは、Dockerイメージを指定します。個別の実行単位となる各ビルドプロジェクトは、それぞれ限定されたほぼ単一の機能だけになり、Dockerイメージは機能単位を分割してシンプルで独立した状態にすることができました。ETLや分析処理に関しては、次のセクションで詳しく触れます。
詳しくは、連載の後の回で触れますが、次の5つの大きなCI/CD機能を独立してテンプレート化し、手軽に構築、変更、破棄が可能な状態に近づきました。
ここで簡単にですが、構成管理に触れます。Jenkinsサーバの構成管理ではChefを利用していましたが、その後「Ansible」「Puppet」を検討し、さらにクラウドへの特化という文脈で「Terraform」と「AWS Cloud Development Kit」(CDK)を検討しました。最終的に、Pythonベースの開発が多いわれわれのチームは、「AWS CDK in Python」を採用しました(実を申し上げれば、当初AWS CDKを「TypeScript」で記述していましたが、その後「一貫性」の文脈で、可能な限りPythonを採用する方針に転換したので、AWS CDK in Pythonに書き直しました)。
当初、フェーズ1の状態において、われわれのデータ連携は多種多様でした。例えば、データベースのアカウントとパスワードを共有してもらって取得するものや、http経由でこちらからGETするものと相手側からPOSTされるものがあったり、CSV、XML、JSONなどデータフォーマットが分かれていたりと多種多様でした。これらの運用負荷は大変高く、残念ながら「一貫性」は皆無の状態でした。
われわれはフェーズ2に移行する過程でスコープを絞り、データ連携に関しては、次の2つだけのサポートとしました。
連載第1回でも触れたように、リクルートでは全社的にデータ基盤が「Apache Hadoop」からBigQueryに移行しているさなかでした。分析処理自体も複雑なHadoopのMapReduce処理からBigQuery上でのSQLによる実行に変わり、データ連携も必要なデータを「HDFS」(Hadoop Distributed File System)上に配置する処理からBigQuery上のテーブルへのロード処理やテーブル参照に変わりました。
そのため、特にデータ連携に関するETL処理は、それ自体が簡略化されました。現在、全社的なBigQuery化は着実に進んでおり、将来的には全てBigQuery経由でテーブルを参照するだけのフェーズ3の世界に近づきつつあります。
次に、分析処理の実行をCodeBuild、CodePipelineで実行するフェーズ2に移行しました。しかし、図3では簡略化のために省きましたが、CodeBuild上でETL自体を行う処理が残っていた時期がありました。これはJenkins上でETLを行っていたフェーズ1の時代の問題をそのまま継承してしまっています。特に問題視したのは、数千万オーダーのデータをElasticsearchに格納する際、Elasticsearchのクラスタは容易にスケールアウトできても、その強力なクラスタに見合うスケールアウト可能なETL基盤を導入できていなかったことです。
そこで、われわれは「AWS Glue」を導入することで、サーバレス化+容易なスケールアウト/スケールインができるようになりました。特に、Glueは、「AWS Marketplace」で提供されているカスタムコネクターが便利で、次の2つのタスクを「シンプル化」することができました。
われわれはBigQueryと親和性の高い「dbt」の導入を検討しています。dbtによって、複雑化が避けられないCodePipelineにおけるBigQueryのワークフローを「シンプル化」し、「フレキシビリティの向上」を図ろうと計画しています。
詳細は、連載の後の回で触れますが、次の3つの大きなコンポーネントをテンプレート化しました。
これによって、手軽に構築、変更、破棄が可能になり、有用なデータの活用や探索と、分析処理におけるロジックやアルゴリズムの改善に集中できる状態に近づくことができました。
APIサーバとElasticsearchに関しては、各フェーズに分けて解説します。
・フェーズ1:標準的な構成
当初われわれは、APIサーバとElasticsearchに関して、「Load Balancer」とEC2を用いた標準的な構成をとっていました。スケールイン/スケールアウトは、Jenkinsサーバ上でのパラメーター変更(EC2のインスタンス数設定変更など)によって、ブルー/グリーンデプロイメントで実現できていました。また、APIサーバとElasticsearchはLoad Balancerを介して、独立していました。しかし、問題点が幾つかありました。
1点目のAPIサーバの「一貫性」の喪失は、共通のフォーマットを持たないことに起因していました。HTTP経由のRESTfulAPIという点では共通でしたが、それ以上の制約はありませんでした。そのため、サービスごとのAPI定義や構成は独自のものとなり、運用負荷が増大し、敏速な対応が難しい状態になりました。
2点目は、APIサーバとElasticsearchの依存関係です。Elasticsearchはリリースペースが非常に早く、新しいElasticsearchには魅力的な機能が素早く追加されます。しかし、APIサーバは特定のバージョンのElasticsearchに依存することが多く、気軽にバージョンアップするのが困難な状況でした。
・フェーズ2:OpenAPIの導入と行き過ぎた分離
フェーズ1で問題になったAPIの共通フォーマットとして、われわれは「OpenAPI」を採用しました。どのサービスのAPIを見ても、必ずOpenAPIのフォーマットに従っており、一貫性を保つことが容易になりました。
少し脱線すると、「GraphQL」の導入も検討しました。われわれの扱う比較的シンプルな情報検索APIとしてGraphQLを有効活用する方法を見つけることができず、いったん保留としていますが、今後もGraphQLの動向は追っていきます。
次に、フェーズ1で問題になったAPIサーバとElasticsearchの依存関係の問題です。次のように分割して考えるようにしました。
それぞれの機能を分離して考え、各機能を担当するコンポーネントを分離してしまう考え方は「単一責任の原則」に合致するものでした。APIサーバの責任は「Elasticsearchへの検索クエリの発行」です。また、われわれはもう一歩進み、APIサーバが利用するElasticsearchを「検索品質向上におけるクエリの解釈や他のAPI情報の利用」における「他のAPI情報」の一つと位置付けました。
しかし、フェーズ2におけるわれわれの解は、正直に申し上げてあまり良いものでありませんでした。われわれの考えた解決策は次の通りです。
1つ目の解決策「データ込みのDockerイメージ」には、長所もありましたが、われわれの利用方法に致命的な短所がありました。
長所としては、次の通り。
われわれの利用方法における致命的な短所は次の通りです。
共に、実行環境と作成環境のスケールアウト/スケールインの複雑化と、特にインデックスが巨大な場合には、それに比例して環境が複雑化しました。
2つ目の解決策「もう一つのOpenAPIサーバレイヤーの導入」も、同様に長所もありましたが、そのような長所を相殺して余りある短所がありました。「もう一つのOpenAPIレイヤー」は、「OpenAPIで定義されたリクエストからElasticsearchのクエリへのマッピング」「ElasticsearchのレスポンスからOpenAPIのレスポンスへのマッピング」のみのOpenAPIサーバです。しかし、このようなレイヤーを導入しても得られるものは少なく、「Elasticsearchの依存関係を取り除いても、APIサーバ自体の複雑さを軽減しない」「2つのマッピングの制約と複雑さからフレキシビリティが低下する(あまり本質的ではないマッピングの作成に時間を取られる)」といった短所だけが浮き彫りになりました。われわれは早急にフェーズ3に移行する必要がありました。
ここで、簡単にですが、実行環境に触れます。われわれは、ECSと「AWS Fargate」を選択しました。というのも、比較した当時「Amazon Elastic Kubernetes Service」(EKS)にFargateがなかったことと、ECSのシンプルさに引かれたからです。ECSの導入によって、われわれは、サーバレス化することができ、手軽にシステム全体の交換、更新、破棄が可能になりました。今後もECS、EKS、「AWS API Gateway」などの進化の動向を、注意深く追います。
・フェーズ3:シンプルなAPIサーバへの回帰とOpenSearch Serviceの導入
フェーズ2における反省から、フェーズ3でわれわれは「「シンプル」にElasticsearchを利用する(OpenSearch Serviceの導入)」「OpenAPIサーバは、Elasticsearch から可能な限り独立させ、「シンプル」な構成とする」と考えました。
OpenSearch Serviceの導入メリットは大きく、安定運用に関する「マルチAZ構成」「マルチマスター構成」「専用マスターノード」メリットは特に大きいものでした。もちろんですが、フェーズ2におけるElasticsearchに対する3つの機能別のコンポーネント分割を阻害するものは、何もありません。
最終的に、3つコンポーネントは次のようになりました。
最後に挙げたOpenAPIサーバにおけるSearch Templateは肥大化しやすいElasticsearchのクエリにプレースホルダー(正確にはmustache形式のテンプレート)を指定してサーバに格納し、プレースホルダーに対応するパラメーターのみをリクエストすればクエリが発行できる仕組みです。
このElasticsearchの機能のみを利用することによって、OpenAPIサーバは「リクエストを投げる先がElasticsearchだ」とほとんど意識する必要がなくなります。われわれが必要としたAPIサーバとElasticsearchの依存関係の解決にはSearch Templateだけがあれば十分でした。副産物として、どのサービスの、どのクエリも、必ずSearch Templateを持つことになり、「一貫性」を保つことができました。
余談ですが、Elasticsearchの管理、格納されたデータの可視化、改善の試行錯誤のために、「kibana」(OpenSearchでは「OpenSearch Dashboards」)を利用していました。OpenSearch Serviceを使う以前は、ローカル環境にkibanaを立ち上げて試すことが多かったのですが、OpenSearch Serviceの場合は自動でOpenSearch Dashboardsが付与されて立ち上がるので、個別にkibanaを立ち上げる必要がなくなり、大変便利になりました。
最終的に、詳細は連載の後の回で触れますが、次のように「APIの品質向上」の本質的に関わる部分に集中できる状態に近づきました。
最後は、負荷テスト、Integration Test(統合テスト)、検索品質テストについてです。われわれは、これまで3つのテストをそれぞれ異なるツールで行っていました。
負荷テストは、過去のログなどを大量に用意して「Jmeter」で実行することになります。負荷テストなので、強力な検索API用のクラスタを準備した場合、Jmeter自体もそれに見合うクラスタとして構築する必要があります。われわれはこれらの構築をうまく簡素化できていませんでした。
検索品質テストについては、手元に必要なクエリをBigQueryや過去ログから生成することで用意し、検索クエリに変換して投げ、検索結果を再度BigQueryに格納するなどを行っていました。
残念ながら、これらの環境構築方法や実行方法は手順書などを残すのが精いっぱいで、なかなか有用な共有できる資産として残すことができていませんでした。
そこでわれわれのチームは、3つのテストが共通項目を持つことに着目し、より柔軟なテストが可能な「Locust」を使うことで、3つのテストの統合とコードによる資産化を進めることにしました。その機能の例を挙げると次のようになります。
Locustの実行環境をECS(Fargate)にすることによって、テスト環境もサーバレス化することができ、スケールイン/スケールアウトも容易になりました。同様のDockerイメージを利用することで、CodeBuild上の統合テストで流用することも可能になりました。これまでチーム内での共有がなかなかスムーズでなかったテスト関連の資産を、コード化することで共有できるようになりました。Locustを用いたテストに関しては、連載の後の回で詳細に触れます。
ここまで、各コンポーネントのクラウドネイティブ化の技術的な変遷を紹介しました。その紹介の中で、幾つかの判断基準などを用いたことにお気付きになったと思います。ここからは、そのような判断が必要になった際に、われわれのチームが取り入れた原理原則を紹介します。
残念ながら、これら原理原則の導入は、時系列で表すには非常に複雑で、奇麗な年表を作成するのは困難でした。「紆余(うよ)曲折を繰り返した」のが現実です。チーム全体で原理主義に捕らわれることがないように注意しました。チーム全体が原理原則でがんじがらめになるのではなく、それとはまったく逆で、「Aの指針に従えばXがいいけど、Bの指針に従えばYもいいね」といった柔軟に対応するための潤滑油として利用しました。
われわれの採用した原理原則は次の4つです。
原理原則を導入した背景は次のようになります。目標が決まり、スコープが絞り込まれ、QCD(Quality、Cost、Delivery)を考慮して優先順位を決め、われわれは現システムの構築と改善に取り掛かりました。しかし、最も優先順位の高い改善項目から取り掛かろうにも、アーキテクチャの採用やシステムの改善での各レイヤーやコンポーネントにおいて、チームで決定を下す際の指針に曖昧な点が多かったのです。そこで、幾つかの原理原則を導入することによって、長所と短所を比較し、チームで決定を下すことにしました。
ここからは、「原理原則をわれわれのチームがどのように適用したか」を紹介します。
「クラウドネイティブ」の解釈は多々あると思いますが、まず、われわれのチームが採用した「クラウドネイティブ化」はシンプルにクラウドサービスを徹底的に利用することでした。同時に、クラウドサービスを利用できるように、スコープに合わせて機能を絞り込み、旧世代のシステムを変更することでした。そこでわれわれの指針は、次のようになりました:
お気付きの方もいるかもしれませんが、上記の内容は「マイクロサービス」の特性の幾つかです。そして、マイクロサービスの掲げる敏速さは、われわれの目指す検索品質向上のために、試行錯誤の回数とスピードを上げることに合致していました。
われわれの採用した指針は、特別なものではなく、一般的な内容であり、多くのシステムが目指すべき指針と考えられます。しかし、われわれの目標とする「フォーマット化、もしくは、テンプレート化」には十分とは考えられませんでした。というのも、旧世代のシステムも掲げられた指針を満たすケースが多かったのです。旧世代のシステムが十分に「フォーマット化、もしくは、テンプレート化」できているとは言えません。そこで、われわれが「フォーマット化、もしくは、テンプレート化」のためにさらに採用した4つの指針は、次の内容でした。
各内容には関しては、続くセクションで触れます。これら「4つの指針」をクラウドネイティブ化によって向上させるために、さらなる原理原則が必要となったのです。
2つ目は、われわれのチームが「ペットと家畜」(もしくは「Pets vs. Cattle」)の文脈で語られるメンタルモデルを持つことでした。「ペットと家畜」のメンタルモデルを持つことで採用した指針は、先の「クラウドネイティブ化」や「マイクロサービス」における指針と多くの点で重複する内容です。重複していますが、ここでは少し踏み込んで、より詳細な指針の内容を紹介します。われわれのチームは、次のように考えるようになりました。
これらの指針は、われわれが重視した「4つの指針」の促進に、マッチしました。例を挙げれば、ほとんど全ての実行環境をDocker化することは、「シンプル化」「安定運用」「一貫性」に寄与します。また、容易にスケールアウト/スケールインできることは、「安定運用」「フレキシビリティ向上」に寄与します。
3つ目は「KISSの原則」です。これは「4つの指針」の「シンプル化」に直接つながります。あえて、ここに「KISSの原則」を挙げたのも、「シンプル化」はわれわれにとって重要な指針だったからです。また、ある指針が他の指針を強化する場合や、相反する指針に直面した場合に、「われわれのチームがどのように考えたか?」の一例になると考えたからです。
1つ目は、「シンプル化」は「安定運用」にもつながると考えた点です。これは続くセクションで取り上げる「SRE」の文脈でも語られている内容です。先に紹介したように、われわれのチームは複数のサービスを運用しています。各サービスは同じコードベースのシステムで運用されていますが、必ずしも一様ではなく、個々のサービスがもつ特性によって差異が生じます。少ない人数のチームで、差異がある複数のサービスを「安定運用」するには「一貫性」が必要ですが、どうにか「一貫性」を保ちたいと考えても、個々のサービスからの要求によって「一貫性」は崩れます。また、過度な「一貫性」はそもそものサービスの価値を生み出すことを阻害しかねないことに注意しました。「試行錯誤」ができなければ、そもそもの目標を達成できないことになります。そのためにも「4つの指針」に「フレキシビリティの向上」を含めました。
「安定運用」のためにも「一貫性」を保ちたいのですが、必ずしも「一貫性」は守り切れず、妥協が必要でした。そこで、代わりに徹底して「シンプル化」すれば、「一貫性」を崩す差異も明白になり、「シンプル化」の恩恵によって運用負荷が削減され、「安定運用」につながると考えたのです。KISSの法則の説明にある、ケリー・ジョンソンが設計チームに一握りの工具を手渡して出した課題にある「平凡な整備員が戦闘状況で、この工具だけを使って修理ができるようなジェット戦闘機」のようなシステムこそ、われわれの目指すシステムでした。
2つ目は、「シンプル化」を促進できなければ、目標としている「フォーマット化、もしくは、テンプレート化」が難しいと考えたのです。先に挙げた「4つの指針」にある「一貫性」は、そのまま「フォーマット化、もしくは、テンプレート化」に寄与しますが、先述の通り「一貫性」には妥協が必要でした。ですが、あまりに妥協を重ね、例外や形式化から逸脱した内容が過多になれば、それはほとんどフォーマット化やテンプレート化に失敗していると考えなければなりません。また、あまりに長大なフォーマット化やテンプレート化も、そもそものフォーマット化やテンプレート化に意味がなくなってしまいます。十分に意味のある「フォーマット化、もしくは、テンプレート化」のためにも、「シンプル化」が必要と考えました。
われわれがKISSの法則に反すると考えた例を挙げると、次のようになります:
最後の「開発プロセス」は、連載第1回で紹介した「誰でも簡単に早く開発できる状態を目指した開発プロセスのフォーマット化」で触れた開発プロセスであり、連載第3回、第4回で詳細に触れます。
「シンプルである」ということは、個人によって差異のあることですし、また、定量的に評価することも難しいことです。また「KISSの法則」は、なにがしかの明示的な規則や規定を意味しているわけではないので、大きな指針として用い、他の指針やルールを適用する際の上位に位置する指針と考えました。先に挙げた例は、他の規約や方法論からの抜粋がほとんどであり、続く「SREの導入」でも語られる内容です。繰り返しになりますが、他の指針である「一貫性」や「フレキシビリティの向上」も踏まえて、「シンプル化」を満たしているかどうかも検討しました。
最後に挙げるのがSRE(Site Reliability Engineering)の導入です。先にも述べた通り、われわれは、検索機能の品質向上をメインに担当するチームですが、同時にサービスを運用するチームでもあります。幾つかのサービスやコンポーネントを改善、新規追加する過程で、運用上の問題が明らかになりました。
そこで、チーム全員で書籍『SREサイトリライアビリティエンジニアリング――Googleの信頼性を支えるエンジニアリングチーム』(オライリー・ジャパン)を読み、問題点や改善点を洗い出し、ポストモーテムを繰り返しました。そして、問題点、改善点と対応するSREでの推奨内容を照らし合わせ、クラウドネイティブ化による改善方法を決定しました。
われわれの問題点、改善点と対応する書籍の章を幾つか挙げてみます。
SREは方法論なので、直接的な解法を得られるわけではありません。われわれはSREを、「自分たち行おうとするクラウドネイティブ化による改善方法が、SREの推奨する方法をうまく実践できるか?」の良きチェックリストとして、利用しました。
少し脱線しますが、書籍では第9章で「単純さ(Simplicity、シンプルさ)」が取り上げられています。短い章ですが、先の「KISSの法則」を補強するために、大変参考になりました。
最後に挙げておくべき点として、SREの中で語られるSLA(Service Level Agreement、サービスレベル目標)の導入です。恥ずかしながら、われわれは運用上の問題が起きた際、適切なアクションができているとは言い難い状態でした。それは多くの場合、SLAが適切でないことに起因していたのです。現在も続けて改善に取り組んでおり、われわれのチームは適切なSLAによって適切な監視、適切なアクションが取れる運用状態を目指しています。
また、現在、われわれのチームではVSM(Value Stream Mapping)が導入され、さらに改善を明確化しています。
本稿では、なるべく検索に限らず他のシステムのクラウドネイティブ化の参考になるようにと思い、残念ながら検索の品質向上に関する内容には触れることができませんでした。幸い、最近リクルートの社員も執筆に参加した『検索システム ― 実務者のための開発改善ガイドブック』(ラムダノート)が出版されました。より検索システムに特化した改善の内容に興味のある方は、こちらの本を手にとってみてください。
最終的に、われわれのチームが構築した現行のシステムは、「短期学生アルバイトや入社直後の新卒の方でも動くAPIを作ることができ、そのAPIの品質を向上させるために利用データやアルゴリズムの探索に集中すること」ができ、「ユーザー体験やアルゴリズムの試行錯誤を重視した開発」を円滑に行うシステムに、少しでも近づけたかと思います。しかし、このシステムは2022年5月現在のスナップショットであり、開発環境の改善、可用性の向上、検索品質向上のために利用できる機能の拡充など、われわれの導入した原理原則に照らし合わせれば、課題はまだまだたくさんあります。
また、原理原則が目的達成にそぐわなければ、それ自体のアップデートも必要になります。引き続き、システムの改善と進歩が必要だと感じています。そして、特に、検索のユーザー体験向上や、そうするために試行錯誤の領域を拡大することは、無限に続くと思われます。
Copyright © ITmedia, Inc. All Rights Reserved.