Redis 實例間遷移(如分庫、換機房、版本升級)需保持類型與結構完整。本文提供支援 String、List、Hash、ZSet 四大核心類型的 PHP 遷移腳本,採用 phpredis 擴展,含進度顯示與錯誤處理。
<?php
// 配置來源與目標:host:port/db
$from = '127.0.0.1:6200/6';
$to = '127.0.0.1:6200/8';
$fromRedis = redisInit($from);
$toRedis = redisInit($to);
$keys = $fromRedis->keys('*');
$total = count($keys);
$count = 0;
foreach ($keys as $key) {
if (++$count % 100 === 1) {
echo "$count/$total\n";
}
$type = $fromRedis->type($key);
switch ($type) {
case Redis::REDIS_STRING:
$val = $fromRedis->get($key);
$toRedis->set($key, $val);
break;
case Redis::REDIS_LIST:
$list = $fromRedis->lRange($key, 0, -1);
foreach ($list as $val) {
$toRedis->rPush($key, $val);
}
break;
case Redis::REDIS_HASH:
$hash = $fromRedis->hGetAll($key);
$toRedis->hMSet($key, $hash);
break;
case Redis::REDIS_ZSET:
$zset = $fromRedis->zRange($key, 0, -1, true); // withscores
foreach ($zset as $member => $score) {
$toRedis->zAdd($key, $score, $member);
}
break;
default:
echo "SKIP $key (unsupported type: $type)\n";
}
}
function redisInit(string $conf): Redis {
$redis = new Redis();
// 解析 host:port/db
if (!preg_match('/^([^:]+)(:(\d+))?\/(\d+)?$/', $conf, $m)) {
throw new InvalidArgumentException("Invalid redis config: $conf");
}
$host = $m[1];
$port = $m[3] ?? 6379;
$db = $m[4] ?? 0;
$redis->connect($host, $port);
$redis->select($db);
return $redis;
}
| Redis 類型 | 讀取命令 | 寫入命令 | 注意事項 |
|---|---|---|---|
| String | GET | SET | 含二進制安全 |
| List | LRANGE key 0 -1 | RPUSH (保持順序) | LPUSH 會反轉順序 |
| Hash | HGETALL | HMSET | 單次寫入原子性 |
| ZSet | ZRANGE key 0 -1 WITHSCORES | ZADD score member | 分數為 float,精度保持 |
| Set | SMEMBERS | SADD | 腳本未含,易擴展 |
KEYS *(阻塞),改用 SCAN 游標迭代:
$it = null;
while ($keys = $fromRedis->scan($it, '*', 1000)) {
foreach ($keys as $key) { ... }
}
$toRedis->pipeline();
foreach (...) { $toRedis->set(...); }
$toRedis->exec();
TTL key 獲取過期時間,寫入後 EXPIRE key ttl 恢復。TYPE、STRLEN、HLEN、ZCARD 對比。| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| PHP 腳本遷移 | 邏輯可控、支援類型轉換、易調試 | 單線程慢、大數據需優化 | 中小數據量、需數據清洗 |
| redis-cli --migrate | 原生、原子、支援 COPY/REPLACE | 需 3.0+、單 Key 操作 | 單 Key/小批量、版本兼容 |
| Redis Replication (Replicaof) | 全量+增量同步、零代碼 | 需相容版本、佔用從節點資源 | 整實例遷移、版本兼容 |
| RDB/AOF 文件導入 | 極快、離線操作 | 需停機、版本敏感 | 大數據量、可接受停機窗口 |
選對遷移策略,配合驗證與回滾預案,才能確保 Redis 數據零損失、零停機平滑流轉。