こんにちは。サーバーサイドエンジニアの青山です。
今回は、ElastiCache for Redisのメモリ使用率を削減したときのことを紹介します。
はじめに
早速ですが、Studyplusにはタイムラインという機能があります。タイムラインにはユーザー、フォロワー、教材、達成目標など様々な種類のものがあり、その一部のデータを返すためにElastiCacheが使われています。
ある日、別件でタイムライン表示に使われているElastiCacheを調べているとメモリ使用率が右肩上がりで増え続けていることに気付きました。
グラフの通り、過去15ヶ月で24%程度(月に1.6%のペース)で増加しており、このままだと大体15ヶ月後には100%に到達してしまう状態です。
また、同様に項目数も増え続けている事が分かりました。調査時点で2100万件程度です。
そこで、まだリソースに余裕があるうちに何か対策をしようと動き始めました。
現状把握
対策するにもなぜこのような状態になっているのか知る必要があります。まずは現状把握することから始めました。
すると、調査の結果から以下のことが分かってきました。
- ElastiCacheに保存されているデータのほとんどは教材タイムラインのデータだった。
- 教材にはユーザーが登録できる独自教材というものがある。
- 教材タイムラインの多くはこの独自教材によるもの。
- 独自教材は他のデータに比べると増加ペースが早い傾向にある。
- 教材の登録ペースが早くなると限界に到達する時期も早くなる。
- 教材にはユーザーが登録できる独自教材というものがある。
- 教材タイムラインのデータは再生成にかかるコストが高いという理由で削除されないように作られている。
対応案の検討
避けようがないものであればスケールアップしてしまうのも手ですが、円安によってコストが増加していることもあり、まずは本当にデータを削除できないか考えることにしました。
- タイムラインに保存するフィードの上限数を減らす。
- ユーザー登録の独自教材という性質上、そもそも1つの教材に対するフィード数が少ない傾向。
- 項目数が増え続けることに変わりがない。
- 最低限欲しいフィード数まで減らしても5%程度の削減にしかならなそうだったため見送り。
- 利用頻度の低い教材タイムラインのデータを一定期間後に削除する。
- APMなどを見ると他のタイムラインに比べてアクセス数が少ない傾向にある。
- 全タイムラインのうち教材タイムラインへのアクセスは3%程度だった。
- 改めて再生成する処理のパフォーマンスを確認したところ、十分耐えられそうだった。
- 保存するフィード上限数、クエリの実行計画、アクセス頻度から問題なさそうだった。
- アクセス頻度と想定しているTTLの期間からすると、教材タイムラインの項目数を150万件程度まで減らせそう。
- メモリ使用率削減への影響も大きいため採用。
- APMなどを見ると他のタイムラインに比べてアクセス数が少ない傾向にある。
実際の対応
TTLを設定して利用頻度の低いデータを一定期間後に削除するという方針が見えてきたので、あとはやっていくだけです。
- アプリケーション側を修正する。
- 読み取りと書き込みのタイミングで教材タイムラインのTTLを設定(延長)する。
- 一定期間中アクセスがなければデータが破棄されるようにする。
- 読み取りと書き込みのタイミングでElastiCacheにデータがなければRDBからデータを取得してキャッシュし直す。
- 読み取りと書き込みのタイミングで教材タイムラインのTTLを設定(延長)する。
- 修正以前の過去データにTTLを設定する。
- Rakeタスクを用意して手動実行した。
- 何かあったときのリカバリや徐々に設定数を増やすために様子見しながらやりたかった。
- Rakeタスクを用意して手動実行した。
対応後
やった事自体はシンプルですが、以下のように大きく削減できました。
メモリ使用率は78%から30%前後まで削減。
項目数は2100万件から350万件まで削減。
おわりに
タイムラインはコア機能の1つということもあり、入念に調査をして対応をしたためそれなりに時間がかかってしまいました。しかし、そのおかげか作業自体は何事もなくスムーズに終えることができたのでホッとしました。
メモリ使用率の削減もですが、データが増え続けることについても対応できたのでしばらくは安心して過ごせそうです。