首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 實現 Redis 實例間數據遷移:支援 String/List/Hash/ZSet 全類型同步腳本

     編輯:PHP 相關知識

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 類型讀取命令寫入命令注意事項
StringGETSET含二進制安全
ListLRANGE key 0 -1RPUSH (保持順序)LPUSH 會反轉順序
HashHGETALLHMSET單次寫入原子性
ZSetZRANGE key 0 -1 WITHSCORESZADD score member分數為 float,精度保持
SetSMEMBERSSADD腳本未含,易擴展

生產環境增強清單

  • 掃描替代 KEYS:生產禁用 KEYS *(阻塞),改用 SCAN 游標迭代:
    $it = null;
    while ($keys = $fromRedis->scan($it, '*', 1000)) {
        foreach ($keys as $key) { ... }
    }
    
  • Pipeline 批量寫入:目標端啟用 Pipeline 減少 RTT:
    $toRedis->pipeline();
    foreach (...) { $toRedis->set(...); }
    $toRedis->exec();
    
  • 大 Key 分批:List/Hash/ZSet 元素超萬時,分批讀寫,避免記憶體飆升。
  • TTL 保持:遷移前 TTL key 獲取過期時間,寫入後 EXPIRE key ttl 恢復。
  • 校驗一致性:遷移後抽樣 TYPE、STRLEN、HLEN、ZCARD 對比。
  • 斷點續傳:記錄已遷移 Key 至文件/Redis,中斷後跳過。
  • 雙寫過渡期:遷移期間應用雙寫新舊實例,驗證無誤後切換讀流量。

替代方案對比

方案優點缺點適用場景
PHP 腳本遷移邏輯可控、支援類型轉換、易調試單線程慢、大數據需優化中小數據量、需數據清洗
redis-cli --migrate原生、原子、支援 COPY/REPLACE需 3.0+、單 Key 操作單 Key/小批量、版本兼容
Redis Replication (Replicaof)全量+增量同步、零代碼需相容版本、佔用從節點資源整實例遷移、版本兼容
RDB/AOF 文件導入極快、離線操作需停機、版本敏感大數據量、可接受停機窗口

選對遷移策略,配合驗證與回滾預案,才能確保 Redis 數據零損失、零停機平滑流轉。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved