Closed9

MemcachedとRedisについてなんとなくの比較しかしてこなかったので改めて整理

tamaco489tamaco489

基本情報の比較

特徴 Memcached Redis
開発年 2003年 2009年
データ構造 単純なキーと値(文字列のみ) 多様なデータ構造(文字列、リスト、ハッシュ、セット、ソート済みセットなど)
永続化 なし(完全揮発性) オプションで永続化可能(スナップショットまたはAOF)
マルチスレッド対応 はい(v1.4以降) いいえ(シングルスレッド。ただしI/Oはマルチスレッド化可能)
レプリケーション なし(外部で対応) あり(マスター/レプリカ構成が可能)
クラスタリング 外部ツールで対応(例:mcrouter) Redis Clusterを公式サポート
トランザクション なし あり(MULTI/EXEC)
Luaスクリプト なし あり(組み込みでサポート)
pub/sub機能 なし あり
tamaco489tamaco489

パフォーマンス比較

項目 Memcached Redis
スループット 非常に高速(シンプルな処理向き) 高速(複雑な処理も可能)
レイテンシ 低い 低い(ただし機能によって増減)
スケーラビリティ 良い(キーの分散による) 良い(Redis Clusterなどで対応)
tamaco489tamaco489

利用ケースにおける選択の目安

要件 推奨
単純なキャッシュ(キー/値) Memcachedが適している
高機能なデータ構造を使いたい Redisが適している
永続化が必要 Redis
高度なクエリ、ランキング、統計など Redis
メモリ効率重視(非常に単純な用途) Memcached
tamaco489tamaco489

ざっと要点まとめると、
基本Redisのほうができることが多くて、特にストレージへの永続化をしないといけないとか、レプリケーション目的でクラスタ組まないといけないとかならほぼ確Redis使うのが良い。
一方で、Redisはマルチスレッド対応していない(シングルスレッドで動く)ので、単純なGET/SET以外のコマンドを実行するのに、1クライアントの処理で長時間全体の処理がブロックされてしまう可能性があるので、単純なKVSではない使い方をする場合、発行するコマンドによってはパフォーマンスを出しづらい場面もあるため、この場合はMemcachedに軍配が上がる。

tamaco489tamaco489

memo:シングルスレッドで動作するとは?

クライアントから受けたリクエストの処理を1つのスレッドで処理するということ。

🔍 具体的には

  • 1つのクライアントのコマンドを順番に処理する。※つまり並列実行しない
  • そのため、CPUコアが複数あってもRedisは基本的には1コアしか使わない。
  • 例:1000個のクライアントから同時アクセスされても、内部では1つづつ順番に処理される。

※Redisで並列処理させないといけないとかになったら、複数インスタンスを立てる or クラスタ構成にするのが一般的らしいがこのあたりは調べきれてない

tamaco489tamaco489
  • 揮発性メモリのMemcachedの場合、再起動した際にキャッシュが全て消失してしまうため、このタイミングで一斉にDBや外部API等のoriginサーバへのアクセスが集中してしまうことも視野に入れる必要がある。
  • そもそもキャッシュしたいデータとは複雑なデータ(もしくは整形しにくいデータ)であることが前提と考えれるため、負荷のかかりやすいslow-queryになるものが多い。
tamaco489tamaco489

Thredering herd problem 問題について

https://techblog.lycorp.co.jp/ja/20250203a

以下、キャッシュを利用する際の大まかな通信の流れ

  1. クライアントによるリクエスト
  2. バックエンドでリクエストを解析し、キャッシュサーバに問い合わせ
  3. キャッシュサーバにデータが存在していないため、DBに問い合わせ
  4. DBから取得したデータをキャッシュサーバに設定
  5. クライアントにレスポンス返却

だいたい上記のような構成になるが、
前述したとおり、キャッシュに乗せたいデータはつまりは負荷のかかりやすいデータであることが多いため、とくに初回のリクエストなどで、APIエンドポイントは異なれど、それぞれのAPIのロジック内で扱うデータをキャッシュ上のデータを参照するような構成にしている場合は、キャッシュサーバ再起動後の初回リクエスト時に↑の3の処理が多数走ってしまい、結果高負荷な状態に陥ってしまう。

キャッシュサーバを再起動するって運用しててあんまり遭遇したことがないけど、もし定期的に再起動かけないといけないってなった場合はMemcached使いどころむずいなといったところで、そこまで大規模な環境でない場合はRedis使っておくのが無難なのではないかと。

tamaco489tamaco489

キャッシュサーバを再起動するって運用しててあんまり遭遇したことがないけど、もし定期的に再起動かけないといけないってなった場合はMemcached使いどころむずいなといったところで、そこまで大規模な環境でない場合はRedis使っておくのが無難なのではないかと。

回避策は結構あるなと思い、例えば再起動かける前に別のデータストアにその情報保持しておいて、再起動後にbatch処理か何かで再度設定してあげれば良いねと。と言いつつ、この運用すら冗長だなとか、のちに考えること多そうだなという思いが強い場合は結局のところRedisが無難という結論は変わらないかも。

このスクラップは4ヶ月前にクローズされました