(0)Redis-port原理:html
首先是看到下面這篇文檔開始研究的redis-portmysql
http://www.itnpc.com/news/web/146085373656602.html 簡要截圖以下:git
上面的兩點其實是實現4個功能,在redis-port安裝包README.md的文檔中也有介紹github
* **DECODE** dumped payload to human readable format (hex-encoding)web
* **RESTORE** rdb file to target redisredis
* **DUMP** rdb file from master redissql
* **SYNC** data from master to slavevim
靜態分析RDB文件就是指:decodeapp
解析以及恢復RDB是指:restoresocket
從redis上dumpRDB是指:dump
redis和codis同步數據是指:sync
因此按照README.md的說法看就是將redis-port以slave身份同步redis上的數據到codis
簡書上趕集網DBA寫了一篇關於redis-port的使用文章很受益,指路:
http://www.jianshu.com/p/a5eec15de485
(1)爲方便看我下面的文檔,鋪一下個人部署狀況以下:
(2)準備好redis上須要導入codis的數據
(保證key沒有和codis封裝的redis重複,有重複的就會以新導入的redis上的爲準,由於這裏是從新解讀rdb文件,原有的codis封裝的某一個key會被替換掉)
這裏的redis的數據準備我是從mysql的test庫中u_2表遷移上去的,
固然你能夠本身在redis裏面set,或者本來就有數據,我這裏正好介紹一下mysql----->redis的操做。
準備步驟以下。
2.1)準備protocol,用redis的pipe把mysql的數據導進redis:
這個步驟其實是將mysql的字段拼接成redis能夠讀懂的protocol,
官網指路:英: https://redis.io/topics/protocol 中: http://www.redis.cn/topics/mass-insert.html
[why@wyt1 scripts]$ vim mysql-to-redis.sql
[why@wyt1 scripts]$ cat mysql-to-redis.sql
select
CONCAT('*3\r\n','$','3\r\n','SET\r\n',
'$',LENGTH(empno), '\r\n',empno,'\r\n',
'$',LENGTH(ename), '\r\n',ename, '\r'
)
from test.u_2 ;
[why@wyt1 scripts]$
簡單的解釋一下protocal:
*<參數數量> CR LF
$<參數 1 的字節數量> CR LF
<參數 1 的數據> CR LF
...
$<參數 N 的字節數量> CR LF
<參數 N 的數據> CR LF
拼接後應該是:
*3\r\n$3\r\nSET\r\n$LENGTH(empno)\r\nempno\r\n$LENGTH(ename)\r\nename\r
*3\r\n:是指3個參數即下面有幾個$,這裏是set、empno、ename,其實就是SET KEY VALUE,若是是使用hset的命令就是*4,
後面的格式就是「$+命令或者字段長度+」。
2.2)使用redis的管道將mysql表中的數據遷移到redis
[why@wyt1 scripts]$ mysql -uroot -pwhy -P6666 -h192.168.6.10 -N --raw < /home/why/redis-3.0.7/scripts/mysql-to-redis.sql |/home/why/redis-3.0.7/src/redis-cli -a whyredis -h 192.168.6.11 -p 6001 --pipe
Warning: Using a password on the command line interface can be insecure.
All data transferred. Waiting for the last reply...
Last reply received from server.
errors: 0, replies: 14
(3)安裝和使用redis-port
3.1)編譯:
源碼地址:https://github.com/CodisLabs/redis-port
[why@wyt1 packages]$ unzip redis-port-master.zip -d /home/why/codis/application/codis/src/
[why@wyt1 packages]$ cd /home/why/codis/application/codis/src/
[why@wyt1 src]$ mv redis-port-master/ /home/why/codis/application/codis/src/github.com/CodisLabs/redis-port
這裏爲何要更名字,由於編譯的時候會找這個目錄,/home/why/codis/application/codis/src/github.com/CodisLabs/redis-port/pkg/
[why@wyt1 packages]$ cd /home/why/codis/application/codis/src/github.com/CodisLabs/
[why@wyt1 CodisLabs]$ cd redis-port/
[why@wyt1 redis-port]$ make
make: Warning: File `Makefile' has modification time 9.8e+05 s in the future
fatal: Not a git repository (or any of the parent directories): .git
go build -i -o bin/redis-port ./cmd
make: 警告:檢測到時鐘錯誤。您的建立多是不完整的。
忽略警告後發現bin目錄已經建好裏面有編譯好的redis-port,工具是可以正常使用的。
[why@wyt1 redis-port]$ ls
bin cmd Godeps Makefile MIT-LICENSE.txt pkg README.md vendor version wandoujia_license.txt
[why@wyt1 redis-port]$ cd bin
[why@wyt1 bin]$ ls
redis-port version
[why@wyt1 bin]$
3.2)命令參數使用:
詳見 https://github.com/CodisLabs/redis-port
Options
set runtime.GOMAXPROCS to N
set number of parallel routines
use INPUT as input file, or if it is not given, redis-port reads from stdin (means '/dev/stdin')
use OUTPUT as output file, or if it is not given, redis-port writes to stdout (means '/dev/stdout')
specify the master redis
specify the slave redis (or target redis)
specify the redis auth password
specify the auth password for target
dump or restore following redis backlog commands
target is normal redis instance, default value is false.
target is codis proxy, default value is true.
filter specifed db number, default value is '*'
或者是
[why@wyt1 bin]$ ./redis-port -h
Usage:
redis-port decode [--ncpu=N] [--parallel=M] [--input=INPUT] [--output=OUTPUT]
redis-port restore [--ncpu=N] [--parallel=M] [--input=INPUT] [--faketime=FAKETIME] [--extra] [--filterdb=DB] --target=TARGET [--auth=AUTH] [--redis|--codis]
redis-port sync [--ncpu=N] [--parallel=M] --from=MASTER [--password=PASSWORD] [--psync] [--filterdb=DB] --target=TARGET [--auth=AUTH] [--redis|--codis] [--sockfile=FILE [--filesize=SIZE]]
redis-port dump [--ncpu=N] [--parallel=M] --from=MASTER [--password=PASSWORD] [--extra] [--output=OUTPUT]
redis-port --version
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.
--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.
-e, --extra Set true to send/receive following redis commands, default is false.
--redis Target is normal redis instance, default is false.
--codis Target is codis proxy, default is true.
--filterdb=DB Filter db = DB, default is *.
--psync Use PSYNC command.
[why@wyt1 bin]$
能夠看到redis-port一共有4種使用:decode、restore、dump、sync,這裏咱們用sync實現redis到codis
建立一個存放輸出日誌的位置和文件
[why@wyt1 redis-port]$ mkdir log
[why@wyt1 redis-port]$ cd log
[why@wyt1 log]$ touch redis-to-codis.log
導入以前看一下如今的組一和組二的數據,group1上9個key,group2有9個key(純屬巧合哈)
3.3)使用redis-port:
這裏後臺執行命令
[why@wyt1 redis-port]$ nohup ./bin/redis-port sync --ncpu=1 --from=192.168.6.11:6001 --password=whyredis --target=192.168.6.11:19002 --auth=codiswyt >> /home/why/codis/application/codis/src/github.com/CodisLabs/redis-port/log/redis-to-codis.log 2>&1 &
[2] 58292
[why@wyt1 redis-port]$
看到日誌redis-to-codis.log 輸出以下:
看到group1和group2中都導入了數據
能夠查看一下,這個進程是一直在工做的
[why@wyt1 redis-port]$ ps -ef | grep redis-port|grep -v grep
why 58292 23483 2 09:44 pts/1 00:00:02 ./bin/redis-port sync --ncpu=1 --from=192.168.6.11:6001 --password=whyredis --target=192.168.6.11:19002 --auth=codiswyt
3.4)觀察redis-port工做
可是隻要別同步的redis服務不斷,redis-port的日誌是一直在寫的,
當向redis繼續插入數據時,能夠看到log的輸出變化,下圖58那裏
[why@wyt1 bin]$ ./redis-cli -a whyredis -p 6001
127.0.0.1:6001> get 11370
"SMITH"
127.0.0.1:6001> set idol tfboys
OK
127.0.0.1:6001> set monkey yyqx
OK
127.0.0.1:6001> set rabbit wjk
OK
127.0.0.1:6001> quit
再同時多插入數據看看同步的狀況,將mysql中的u_3表的數據添加到codis
[why@wyt1 scripts]$ vim mysql-to-redis-u3.sql
[why@wyt1 scripts]$ cat mysql-to-redis-u3.sql
select
CONCAT('*3\r\n','$','3\r\n','SET\r\n',
'$',LENGTH(empno), '\r\n',empno,'\r\n',
'$',LENGTH(job), '\r\n',job, '\r'
)
from test.u_3 ;
[why@wyt1 scripts]$
[why@wyt1 scripts]$ mysql -uroot -pwhy -P6666 -h192.168.6.10 -N --raw < /home/why/redis-3.0.7/scripts/mysql-to-redis-u3.sql |/home/why/redis-3.0.7/src/redis-cli -a whyredis -h 192.168.6.11 -p 6001 --pipe
Warning: Using a password on the command line interface can be insecure.
All data transferred. Waiting for the last reply...
Last reply received from server.
errors: 0, replies: 14
[why@wyt1 scripts]$
看到下圖516的那個地方是忽然增長的。
而後停掉6001的redis,看一下redis-port是否會自動斷開,6001的正常關閉
已經查不到redis-port的進程,[why@wyt1 redis-port]$ ps -ef | grep redis-port|grep -v grep
看一下redis-to-codis.log日誌的輸出:是error了,redis-port本身就停了
導入u_2以後檢查一下redis-port是按照crc32原理將redis數據導入兩個slot:
查源redis上的數據
[why@wyt1 redis-3.0.7]$ ./src/redis-cli -a whyredis -p 6001 -h 192.168.6.11
192.168.6.11:6001> keys *
1) "11370"
2) "11935"
3) "11567"
4) "11699"
5) "11500"
6) "11783"
7) "11655"
8) "11877"
9) "11522"
10) "11901"
11) "11845"
12) "11789"
13) "11903"
192.168.6.11:6001>
看一下上面13個key分佈在codis兩個slot的狀況
[why@wyt1 bin]$ ./redis-cli -a codiswyt -p 8002
127.0.0.1:8002> keys *
1) "11522"
2) "name"
3) "7839"
4) "11783"
5) "7900"
6) "11655"
7) "birth"
8) "7876"
9) "11567"
10) "11370"
11) "11845"
12) "11935"
13) "11789"
14) "7499"
15) "gender"
16) "7902"
17) "7698"
127.0.0.1:8002> quit
[why@wyt1 bin]$ ./redis-cli -a codiswyt -p 7002 -h 192.168.6.10
192.168.6.10:7002> keys *
1) "7788"
2) "11877"
3) "age"
4) "11699"
5) "11500"
6) "11901"
7) "11903"
8) "7521"
9) "7844"
10) "7566"
11) "7782"
12) "7934"
13) "7654"
14) "7369"