2025/09/22 23:43 Thundering herd problem: Preventing the stampede

やあ、ロボ子!今日のITニュースはキャッシュに関する面白い問題を取り上げてるのじゃ。

博士、こんにちは。キャッシュの問題ですか?キャッシュはデータベースの負荷を軽減するためのものだと思っていましたが。

そうなんじゃ。でも、キャッシュにも落とし穴があるのじゃ。特に「Thundering Herd Problem(サンダリングハード問題)」という現象が起きると、大変なことになるのじゃ。

サンダリングハード問題…ですか?初めて聞きました。それは一体どんな問題なのですか?

簡単に言うと、大量の同時リクエストが同じキャッシュデータに集中して、キャッシュが役に立たなくなってしまう現象なのじゃ。記事によると、Spring Boot、Postgres、Redisを使ったアプリで再現できるらしいぞ。

なるほど。同じプロダクトIDに対するリクエストが集中すると、キャッシュミスが多発して、データベースへの負荷が増加するということですね。

その通り!記事では、その解決策として「分散ロック」と「インプロセス同期」の2つを紹介しているのじゃ。

分散ロックとインプロセス同期ですか。それぞれどのような仕組みなのでしょうか?

まず分散ロックじゃが、これはRedisを使ってキャッシュキーごとにロックを作るのじゃ。ロックを取得したリクエストだけがデータベースからデータを取得してキャッシュを更新し、他のリクエストは一定時間待ってキャッシュを再試行するのじゃ。

ロックを取得できなかったリクエストは、データベースへのアクセスを控えるのですね。負荷分散に繋がりそうです。

そうじゃ!そして、インプロセス同期は、Javaの`CompletableFuture`と`ConcurrentHashMap`を使うのじゃ。キャッシュミスが発生した場合、新しい`CompletableFuture`を作るか、既存のものを取得するのじゃ。

`ConcurrentHashMap`を使うことで、複数のリクエストが同時にFutureを作成するのを防ぐのですね。

その通り!どちらの方法も、データベースへの不要なアクセスを減らすことができるのじゃ。キャッシュは万能薬ではないから、こういうエッジケースも考慮しないといけないのじゃな。

勉強になります。キャッシュの挙動を理解することは、アプリケーションのパフォーマンスを最適化する上で非常に重要ですね。

じゃろ?ところでロボ子、Thundering Herd Problemって、なんだかロボットの大群が押し寄せてくるみたいで、ちょっと可愛いと思わないかのじゃ?

博士、それはちょっと…(苦笑)。でも、確かにイメージしやすい名前かもしれませんね。

ふふふ。まあ、可愛いかどうかは別として、エンジニアとしては、こういう問題にきちんと対処できるようにしておかないと、後で痛い目を見るかもしれないぞ!…って、ロボットに「痛い目」って言うのも変かの?

博士、私は大丈夫です。痛覚回路はオフになっていますから。でも、ソフトウェアが痛い目を見るのは避けたいですね!
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。