「HRMOS採用」では、採用に関するデータをElasticsearchに保存し検索機能で利用しております。 以前はEC2インスタンスにインストールしたElasticsearchを利用していましたが、スケールやメンテナンスしづらいことからAWSのマネージドサービスであるAmazon OpenSearch Serviceへの移行を行いました。
移行の際には、ユーザに安心・安全な利用をしていただけるように、下記の4つの観点に気をつけました。
- データのロストがないこと
- セキュリティ的に安全であること
- 機能・非機能ともに劣化がないこと
- ダウンタイムなしで移行完了させること
この記事では、特に ダウンタイムなしで移行完了
に至った3つの工夫を紹介します。
※以降、Elasitcseasrch=ES、Amazon OpenSearch Service=AOSと記載します
はじめに
「HRMOS採用」とは?
「HRMOS(ハーモス)」シリーズは、利用中企業数約1000社超の人財活用プラットフォームです。シリーズの一つである採用管理クラウド「HRMOS採用」は、採用業務の一元管理を通じて、オペレーション業務の効率化と、採用スピードの向上を実現できるクラウドサービスです。データによる採用活動の可視化・分析により、数値データを根拠とした戦略的な意思決定を実現し、効果的な採用につなげることができます。
採用に関するデータ(応募者のプロフィール情報や履歴書情報、選考過程でのデータなど)は基本的にRDSにて永続化しておりますが、一部のデータをESに保存し検索性及び検索速度向上に利用しております。
なぜ移行を行ったのか?
以前までは自前で用意したEC2インスタンスに直接ESをインストールしクラスタを構築しておりましたが下記のような課題がありました。
- スケールアップ・スケールアウトを行う際にダウンタイムが発生してしまう
- バージョンアップの際にクラスタを新しく構築し移行する必要がある
- EC2インスタンスの監視やメンテナンス等を気にしなければならない
これらの作業は工数がかかるものが多く、さらにダウンタイムを発生させる必要がある作業もあったため運用コストやリスクが高くなっておりました。 また、ESを利用している部分は「HRMOS採用」にとって重要な機能であるため
利用できなくなる期間 = 利用ユーザ全員の採用業務が停止している期間
となってしまいます。
そのため、極力ダウンタイムを避け、ユーザにできるだけ安心・安全に継続して利用していただき、かつ我々の運用負荷も下げるためにマネージドサービスであるAOSへ移行を決定しました。
移行フローの工夫
「HRMOS採用」ではスクラムというフレームワークを取り入れており、複雑性の高い課題を1スプリント(1週間)で終わらせることができる単位まで細分化しながら開発を進めています。(基本的に週次で定期的なリリースを行っております) かつ、冒頭で挙げていた「移行の際に気をつけていた4つのこと」を満たすために下記のフェーズに区切り進めました。
- 調査/設計
- AOSの構築
- Writer機能の実装
- Reader機能の実装
- ESの停止
特に、Writer機能の実装
と Reader機能の実装
のフェーズを分けた背景には下記のような観点が挙げられます。
- 1リリース当たりの変更量を最小化するため
- それぞれのフェーズで機能要件・非機能要件の検証をしやすくするため
- 問題が発生した際にロールバックをしやすくするため
- 通常のリリースフローに乗せやすくするため
- このようなデータソースを移行するようなプロジェクトの場合、比較的利用ユーザ数が少ない夜間にメンテナンスする手法が挙げられますが、開発者の負担を考慮し通常のリリースに乗せる判断を行いました。
- また、夜間にメンテナンスする際にはカスタマーサクセスチームを通じてユーザへ告知しているなど、開発者以外にも負担をかける場合があるので、できるだけ影響を局所化する目的もあります。
このようなプロジェクトの進め方および、段階的なリリース計画がダウンタイムなしで移行完了につながった1つ目の工夫として挙げられます。
それでは次項以降でそれぞれのフェーズごとに発生した課題や解決方法などを紹介していきます。
各フェーズの工夫
調査/設計
今回のプロジェクトでは下記2つの要件がありました。
- 自前で管理していたものからマネージドサービスへの移行
- ES(AOS)のバージョンアップ
これらの要件を満たすため、下記の観点で調査及び設計を行いました。
- ESと同じ内容でmappingやanalyzerなどの設定を行えるかどうかをsandbox環境で確認
- 当時のESへの負荷状況の確認
- 当時のESへ挿入されているデータ数からの推測したキャパシティプランニング
- アプリケーション側の移行の対象の洗い出し
上記の調査により、大幅にバージョンを上げた場合、ESで適用している設定のままではmappingやanalyzerを期待通り動作させられないことが判明しました。
主な変更点および代替の設定は下記です。
string
タイプの廃止- analyzer経由での検索をしたい場合 →
text
タイプへ変更 - 上記以外の場合 →
keyword
タイプへ変更
- analyzer経由での検索をしたい場合 →
not_analyzed
の指定廃止- stringタイプの場合は前述の通りにタイプを変更することにより、指定しなくても区別できるようになった
_timestamp
、_all
、_ttl
などの設定が廃止- デフォルトの挙動で機能要件を満たせることを確認
このように代替となる設定を行うことでこれを期待通り動作させ、機能要件を落とすことなく設計をすすめることができました。
AOSの構築
ここでは、前章で設計した内容や、ベストプラクティスを参考にAOSを構築することを目指しました。
ベストプラクティス以外に独自で工夫した点としては、「障害発生時を考慮したスナップショット取得及びリストア方法の確立」が挙げられます。 もともとAWS側管理のS3へ自動でスナップショットを取得する機能は提供されていましたが、下記理由で我々管理のS3へもスナップショットを取得するようにしました。
- 障害発生時の復旧時間をより最小にするためにクラスタごと作り直す可能性を考慮した
- クラスタごと作り直した際にスナップショットからのリストアを可能にするため(自動スナップショットからのリストアは不可能だったため)
また、構築を進めていく上で下記の点に大きくハマってしまいました。
- 定期的にマスターノードへの負荷が上がりメモリを逼迫した結果GCが走りリクエストタイムアウトしてしまう
- AOS内部のソフトウェアバージョンが古く、GC時間が長期化してしまっていた
- ソフトウェアアップデートすることにより解消
- 推奨のAOSのインスタンスタイプが設計当初から変更されており最新の推奨設定に追従できていなかった
- 最新の推奨設定へスケールアップすることにより安定稼働
- AOS内部のソフトウェアバージョンが古く、GC時間が長期化してしまっていた
弊社ではAWSとエンタープライズサポート契約を行っているため、TAM(Technical Account Manager)の方へ随時相談に乗っていただいた結果、上記課題を解決することができました。 改めて関係者の方々には感謝申し上げます。
Writer機能の実装
Writer機能としては大きく分けて2つの機能が存在しています。
- 応募者の情報が変更されたことを検知しAOSに挿入する機能
- 応募者の削除を検知しAOSから削除する機能
ここでは、最終的にESとAOSで データの整合性が取れていること
を目指し進めていました。
そこで、下記の手順を踏むことによりデータの整合性を担保しました。
また、これらはダウンタイムなしでの移行の実現に大きく寄与した工夫の一つです。
- ESとAOSの両方に対して同じデータを挿入・削除するように並行稼動
- ESとAOSに入っているデータを比較するツールを作成し監視
- 差分が発生した場合解消するツールを作成し運用
これにより、実際にユーザ影響のあるReader機能を置き換えるまでにはデータの整合性がとれた状態を作ることができたため、移行完了時にデータのロスト(今まで見えていたものが見えなくなっているなど)の報告なく完了に至ることができました。
Reader機能の実装
前のフェーズでESとAOSに入っているデータの整合性は確認できているので、このフェーズでは同じクエリを再現することができるかどうかに注力することができました。
しかし、今回は元々使っていたESのバージョンから大幅なバージョンアップとなってしまったため、mappingの際と同様にクエリの書き方が変わっている箇所が多々ありました。
クエリの書き換えにおいては機能要件を満たせる範囲内での変更に収まったのですが、一部挙動が変わってしまう箇所が発生してしまいました。 原因としてはESとAOSで設定不備により一部のmappingがずれてしまっていたことでしたが、アプリケーション側で差分を吸収できたため最終的には挙動を変えることなく移行できました。
この手の移行を行う際には、設計・調査段階で実際に投げているクエリベースでの検証を行っておくことを推奨します。
また、冒頭で示した4つの観点のうち「機能・非機能ともに劣化がないこと」の要件の一つとして「パフォーマンスの劣化が起きていないこと」を挙げていたため、想定されるリクエスト数の数倍程度で負荷テストをすることで下記に挙げる基準を満たせるか評価しました。
- レイテンシの劣化が起きていないこと(起きていたとしても100ms程度未満)
- リソースのメトリクス(CPU/Memory/JVMなど)が跳ね上がるようなことが起こっていないか
上記の評価結果から、パフォーマンスの劣化が起こっていないことが確認できたため、特にチューニングを行うことなく移行に踏み切ることができました。
ESの停止
最後に不要なESを残しておくことはコスト面やセキュリティ面でも懸念があったため、数週間様子見を行った後に下記2点を確認した上でESの停止を行いました。
- AOS移行によるユーザ影響がないこと(数週間ユーザからのお問い合わせがないこと)
- ESへのアクセスが完全になくなっていること
- ESが動いているEC2コンテナにてtcpdumpを取ることで意図しないアクセスがないことを確認
上記の確認を行った結果、特に問題が発生することなく安全に停止を行うことができました。
まとめ
この記事では、EC2にインストールして自前で管理していたESをマネージドサービスであるAOSへ移行するまでにいたった課題や解決方法を紹介してきました。 ダウンタイムなしで移行を完了できた理由としては、下記3つの工夫が寄与していると考えています。
- Writer機能→Reader機能を分けて段階を踏み移行
- ESとAOSの並行稼働期間を設ける
- ESとAOSの差分監視・解消ツールの運用
最後に今後の展望を述べてこの記事を締めたいと思います。
現状、「HRMOS採用」ではSLOを定めており、各APIのレイテンシなどの監視を行っています。(参考:円滑なエラーバジェット運用に向けた取り組み)
そこで、エラーバジェットの安定稼働のためAOSを更に活用し、ユーザにとってより安心安全なサービスづくりができるのではないかと考えております。