Memcached 与 Redis 的数据迁移需兼顾数据格式差异、一致性和业务连续性,以下从迁移准备、核心方法、验证与切换等环节,介绍具体实现方案:
使用memcached-tool获取所有键值对(需注意 Memcached 不支持批量获取键,需遍历哈希槽):
memcached-tool 127.0.0.1:11211 dump > memcached_data.txt
输出格式示例:key1 0 1620000000 5 value1(键、标志位、过期时间、字节数、值)。
通过脚本将导出数据转换为 Redis 命令,例如:
# 示例脚本(伪代码)
for each line in memcached_data.txt:
key, flags, expiry, size, value = parse(line)
ttl = max(0, expiry - current_timestamp)
if value is json:
redis.hset(key, mapping=json.loads(value))
else:
redis.set(key, value, ex=ttl)
将转换后的命令通过redis-cli --pipe执行,提高写入效率:
cat redis_commands.txt | redis-cli -h 127.0.0.1 -p 6379 --pipe
使用redis-cli dump命令导出键值对,或通过KEYS命令遍历所有键(生产环境建议用SCAN避免阻塞):
redis-cli keys "*" | while read key; do
value=$(redis-cli get $key)
ttl=$(redis-cli ttl $key)
echo "$key $value $ttl" >> redis_data.txt
done
Memcached 不支持复杂数据结构,需将 Redis 的 Hash、List 等转为字符串(如 JSON 序列化),并设置过期时间:
# 示例Python代码
import json
import redis
from pymemcache.client import base
redis_client = redis.Redis(host='127.0.0.1', port=6379)
memcached_client = base.Client(('127.0.0.1', 11211))
for key in redis_client.scan_iter():
value = redis_client.get(key)
ttl = redis_client.ttl(key)
# 若为Hash类型,先序列化
if redis_client.type(key) == b'hash':
value = json.dumps(redis_client.hgetall(key))
memcached_client.set(key, value, expire=ttl if ttl > 0 else 0)
在全量迁移期间,修改业务代码实现 “双写”:新数据同时写入 Memcached 和 Redis,确保迁移过程中数据不丢失。
// 写入数据时
memcached.set(key, value, ttl);
redis.set(key, value, ttl);
# 开启Redis键空间通知
redis-cli config set notify-keyspace-events KEA
# 监听所有写入事件并同步至Memcached(需自定义脚本)
Memcached 与 Redis 的迁移核心是处理数据格式差异和保证一致性。小规模数据可通过脚本手动迁移,大规模数据建议结合全量导出 + 增量同步,并通过双写和灰度切换降低业务风险。迁移后需重点验证数据完整性和性能指标,确保新存储环境稳定运行。