Memcached:Redisではなく、この「ベテラン」を選ぶべきタイミングとは?

Database tutorial - IT technology blog
Database tutorial - IT technology blog

5分でできるMemcached의インストール

Memcachedのインストールは、想像以上に簡単です。面倒な設定は不要で、現在のサーバーOSの定番であるUbuntu/Debian上ですぐに稼働させることができます。

1. Ubuntuへのインストール

sudo apt update
sudo apt install memcached libmemcached-tools -y

2. ステータスの確認

インストール完了後、サービスは自動的に起動します。以下のコマンドを使用して、正しく動作しているか確認しましょう:

sudo systemctl status memcached

3. Telnetによるクイックテスト

すぐにコードを書く代わりに、Telnetを介してMemcachedと直接「対話」することができます。これはデバッグ時に非常に便利です。

telnet localhost 11211

# 構文: set <key> <flags> <exptime> <bytes>
set session_id 0 60 5
abc12

# データの取得: get <key>
get session_id

# 実行結果:
# VALUE session_id 0 5
# abc12
# END

この例では、session_idabc12という値を60秒間保存しています。すべての処理は1ミリ秒未満で完了します。

Redisが強力であるにもかかわらず、なぜMemcachedが使われ続けるのか?

多くのエンジニアが「Redisの方が多機能なのに、なぜMemcachedを使う必要があるのか?」という疑問を抱きます。その答えは「特化」にあります。Redisがあらゆる機能を網羅しようとする一方で、Memcachedはただ一つのこと、つまり「超高速なデータキャッシュ」だけに集中しています。

Memcachedは分散型のインメモリKey-Valueストアです。複雑なロジックは持たず、文字列(Strings)とシリアライズされたオブジェクトのみを扱います。このシンプルさこそが、極めて高いスループットを実現する鍵となっています。

実践的なメリット:

  • マルチスレッド・アーキテクチャ (Multi-threaded): これが秘密兵器です。Memcachedは、32コアや64コアといったマルチコアCPUの性能を最大限に引き出します。Redisは(基本的に)シングルスレッドでコマンドを処理するため、純粋なスループットのテストではMemcachedが上回ることがよくあります。
  • Slab Allocationによるメモリ割り当て: このメカニズムにより、メモリの断片化による速度低下を招くことなく、サーバーを長期間稼働させることができます。
  • リソースの節約: セッションの保存やSQLクエリ結果のキャッシュだけであれば、MemcachedはRedisに比べてメモリとCPUの消費量が大幅に少なくて済みます。

実践比較:Memcached vs Redis

以下は、実際のプロジェクト導入経験に基づいた比較表です:

特徴 Memcached Redis
データ型 シンプルな文字列のみ リスト、ハッシュ、セット、位置情報など
処理方式 マルチスレッド(マルチコアを効率的に活用) シングルスレッド(最新版ではI/Oスレッドあり)
データの永続性 なし(リセット時に消失) あり(ディスクへの書き込み)
Key/Valueの制限 Valueは最大1MB Valueは最大512MB

選定の目安: 膨大なトラフィック(例:毎秒10万リクエスト)が発生するシステムの純粋なキャッシュ層が必要な場合は、Memcachedを選択してください。複雑なデータ構造が必要な場合や、サーバー再起動時にキャッシュを失いたくない場合は、Redisを選択してください。

Slab Allocationメカニズム:安定性の秘密

メモリの断片化(Memory Fragmentation)は、インメモリシステムの天敵です。無計画にメモリを割り当てると、実際には空き容量があっても、小さな空き領域が散在しているためにメモリ不足を報告することがあります。

Memcachedは、RAMを「Slab Class」という単位に分割することでこの問題を解決しています。例えば、Class 1は64バイトの枠、Class 2は128バイトの枠、といった具合です。100バイトのデータを保存する場合、128バイトの枠に格納されます。数バイトの無駄を許容することで、ガベージコレクション(Garbage Collection)の手間を省き、レイテンシを極めて低いレベルで安定させています。

Pythonでの利用例(実践的なサンプル)

以下は、データベースの負荷を軽減するために私がよく使用する方法です(3秒かかるクエリを想定):

import time
from pymemcache.client.base import Client

# Memcachedへの接続
client = Client(('localhost', 11211))

def get_user_profile(user_id):
    # 最初にキャッシュからの取得を試みる
    cache_key = f'user:{user_id}'
    data = client.get(cache_key)
    
    if data:
        return data.decode('utf-8')

    # キャッシュミス(Miss)の場合、DBクエリをシミュレート
    time.sleep(3) 
    result = f"ユーザー {user_id} のプロフィール"

    # 10分間キャッシュに保存
    client.set(cache_key, result, expire=600)
    return result

# 1回目:3秒待機
print(get_user_profile(99))
# 2回目:即座に応答
print(get_user_profile(99))

「血肉となる」セキュリティ上の注意点

Memcachedのシンプルさに油断してはいけません。本番環境に導入する際は、以下の2点を必ず守ってください:

1. ポート11211を即座にブロックする

Memcachedはデフォルトでパスワードを要求しません。2018年、GitHubは公開状態のMemcachedサーバーを悪用した攻撃者により、史上最大規模の1.35 TbpsのDDoS攻撃を受けました。必ず -l 127.0.0.1 を設定するか、アプリケーションサーバーのIPのみを許可するようにファイアウォールを設定してください。

2. メモリ制限の緩和

デフォルトではMemcachedは64MBのRAMしか使用しません。これは現代のアプリケーションにとっては少なすぎます。リソースに合わせて増やしましょう:

# /etc/memcached.conf 内で修正
-m 1024  # 1GB RAMに増量

Memcachedは派手さはないかもしれませんが、勤勉で非常に信頼できる「職人」のような存在です。シンプルなタスクで最大限の速度を求めるなら、迷わずMemcachedを選んでください。

Share: