1. 程式人生 > 實用技巧 >Redis&Pika單機及主從資料遷移方案

Redis&Pika單機及主從資料遷移方案

前言:如果同步過程中發現數據量不一致,先不要斷開主從,分析一下每日進redis的資料量是否很大,以及鍵的過期時間

redis會在後臺,每秒10次的執行如下操作:
隨機選取100個key校驗是否過期,如果有25個以上的key過期了,立刻額外隨機選取下100個key。也就是說,如果過期的key不多,redis最多每秒回收200條左右

一、redis到redis資料遷移方案

1.建立 “主從” 方式遷移(注:所有的操作都在新redis中執行,為了避免主從關係建立反,請儘量不要在原redis中進行操作)

前提條件:

    原 redis  ip1  port1   masterauth=old-pwd
    新 redis  ip2  port2   masterauth=new-pwd

主從關係建立時一般遇到的問題就是密碼不同步的問題,在建立主從同步前需要將密碼設定一致

1.可在新redis中執行: config set masterauth "old-pwd"
2.新redis中執行:slaveof ip1 port1(與原redis建立主從關係)
                 info replication (檢視 master_link_status 狀態是否為 up ,確定主從關係已經建立 )
3.新redis 原redis中執行:dbsize(確定資料同步完成)
4.新redis中執行: slaveof no one(解除主從關係)  
                 info replication (確定新節點已經成為主節點)
                 config set masterauth "pwd" (將密碼設定回來)

2.redis-port方式遷移資料

第一步:工具準備

redis-port 此工具已經編譯完成 連結:https://pan.baidu.com/s/1QragD66OA0VawEEiu85MEQ    提取碼:xeoj
若要自己編譯請訪問官網下載編譯https://github.com/CodisLabs/redis-port

第二步:redis-port引數說明

Options:
        -n N, --ncpu=N                    Set runtime.GOMAXPROCS to N.
        -p M, --parallel=M                Set the number of parallel routines to M.
        -i INPUT, --input=INPUT           Set input file, default is stdin ('/dev/stdin').
        -o OUTPUT, --output=OUTPUT        Set output file, default is stdout ('/dev/stdout').
        -f MASTER, --from=MASTER          Set host:port of master redis.
        -t TARGET, --target=TARGET        Set host:port of slave redis.
        -P PASSWORD, --password=PASSWORD  Set redis auth password.
        -A AUTH, --auth=AUTH              Set auth password for target.
        --fromencodepassword=PASSWORD     Set encode password for from.
        --targetncodepassword=PASSWORD    Set encode password for target.
        --fromauthtype=FROMAUTHTYPE           Set auth type for from.
        --targetauthtype=TARGETAUTHTYPE   Set auth type for target.
        --fromversion=FROMVERSION         Set From-RDB version no, default to 6 (6 for Redis Version <= 3.0.7, 7 for >=3.2.0)
        --toversion=TOVERSION             Set To-RDB version no, default to 6 (6 for Redis Version <= 3.0.7, 7 for >=3.2.0)
        --faketime=FAKETIME               Set current system time to adjust key's expire time.
        --sockfile=FILE                   Use FILE to as socket buffer, default is disabled.
        --filesize=SIZE                   Set FILE size, default value is 1gb.
        --pidfile=REDISPORT.PID           Pid file path.
        --logfile=REDISPORT.LOG           Log file path.
        -e, --extra                       Set ture to send/receive following redis commands, default is false.
        --rewrite                         Force rewrite when destination restore has the key
        --filterdb=DB                     Filter db = DB, default is *.
        --targetdb=DB                     Target db = DB, default is *.
        --filterkey="a|b|c"               Filter key with prefix string, multiple string is separated by '|'
        --httpport=HTTPPORT               Http port.
        --bigkeysize=BIGKEYSIZE           Big Key Size.
        --psync                           Use PSYNC command.
        --replacehashtag                  Replace key hash tag
        --filterslots="1|2|3"             Filter slots = slots, default is *.
        --pacluster                       set pacluster = true, default is false

可執行命令:
redis-port decode   [--ncpu=N]  [--parallel=M]  [--input=INPUT]  [--output=OUTPUT] [--fromversion=RDBVERSION] [--toversion=RDBVERSION] [--pidfile=REDISPORT.PID] [--logfile=REDISPORT.LOG] [--httpport=HTTPPORT] [--bigkeysize=BIGKEYSIZE]
redis-port restore  [--ncpu=N]  [--parallel=M]  [--input=INPUT]   --target=TARGET   [--auth=AUTH] [--extra] [--faketime=FAKETIME]  [--filterdb=DB] [--filterkey="str1|str2|str3"] [--fromversion=RDBVERSION] [--toversion=RDBVERSION] [--rewrite] [--pidfile=.PID] [--logfile=REDISPORT.LOG] [--httpport=HTTPPORT] [--bigkeysize=BIGKEYSIZE] [--targetauthtype=TARGETAUTHTYPE] [--targetencodepassword=PASSWORD] [--targetdb=DB]
redis-port dump     [--ncpu=N]  [--parallel=M]   --from=MASTER   [--password=PASSWORD]  [--output=OUTPUT]  [--extra] [--fromversion=RDBVERSION] [--toversion=RDBVERSION] [--pidfile=.PID] [--logfile=REDISPORT.LOG]  [--httpport=HTTPPORT] [--bigkeysize=BIGKEYSIZE]
redis-port sync     [--ncpu=N]  [--parallel=M]   --from=MASTER  [--fromencodepassword=PASSWORD] [--fromauthtype=FROMAUTHTYPE] [--targetauthtype=TARGETAUTHTYPE] [--password=PASSWORD]   --target=TARGET [--targetencodepassword=PASSWORD]  [--auth=AUTH]  [--sockfile=FILE [--filesize=SIZE]] [--filterdb=DB]  [--targetdb=DB] [--filterkey="str1|str2|str3"] [--psync] [--fromversion=RDBVERSION] [--toversion=RDBVERSION] [--rewrite]  [--pidfile=.PID] [--logfile=REDISPORT.LOG] [--httpport=HTTPPORT] [--bigkeysize=BIGKEYSIZE] [--replacehashtag] [--filterslots="1|2|3"] [--pacluster]

第三步:具體使用

前提條件:
    原redis1:ip1  port1  pwd1
    新redis2:ip2  port2  pwd2

引數說明:

Options:
        -n N, --ncpu=N                    Set runtime.GOMAXPROCS to N.
        -p M, --parallel=M                Set the number of parallel routines to M.
        -i INPUT, --input=INPUT           Set input file, default is stdin ('/dev/stdin').
        -o OUTPUT, --output=OUTPUT        Set output file, default is stdout ('/dev/stdout').
        -f MASTER, --from=MASTER          Set host:port of master redis.
        -t TARGET, --target=TARGET        Set host:port of slave redis.
        -P PASSWORD, --password=PASSWORD  Set redis auth password.
        -A AUTH, --auth=AUTH              Set auth password for target.
        --fromencodepassword=PASSWORD     Set encode password for from.
        --targetncodepassword=PASSWORD    Set encode password for target.
        --fromauthtype=FROMAUTHTYPE           Set auth type for from.
        --targetauthtype=TARGETAUTHTYPE   Set auth type for target.
        --fromversion=FROMVERSION         Set From-RDB version no, default to 6 (6 for Redis Version <= 3.0.7, 7 for >=3.2.0)
        --toversion=TOVERSION             Set To-RDB version no, default to 6 (6 for Redis Version <= 3.0.7, 7 for >=3.2.0)
        --faketime=FAKETIME               Set current system time to adjust key's expire time.
        --sockfile=FILE                   Use FILE to as socket buffer, default is disabled.
        --filesize=SIZE                   Set FILE size, default value is 1gb.
        --pidfile=REDISPORT.PID           Pid file path.
        --logfile=REDISPORT.LOG           Log file path.
        -e, --extra                       Set ture to send/receive following redis commands, default is false.
        --rewrite                         Force rewrite when destination restore has the key
        --filterdb=DB                     Filter db = DB, default is *.
        --targetdb=DB                     Target db = DB, default is *.
        --filterkey="a|b|c"               Filter key with prefix string, multiple string is separated by '|'
        --httpport=HTTPPORT               Http port.
        --bigkeysize=BIGKEYSIZE           Big Key Size.
        --psync                           Use PSYNC command.
        --replacehashtag                  Replace key hash tag
        --filterslots="1|2|3"             Filter slots = slots, default is *.
        --pacluster                       set pacluster = true, default is false

具體操作:

1.連線redis1客戶端  redis-cli -a pwd1 -h ip1 -p port1  執行bgsave
2.將redis-port上傳到原redis1的伺服器db目錄下找到對應的dump.rdb
3.授權 chmod +x redis-port 
4.有兩種方式,
    第一種傳輸dump.rdb檔案,
      ./redis-port restore -i dump.rdb -t ip2:port2 -A 123456 -n 4
    第二種倆個redis之間傳輸
      ./redis-port sync -f 10.19.185.17:7006 -t 10.19.xx.17:8522 --fromversion=9  --toversion=9 -A 123456 -P 123456 -n 4 -p 32  --sockfile=test.tmp --filesize=32GB   (若是redis5.0以上版本號配置--fromversion=9  --toversion=9)
5.執行完成檢視兩邊資料量是否一致
    redis-cli -a pwd1 -h ip1 -p port1 dbsize
    redis-cli -a pwd2 -h ip2 -p port2 dbsize

二、redis遷移pika方案(aof_to_pika工具遷移)

注:遷移資料前請確認是否有重複的key,以及是否能接受覆蓋掉的key的值:

1.redis 0-15個庫,如果都有資料,那麼在執行save時,不同庫中的相同的key會被覆蓋,例如 db1中的key會覆蓋掉db0中相同0的key的資料
2.若pika中有資料,那麼redis中的key會覆蓋掉pika中的相同的key的資料

1.工具準備aof_to_pika.zip

連結:https://pan.baidu.com/s/1kKkP4kxCBdCPKogMWElKrQ  提取碼:b0s6

2.具體操作步驟

1.停止應用寫入redis資料,並進入到redis中執行dbsize查詢資料量
2.原redis是否做了aof持久化,若沒做進入redis執行config set appendonly yes進行持久化,同時拷貝 appendonly.aof
3.需要機器的gcc版本較高(實踐證明gcc 4.8.x 是可以的)
4.安裝aof_to_pika工具
   在準備好的機器上建立pika/bin/ 目錄下執行
        unzip aof_to_pika.zip    //解壓工具包
        cd aof_to_pika && make   //進入到工具包並執行編譯
5.將appendonly.aof檔案上傳到  pika/bin/output/bin/目錄下
6.在pika/bin/output/bin/目錄下執行  “./aof_to_pika -i ./appendonly.aof -h 【pika-ip】 -p 【pika-port】 -a 【pwd】-v ” 進行遷移
7.遷移完成後通過執行 “redis-cli -a 【pwd】 -h 【pika-ip】 -p 【pika-port】 info keyspace 1 ” 檢視遷移後的資料量(主從都查詢一下,確保主從資料同步)

三、pika遷移pika資料遷移方案

建立主從方式遷移資料

原pika ip1 port1 pwd1
新pika叢集 (主) ip2 port2  pwd2
          (從) ip3 port3  pwd3

1.進入(從)ip3 port3 ,將主從斷開
       redis-cli -a 【pwd3】 -h 【ip3】 -p 【port3】slaveof no one
2.進入(主) ip2 port2,與原pika建立主從關係
      redis-cli -a 【pwd2】 -h 【ip2】 -p 【port2】slaveof 【ip1】【port1】
3.檢視兩邊資料是否一致
      redis-cli -a 【pwd1】 -h 【ip1】 -p 【port1】info keyspace 1
      redis-cli -a 【pwd2】 -h 【ip2】 -p 【port2】info keyspace 1
4.資料一致後,進入從節點重新建立主從關係
      redis-cli -a 【pwd3】 -h 【ip3】 -p 【port3】slaveof pika1 9221
5.查詢主從資料是否一致
      redis-cli -a 【pwd1】 -h 【ip1】 -p 【port1】info keyspace 1
      redis-cli -a 【pwd2】 -h 【ip2】 -p 【port2】info keyspace 1
      redis-cli -a 【pwd3】 -h 【ip3】 -p 【port3】info keyspace 1

四、redis遷移到已有資料的redis中

1.建立主從的方式,從redis中會先執行Flushing old data後才建立主從,此方式不可行
2.推薦使用redis-port 方式遷移,遷移方式同上

./redis-port sync -f 【需要遷移ip】:【需要遷移port】-t  【目標ip】:【目標port】--fromversion=9  --toversion=9 -A 123456 -P 123456 -n 4 -p 32  --sockfile=test.tmp --filesize=32GB

注:資料遷移過程中,因為倆個redis中都有資料,那麼需要確定,重複的key是否可以丟失,遷移中預設是保留目標redis中重複的key值,需要遷移的redis中的重複的key不會被遷移