既存システムにキャッシュを組み込んだら苦労した話

もう12月も中盤に差し掛かりましたね。

お世話になっております。
アイスタイルでマネージャーをやっておりますsakumayです。

本稿はAdvent Calendar 2018 13日の記事となります。

アイスタイル1年生であり、今年の7月から新米マネージャーとして
先日開催された弊社のECセールイベント『@cosme Beauty Day』に立ち向かった話をしたいと思います。

背景

僕らのチームが抱えるサービスは歴史の長い共通基盤API群の開発をしております。
歴史が長くこのAPIが落ちると、いろんなサービスが止まるリスクがあります。

『@cosme Beauty Day』は他のアドベントカレンダーでもご紹介がありましたが、
弊社の売り上げの10%を1日で稼ごうという目標のもとに立ち上げられたセールイベントです。
イベントの発表が7/20でしたので、だいたい4ヵ月ぐらいの開発期間でした。

本稿の内容について

他のサービスへの影響が大きいので絶対止めるわけにはいかず、
サーバー増強などのHW強化だけでは足りなかったので、
システムにキャッシュサーバーを組み込み、HW負荷を分散させることで、
弊社最大のECセールを乗り切りました。
その際に、レガシー化した既存システムに振り回された苦労話です。

システム構成について

現行システムは以下のように、各種フロントサービスからのリクエストをRailsのAPIで受け取って、
SQLServerの結果を返すシンプルな仕組み。
ただ扱うデータの特性からオンプレミスの環境で、DBはマスターDBを参照しており、
また移行目的でも止めることができません。

僕も含めて、チームの開発要員は新規参入メンバーで構成されていたので、この止められないというのが大きな課題になり、
AWS等のクラウドサービスへ移行するという計画も4ヵ月では難しい状況でした。

そこで、増加するであろうマスターDBの負荷を軽減するため、
キャッシュサーバーとしてCouchBaseを組み込み、参照系APIのレスポンスをキャッシュ化することで、サーバー負荷を下げつつ処理速度も改善することにしました。
CouchBaseを採用した理由は、弊社で直近の実績があって、組み込みが早かったからです。

設計の壁

現環境でどうやって性能検証していこうか等を考えたりしたところ、
開発メンバーからこんなアラートが、、、
開発者『rubyのバージョンが古すぎて、CouchBaseのクライアントがないです、、、』

実はこのAPI、rubyのバージョンが1.8系でして、見事にレガシー化しておりました。
嘆いていても始まらないし、そもそも残り期間で検証しながら進めることは難しいので、
中継APIを導入することにしました。

Javaで開発しているのは、現チームがJavaエンジニア主体で、動きが早かったからです。
いくつか検証を行い、問題なさそうだったので、本設計で開発を挑むことにしました。

開発の壁

開発を進めていきながら、キャッシュ化するデータなどを精査していくうちにまたアラートが、、

開発者『バッチ以外でAPIを通さないDB更新があります、、、』


つまるところ、サービスが成長していく中で自分たちの知らないDB更新があるので、
キャッシュ操作については自分たちのところをみてるだけじゃダメという話。
この辺りもレガシーなシステムの落とし穴だと思います。

解決策はとにかく調査!!!!

なにか神様のような発想で調べたりできないだろうかと、
いろいろ試行錯誤しましたが、結論調べる意外にないということで、
調査項目をまとめて、テクノロジー本部全体に問いかけ、
自分たちでも愚直にソースコード調査です。

泥臭い作業になりましたが、
調査結果もエビデンスを残しながら進めていくことで、
想定外の更新箇所をつぶすことができました。

個人的にストアドプロシージャの存在が一番心臓に悪かったです。

テストの壁

・・・そもそもテストコードとか・・・あるよね??

開発者『gemファイルがどうしても存在せず、動かないようです、、、』

このへんは本当に謎でした。
解決策は人海戦術!!

もともとある既存のRSpecがどうにも動かせなかったので、自分達の得意分野で、できることをやろうと
JUnitでAPIレベルでのテストコードを作成する部隊と、
モジュールレベルでテストする部隊に分けて実施。

時間がないと開発者は手動でテストをしたくなりますが、
特別なケースを除いて、テストコードは絶対に書いてもらいました。
この辺は徹底したおかげで、品質確保の観点もありますが、
繰り返し発生する問題を乗り越える際、リグレッションテストとして本当に役に立ってくれました。

リリースの壁

あちこち躓きながらも、性能テストも好調で、いよいよリリース!!

緊張しながらリリースをすると・・・システムアラート!!

APIのレスポンスが1%ぐらいの割合で遅延する事象
ログを見ても特に異常がなく、DBアクセスにも異常がない・・・

つまり、キャッシュサーバーへのアクセス時になんらかの理由で通信が遅くなっているということ

ここは開発者、マネージメント層含めて、本当に悩みました。

原因はなんと『DNS』
中継APIを増やしたことによって、DNSへのアクセスが増え、
DNSがアクセスをさばけなくなったためにパケロスが発生していました。

ここもまたレガシーシステムの悲しいところですが、
新しいサービス達が参照しているDNSとは異なるDNSを参照していたようで、
DNSキャッシュがうまく働いておらず、ネットワークレベルでの遅延が発生しておりました。

弊社の優秀な爆弾処理インフラ部隊が颯爽と駆け付け処理していってくれたおかげで、
無事リリースの壁を乗り越えることができました。

まとめ

赤裸々な話になってしまいましたが、イベント前にこれだけの苦労をしたおかげで、
イベント当日は、このAPIは一度も不具合をだすことなく、当日を過ごすことができました。
また、今までサービス影響が多いために、開かずの扉となっていたシステムが、
今回の対応によって、改善されていく足掛かりになりました。

振り返ってみれば、システム構成やプロジェクトの進め方に改善点はあるのですが、
いざこの期間にこの開発やりきったのは、エンジニアの努力にほかならず、
最後まで責任感をもってやってもらったことに本当に感謝しております。

レガシーなシステムだからといってそこで終わらず、
改善案を突き詰めていけるエンジニアこそ、次のステップに踏み出せるのではないでしょうか!

それではよいお年を!!

2018/02アイスタイル入社。 現在はマネージャーやってます。 声が大きい系エンジニア。初志貫徹がモットー