Memcached
GitHub概要
linsomniac/python-memcached
A python memcached client library.
スター467
ウォッチ21
フォーク201
作成日:2013年3月27日
言語:Python
ライセンス:-
トピックス
なし
スター履歴
データ取得日時: 2025/10/22 08:07
ライブラリ
Memcached
概要
Memcachedは高速分散メモリオブジェクトキャッシュシステムです。シンプルなkey-valueストレージによる軽量キャッシュ実装で、マルチスレッド設計により高スループットを実現し、動的Webアプリケーションのデータベース負荷軽減に特化しています。2025年において高スループット文字列キャッシュの分野でRedisと双璧をなす存在として、シンプルさとパフォーマンスを重視する環境、特に大規模Webサービスで継続的に選択されています。
詳細
Memcached 1.6系列は2025年現在も活発に開発されており、TLS暗号化サポート、プロキシ機能、ホットキー検出、slab自動再配分機能を搭載。マルチスレッド設計により複数CPUコアを効率的に活用し、特に大きなデータセットの保存・管理でRedisを上回る性能を発揮。外部依存なしの純粋なキャッシュソリューションとして、最大限のシンプルさと予測可能性を提供します。一時的なデータ保存に特化し、永続化機能は持たないため軽量でメモリ効率的な運用が可能。
主な特徴
- マルチスレッド設計: 複数CPUコアの効率的活用による高いスループット
- シンプルなプロトコル: テキストベースの簡潔なコマンド体系
- 水平スケーリング: クライアント側ハッシュによる分散配置
- メモリ効率: slabアロケーターによる効率的なメモリ管理
- 高い安定性: 10年以上の本番運用実績
- 軽量実装: 最小限の機能セットと低リソース消費
メリット・デメリット
メリット
- Redisに匹敵するサブミリ秒応答時間の高性能
- マルチスレッドによる大規模データセットでの優位性
- 設定とメンテナンスが極めて簡単
- メモリ使用量の予測が容易(key-valueのみ)
- 軽量で安定した運用が可能
- 豊富なクライアントライブラリとフレームワーク統合
デメリット
- データ永続化機能なし(サーバー再起動でデータ消失)
- 複雑なデータ構造サポートなし(文字列のみ)
- クラスタリング・レプリケーション機能の欠如
- 高可用性機能が限定的(フェイルオーバー不可)
- パブリッシュ/サブスクライブ機能なし
- 原子的操作の制限(インクリメント・デクリメント程度)
参考ページ
書き方の例
インストールとセットアップ
# Ubuntu/Debian でのインストール
sudo apt update
sudo apt install memcached
# CentOS/RHEL でのインストール
sudo yum install memcached
# Docker での起動
docker run --name memcached-server -p 11211:11211 -d memcached:1.6
# サービス起動と確認
sudo systemctl start memcached
sudo systemctl enable memcached
sudo systemctl status memcached
# 設定ファイル確認
cat /etc/memcached.conf
基本的なキャッシュ操作
# telnet で接続テスト
telnet localhost 11211
# 基本的な SET/GET 操作
set user_name 0 3600 4
john
STORED
get user_name
VALUE user_name 0 4
john
END
# 数値のインクリメント/デクリメント
set counter 0 0 1
0
STORED
incr counter 5
5
decr counter 2
3
# 複数キー取得
set key1 0 3600 6
value1
STORED
set key2 0 3600 6
value2
STORED
get key1 key2
VALUE key1 0 6
value1
VALUE key2 0 6
value2
END
クライアントライブラリの使用(Python)
import memcache
# サーバー接続
mc = memcache.Client(['127.0.0.1:11211'], debug=0)
# 基本的なキャッシュ操作
mc.set("user:1", "John Doe", time=3600)
user = mc.get("user:1")
print(user) # "John Doe"
# 複数キー操作
mc.set_multi({
"user:1": "John Doe",
"user:2": "Jane Smith",
"user:3": "Bob Johnson"
}, time=3600)
users = mc.get_multi(["user:1", "user:2", "user:3"])
print(users) # {'user:1': 'John Doe', 'user:2': 'Jane Smith', 'user:3': 'Bob Johnson'}
# 条件付き更新(CAS)
mc.set("inventory_count", 100)
gets_result = mc.gets("inventory_count")
if gets_result:
# CAS (Compare And Swap)
success = mc.cas("inventory_count", 95)
print(f"CAS Success: {success}")
# TTL 確認と削除
mc.set("temp_data", "temporary", time=60)
mc.delete("temp_data")
# 統計情報取得
stats = mc.get_stats()
print(stats)
Node.js でのキャッシュ実装
const memjs = require('memjs');
// サーバー接続
const client = memjs.Client.create('localhost:11211');
// Promise ベースの操作
async function cacheOperations() {
try {
// データ設定
await client.set('session:abc123', 'user_data', {expires: 3600});
// データ取得
const result = await client.get('session:abc123');
if (result.value) {
console.log('Cached data:', result.value.toString());
}
// 複数操作
await Promise.all([
client.set('key1', 'value1', {expires: 1800}),
client.set('key2', 'value2', {expires: 1800}),
client.set('key3', 'value3', {expires: 1800})
]);
// インクリメント
await client.set('view_count', '100');
const newCount = await client.increment('view_count', 1);
console.log('New view count:', newCount.value?.toString());
// 削除
await client.delete('session:abc123');
} catch (error) {
console.error('Cache error:', error);
} finally {
client.close();
}
}
cacheOperations();
分散Memcachedクラスター
import memcache
import hashlib
# 複数サーバーでの分散設定
servers = [
'192.168.1.10:11211',
'192.168.1.11:11211',
'192.168.1.12:11211'
]
mc = memcache.Client(servers, debug=0)
# 一貫性ハッシュによる分散
def get_server_for_key(key, servers):
hash_value = int(hashlib.md5(key.encode()).hexdigest(), 16)
return servers[hash_value % len(servers)]
# ラウンドロビンによる負荷分散
class DistributedMemcache:
def __init__(self, servers):
self.servers = servers
self.clients = {
server: memcache.Client([server])
for server in servers
}
def _get_client(self, key):
server = get_server_for_key(key, self.servers)
return self.clients[server]
def set(self, key, value, time=0):
client = self._get_client(key)
return client.set(key, value, time)
def get(self, key):
client = self._get_client(key)
return client.get(key)
def delete(self, key):
client = self._get_client(key)
return client.delete(key)
# 使用例
distributed_cache = DistributedMemcache(servers)
distributed_cache.set("user:1000", "John Doe", time=3600)
user_data = distributed_cache.get("user:1000")
セッション管理の実装
<?php
// PHP でのセッション管理
class MemcachedSessionHandler {
private $memcached;
private $ttl = 3600; // 1時間
public function __construct($servers) {
$this->memcached = new Memcached();
$this->memcached->addServers($servers);
}
public function read($session_id) {
$data = $this->memcached->get("session:$session_id");
return $data === false ? '' : $data;
}
public function write($session_id, $data) {
return $this->memcached->set("session:$session_id", $data, $this->ttl);
}
public function destroy($session_id) {
return $this->memcached->delete("session:$session_id");
}
public function gc($maxlifetime) {
// Memcached は TTL で自動的に期限切れデータを削除
return true;
}
}
// セッションハンドラー登録
$servers = [
['localhost', 11211],
['192.168.1.20', 11211]
];
$handler = new MemcachedSessionHandler($servers);
session_set_save_handler($handler, true);
// セッション開始
session_start();
$_SESSION['user_id'] = 1234;
$_SESSION['username'] = 'john_doe';
?>
監視とパフォーマンス最適化
# 統計情報の確認
echo "stats" | nc localhost 11211
# 重要な統計項目
# curr_connections: 現在の接続数
# get_hits: ヒット数
# get_misses: ミス数
# hit_ratio: ヒット率 = hits/(hits+misses)
# slab 情報の確認(メモリ使用状況)
echo "stats slabs" | nc localhost 11211
# アイテム情報の確認
echo "stats items" | nc localhost 11211
# パフォーマンス監視スクリプト
#!/bin/bash
while true; do
echo "=== Memcached Stats $(date) ==="
echo "stats" | nc localhost 11211 | grep -E "(get_hits|get_misses|curr_connections|bytes)"
echo ""
sleep 10
done