redis

<meta charset="utf-8">

第1章 Redis介紹

1.1 Redis是什么

Redis是一種基于鍵值對的NoSQL數(shù)據(jù)庫,與很多鍵值對數(shù)據(jù)庫不同,redis中的值可以有string,hash,list,set,zset,geo等多種數(shù)據(jù)結(jié)構(gòu)和算法組成.
因?yàn)镽edis會(huì)將所有的數(shù)據(jù)都放在內(nèi)存中,所以他的讀寫性能非常驚人.
不僅如此,Redis還可以將內(nèi)存中的數(shù)據(jù)利用快照和日志的形式保存到硬盤上
Redis還提供了鍵過期,發(fā)布訂閱,事務(wù),流水線等附加功能.

1.2 Redis重要特性

1.速度快

Redis所有的數(shù)據(jù)都存放在內(nèi)存中
Redis使用C語言實(shí)現(xiàn)
Redis使用單線程架構(gòu)

2.基于鍵值對的數(shù)據(jù)結(jié)構(gòu)服務(wù)器

5中數(shù)據(jù)結(jié)構(gòu):字符串,哈希,列表,集合,有序集合

3.豐富的功能

提供了鍵過期功能,可以實(shí)現(xiàn)緩存
提供了發(fā)布訂閱功能,可以實(shí)現(xiàn)消息系統(tǒng)
提供了pipeline功能,客戶端可以將一批命令一次性傳到Redis,減少了網(wǎng)絡(luò)開銷

4.簡單穩(wěn)定

源碼很少,3.0版本以后5萬行左右.
使用單線程模型法,是的Redis服務(wù)端處理模型變得簡單.
不依賴操作系統(tǒng)的中的類庫

5.客戶端語言多

java,PHP,python,C,C++,Nodejs等

6.持久化

RDB和AOF

7.主從復(fù)制

8.高可用和分布式

哨兵
集群

1.3 Redis應(yīng)用場景

1.緩存-鍵過期時(shí)間

緩存session會(huì)話
緩存用戶信息,找不到再去mysql查,查到然后回寫到redis

2.排行榜-列表&有序集合

熱度排名排行榜
發(fā)布時(shí)間排行榜

3.計(jì)數(shù)器應(yīng)用-天然支持計(jì)數(shù)器

帖子瀏覽數(shù)
視頻播放次數(shù)
商品瀏覽數(shù)

4.社交網(wǎng)絡(luò)-集合

踩/贊,粉絲,共同好友/喜好,推送,打標(biāo)簽

5.消息隊(duì)列系統(tǒng)-發(fā)布訂閱

配合elk實(shí)現(xiàn)日志收集

第2章 Redis安裝部署

2.1 目錄規(guī)劃

### redis下載目錄
/data/soft/
### redis安裝目錄
/opt/redis_cluster/redis_{PORT}/{conf,logs,pid}
### redis數(shù)據(jù)目錄
/data/redis_cluster/redis_{PORT}/redis_{PORT}.rdb
### redis運(yùn)維腳本
/root/scripts/redis_shell.sh

2.2 安裝命令

編輯hosts文件

[root@db01 ~]# tail -3 /etc/hosts
10.0.0.51 db01    
10.0.0.52 db02    
10.0.0.53 db03
mkdir -p /data/soft
mkdir -p /data/redis_cluster/redis_6379
mkdir -p /opt/redis_cluster/redis_6379/{conf,pid,logs}
cd /data/soft/
wget http://download.redis.io/releases/redis-3.2.9.tar.gz
tar zxf redis-3.2.9.tar.gz -C /opt/redis_cluster/
ln -s /opt/redis_cluster/redis-3.2.9/ /opt/redis_cluster/redis
cd /opt/redis_cluster/redis
make && make install

2.3 配置文件說明

### 以守護(hù)進(jìn)程模式啟動(dòng)
daemonize yes
### 綁定的主機(jī)地址
bind 10.0.0.51
### 監(jiān)聽端口
port 6379
### pid文件和log文件的保存地址
pidfile /opt/redis_cluster/redis_6379/pid/redis_6379.pid
logfile /opt/redis_cluster/redis_6379/logs/redis_6379.log
### 設(shè)置數(shù)據(jù)庫的數(shù)量郭膛,默認(rèn)數(shù)據(jù)庫為0
databases 16
### 指定本地持久化文件的文件名,默認(rèn)是dump.rdb
dbfilename redis_6379.rdb
### 本地?cái)?shù)據(jù)庫的目錄
dir /data/redis_cluster/redis_6379

2.4 啟動(dòng)關(guān)閉服務(wù)

啟動(dòng)

[root@db01 ~]# redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf

關(guān)閉

[root@db01 ~]# redis-cli -h db01 shutdown

第3章 Redis基本操作命令

3.1 全局命令

Redis有5種數(shù)據(jù)結(jié)構(gòu),他們是鍵值對中的值,對于鍵來說有一些通用的命令.
1.查看所有命鍵

Keys *  

十分危險(xiǎn)的命令,線上禁止使用

2.查看鍵的總數(shù)

Dbsize 
# dbsize 命令在計(jì)算鍵總數(shù)時(shí)不會(huì)遍歷所有鍵,而是直接獲取Redis內(nèi)置的鍵總數(shù)變量.

3.檢查鍵是否存在

Exists key
# 如果鍵存在則返回1,不存在則返回0

4.刪除鍵

Del key [key …]

通用命令,無論值是什么數(shù)據(jù)結(jié)構(gòu)類型,del命令都可以將其刪除.

5.鍵過期

Expire key seconds
# Redis支持對鍵添加過期時(shí)間,當(dāng)超過過期時(shí)間后,會(huì)自動(dòng)刪除鍵.
# 通過ttl命令觀察鍵的剩余時(shí)間
大于等于0的證書: 鍵剩余過期時(shí)間
-1: 鍵沒設(shè)置過期時(shí)間
-2: 鍵不存在

6.鍵的數(shù)據(jù)類型

Type key

3.2 字符串

Redis并不是簡單地key-value存儲(chǔ),實(shí)際上他是一個(gè)數(shù)據(jù)結(jié)構(gòu)服務(wù)器,支持不同類型的值.
Redis Strings
這是最簡單的Redis類型,如果你只用這種類型,Redis就像一個(gè)持久化的memcache服務(wù)器(注:memcache的數(shù)據(jù)僅保存在內(nèi)存中,服務(wù)器重啟后,數(shù)據(jù)將丟失.)
操作命令:
通常用SET command 和 GET command來設(shè)置和獲取字符串值
練習(xí):

db01:6379> set key1 value1
OK
db01:6379> get key1
"value1"
db01:6379> keys *
1) "key1"

操作命令:
INCR命令將字符串值解析成整型.將其加1,最后結(jié)果保存為新的字符串,類似命令: INCRBY,DECR,DECRBY
練習(xí):

db01:6379> set key2 100
OK
db01:6379> get key2
"100"
db01:6379> incr key2
(integer) 101
db01:6379> get key2
"101"
db01:6379> incrby key2 10
(integer) 111
db01:6379> get key2
"111"

操作命令:
MSET和MGET可以一次存儲(chǔ)或獲取多個(gè)key對應(yīng)的值.
練習(xí):

db01:6379> mset key3 v3 key4 v4 key5 v5
OK
db01:6379> mget key3 key4 key5
1) "v3"
2) "v4"
3) "v5"

操作命令:
EXISTS命令返回1或0標(biāo)識(shí)給定key的值是否存在.
使用DEL命令可以刪除key對應(yīng)的值,
DEL命令返回1或0標(biāo)識(shí)是被刪除(值存在)或者沒被刪除(key對應(yīng)的值不存在).
練習(xí):

db01:6379> exists key5
(integer) 1
db01:6379> del key5
(integer) 1
db01:6379> exists key5
(integer) 0
db01:6379> del key5
(integer) 0

操作命令:
Type命令可以返回key對應(yīng)的存儲(chǔ)類型
練習(xí):

db01:6379> set key5 v5
OK
db01:6379> type key5
string

操作命令:
可以對key設(shè)置一個(gè)超時(shí)時(shí)間,當(dāng)這個(gè)時(shí)間到達(dá)后被刪除
練習(xí):

db01:6379> get key5
"v5"
db01:6379> ttl key5
(integer) -1
db01:6379> expire key5 10
(integer) 1
db01:6379> ttl key5
(integer) 6
db01:6379> ttl key5
(integer) 5
db01:6379> ttl key5
(integer) 2
db01:6379> ttl key5
(integer) -2
db01:6379> ttl key5
(integer) -2
db01:6379> get key5
(nil)

操作命令:
PERSIST命令去除超時(shí)時(shí)間
練習(xí):

db01:6379> set key5 v5 ex 10
OK
db01:6379> ttl key5
(integer) 8
db01:6379> ttl key5
(integer) 6
db01:6379> persist key5
(integer) 1
db01:6379> ttl key5
(integer) -1

3.3 列表

操作命令:
LPUSH命令可向list的左邊(頭部)添加一個(gè)新元素
RPUSH命令可向list的右邊(尾部)添加一個(gè)新元素.
最后LRANGE可以從list中取出一定范圍的元素
練習(xí):

db01:6379> rpush list1 A
(integer) 1
db01:6379> rpush list1 B
(integer) 2
db01:6379> lpush list1 top1
(integer) 3
db01:6379> lrange list1 0 -1
1) "top1"
2) "A"
3) "B"
db01:6379> lrange list1 1 -1
1) "A"
2) "B"
db01:6379> lrange list1 2 -1
1) "B"

操作命令:
Pop,從list中刪除元素并同時(shí)返回刪除的值,可以在左邊或右邊操作.
練習(xí):

db01:6379> rpop list1
"B"
db01:6379> lrange list1 0 -1
1) "top1"
2) "A"
db01:6379> lpop list1
"top1"
db01:6379> lrange list1 0 -1
1) "A"

3.4 哈希
操作命令:
Hash看起來就像一個(gè)’hash’的樣子.由鍵值對組成
HMSET指令設(shè)置hash中的多個(gè)域
HGET取回單個(gè)域.
HMGET取回一系列的值
練習(xí):

db01:6379> hmset user:1000 username zhangya age 27 job it
OK
db01:6379> hget user:1000 username
"zhangya"
db01:6379> hmget user:1000 username age job
1) "zhangya"
2) "27"
3) "it"
db01:6379> hgetall user:1000
1) "username"
2) "zhangya"
3) "age"
4) "27"
5) "job"
6) "it"
db01:6379> hmset user:1000 qq 526195417
OK
db01:6379> hgetall user:1000
1) "username"
2) "zhangya"
3) "age"
4) "27"
5) "job"
6) "it"
7) "qq"
8) "526195417"

3.5 集合
操作命令:
集合是字符串的無序排列,
SADD指令把新的元素添加到set中
練習(xí):

db01:6379> sadd set1 1 2 3
(integer) 3
db01:6379> smembers set1
1) "1"
2) "2"
3) "3"

和list類型不同,set集合不允許出現(xiàn)重復(fù)的元素

db01:6379> sadd set1 1 4
(integer) 1
db01:6379> smembers set1
1) "1"
2) "2"
3) "3"
4) "4"

Srem用來刪除指定的值

db01:6379> srem set1 2 4
(integer) 2
db01:6379> smembers set1
1) "1"
2) "3"

Sdiff計(jì)算集合的差異成員

db01:6379> sadd set1 1 2 3 4
(integer) 2
db01:6379> sadd set2 1 4 5
(integer) 3
db01:6379> sdiff set1 set2
1) "2"
2) "3"

Sinter計(jì)算集合的交集

db01:6379> sinter set1 set2
1) "1"
2) "4"

Sunion計(jì)算集合并集

db01:6379> sunion set1 set2
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"

第4章 Redis持久化

4.1 持久化的兩種方式介紹

RDB 持久化優(yōu)缺點(diǎn)
可以在指定的時(shí)間間隔內(nèi)生成數(shù)據(jù)集的 時(shí)間點(diǎn)快照(point-in-time snapshot)。
優(yōu)點(diǎn):速度快氛悬,適合于用做備份则剃,主從復(fù)制也是基于RDB持久化功能實(shí)現(xiàn)的。
缺點(diǎn):會(huì)有數(shù)據(jù)丟失
rdb持久化核心配置參數(shù):

vim /data/6379/redis.conf
dir /data/6379
dbfilename dump.rdb
save 900 1      #900秒(15分鐘)內(nèi)有1個(gè)更改
save 300 10     #300秒(5分鐘)內(nèi)有10個(gè)更改
save 60 10000   #60秒內(nèi)有10000個(gè)更改  

AOF 持久化(append-only log file)優(yōu)缺點(diǎn)
記錄服務(wù)器執(zhí)行的所有寫操作命令如捅,并在服務(wù)器啟動(dòng)時(shí)棍现,通過重新執(zhí)行這些命令來還原數(shù)據(jù)集。
AOF 文件中的命令全部以 Redis 協(xié)議的格式來保存镜遣,新命令會(huì)被追加到文件的末尾己肮。
優(yōu)點(diǎn):可以最大程度保證數(shù)據(jù)不丟
缺點(diǎn):日志記錄量級(jí)比較大

AOF持久化配置

appendonly yes          #是否打開aof日志功能
appendfsync always      #每1個(gè)命令,都立即同步到aof
appendfsync everysec    #每秒寫1次
appendfsync no          #寫入工作交給操作系統(tǒng),由操作系統(tǒng)判斷緩沖區(qū)大小,統(tǒng)一寫入到aof.

4.2 面試題

redis 持久化方式有哪些?有什么區(qū)別悲关?
rdb:基于快照的持久化谎僻,速度更快,一般用作備份寓辱,主從復(fù)制也是依賴于rdb持久化功能
aof:以追加的方式記錄redis操作日志的文件艘绍。可以最大程度的保證redis數(shù)據(jù)安全秫筏,類似于mysql的binlog

第5章 Redis安全認(rèn)證

redis默認(rèn)開啟了保護(hù)模式诱鞠,只允許本地回環(huán)地址登錄并訪問數(shù)據(jù)庫。
禁止protected-mode
protected-mode yes/no (保護(hù)模式这敬,是否只允許本地訪問)
(1)Bind :指定IP進(jìn)行監(jiān)聽

[root@db01 ~]# vim /opt/redis_cluster/redis_6379/conf/redis_6379.conf
bind 10.0.0.51  127.0.0.1

(2)增加requirepass {password}

[root@db01 ~]# vim /opt/redis_cluster/redis_6379/conf/redis_6379.conf
requirepass 123456

驗(yàn)證方法一:

[root@db01 ~]# redis-cli -a 123456
127.0.0.1:6379> set k1 v1
OK

驗(yàn)證方法二:

[root@db01 ~]# redis-cli
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> set k2 v2
OK

第6章 Redis主從復(fù)制

6.1 主從復(fù)制介紹

主從復(fù)制介紹
在分布式系統(tǒng)中為了解決單點(diǎn)問題,通常會(huì)把數(shù)據(jù)復(fù)制多個(gè)副本到其他機(jī)器,滿足故障恢復(fù)和負(fù)載均衡等求.
Redis也是如此,提供了復(fù)制功能.
復(fù)制功能是高可用Redis的基礎(chǔ),后面的哨兵和集群都是在復(fù)制的基礎(chǔ)上實(shí)現(xiàn)高可用的.

6.2 配置命令

6.2.1 建立復(fù)制

每個(gè)從節(jié)點(diǎn)只能有一個(gè)主節(jié)點(diǎn),主節(jié)點(diǎn)可以有多個(gè)從節(jié)點(diǎn).
配置復(fù)制的方式有三種:

1.在配置文件中加入slaveof {masterHost} {masterPort} 隨redis啟動(dòng)生效.
2.在redis-server啟動(dòng)命令后加入—slaveof {masterHost} {masterPort}生效.
3.直接使用命令:slaveof {masterHost} {masterPort}生效.

查看復(fù)制狀態(tài)信息命令

Info replication

6.2.2 斷開復(fù)制

Slaveof命令不但可以建立復(fù)制,還可以在從節(jié)點(diǎn)執(zhí)行slave of no one來斷開與主節(jié)點(diǎn)復(fù)制關(guān)系.
斷開復(fù)制主要流程:

1.斷開與主節(jié)點(diǎn)復(fù)制關(guān)系
2.從節(jié)點(diǎn)晉升為主節(jié)點(diǎn)

從節(jié)點(diǎn)斷開復(fù)制后不會(huì)拋棄原有數(shù)據(jù),只是無法再獲取主節(jié)點(diǎn)上的數(shù)據(jù)變化.
通過slaveof命令還可以實(shí)現(xiàn)切主操作,所謂切主是指把當(dāng)前從節(jié)點(diǎn)對主節(jié)點(diǎn)的復(fù)制切換到另一個(gè)主節(jié)點(diǎn).
執(zhí)行slaveof {newMasterIp} {newMasterPort}命令即可.
切主操作流程如下:

1.斷開與舊主節(jié)點(diǎn)的復(fù)制關(guān)系
2.與新主節(jié)點(diǎn)建立復(fù)制關(guān)系
3.刪除從節(jié)點(diǎn)當(dāng)前所有數(shù)據(jù)
4.對新主節(jié)點(diǎn)進(jìn)行復(fù)制操作

提示: 線上操作一定要小心,因?yàn)榍兄骱髸?huì)清空之前所有的數(shù)據(jù).

第7章 Redis Sentinel(哨兵)

7.1 哨兵介紹

Sentinel介紹
Redis的主從模式下航夺,主節(jié)點(diǎn)一旦發(fā)生故障不能提供服務(wù),需要人工干預(yù)崔涂,將從節(jié)點(diǎn)晉升為主節(jié)點(diǎn)阳掐,同時(shí)還需要修改客戶端配置。對于很多應(yīng)用場景這種方式無法接受。
Sentinel(哨兵)架構(gòu)解決了redis主從人工干預(yù)的問題锚烦。
Redis Sentinel是redis的高可用實(shí)現(xiàn)方案觅闽,實(shí)際生產(chǎn)環(huán)境中,對提高整個(gè)系統(tǒng)可用性非常有幫助的涮俄。

7.2 哨兵主要功能

Redis Sentinel 是一個(gè)分布式系統(tǒng)蛉拙, Redis Sentinel為Redis提供高可用性〕骨祝可以在沒有人為干預(yù)的情況下阻止某種類型的故障孕锄。
Redis 的 Sentinel 系統(tǒng)用于管理多個(gè) Redis 服務(wù)器(instance)該系統(tǒng)執(zhí)行以下三個(gè)任務(wù):
1.監(jiān)控(Monitoring):
Sentinel 會(huì)不斷地定期檢查你的主服務(wù)器和從服務(wù)器是否運(yùn)作正常。
2.提醒(Notification):
當(dāng)被監(jiān)控的某個(gè) Redis 服務(wù)器出現(xiàn)問題時(shí)苞尝, Sentinel 可以通過 API 向管理員或者其他應(yīng)用程序發(fā)送通知畸肆。
3.自動(dòng)故障遷移(Automatic failover):
當(dāng)一個(gè)主服務(wù)器不能正常工作時(shí), Sentinel 會(huì)開始一次自動(dòng)故障遷移操作宙址, 它會(huì)將失效主服務(wù)器的其中一個(gè)從服務(wù)器升級(jí)為新的主服務(wù)器轴脐, 并讓失效主服務(wù)器的其他從服務(wù)器改為復(fù)制新的主服務(wù)器; 當(dāng)客戶端試圖連接失效的主服務(wù)器時(shí)抡砂, 集群也會(huì)向客戶端返回新主服務(wù)器的地址大咱, 使得集群可以使用新主服務(wù)器代替失效服務(wù)器
架構(gòu)圖:

7.3 目錄規(guī)劃

角色  IP  端口
Master  10.0.0.51   6379
Sentinel-01     26379
Master  10.0.0.52   6379
Sentinel-01     26379
Master  10.0.0.53   6379
Sentinel-01     26379

7.4 安裝配置命令

哨兵是基于主從復(fù)制,所以需要先部署好主從復(fù)制
手工操作步驟如下:
1.先配置和創(chuàng)建好1臺(tái)服務(wù)器的節(jié)點(diǎn)和哨兵
2.使用rsync傳輸?shù)搅硗?臺(tái)機(jī)器
3.修改另外兩臺(tái)機(jī)器的IP地址
建議使用ansible劇本批量部署

7.4.1 db01命令

mkdir -p /data/redis_cluster/redis_26379
mkdir -p /opt/redis_cluster/redis_26379/{conf,pid,logs}
vim /opt/redis_cluster/redis_26379/conf/redis_26379.conf
bind 10.0.0.51
port 26379
daemonize yes
logfile /opt/redis_cluster/redis_26379/logs/redis_26379.log
dir /data/redis_cluster/redis_26379
sentinel monitor mymaster 10.0.0.51 6379 2
sentinel down-after-milliseconds mymaster 3000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 18000

7.4.2 配置文件解釋

sentinel monitor mymaster 10.0.0.51 6379 2 
#mymaster主節(jié)點(diǎn)別名 主節(jié)點(diǎn) ip 和端口注益,判斷主節(jié)點(diǎn)失敗碴巾,兩個(gè) sentinel 節(jié)點(diǎn)同意
sentinel down-after-milliseconds mymaster 30000 
#選項(xiàng)指定了 Sentinel 認(rèn)為服務(wù)器已經(jīng)斷線所需的毫秒數(shù)。
sentinel parallel-syncs mymaster 1 
#向新的主節(jié)點(diǎn)發(fā)起復(fù)制操作的從節(jié)點(diǎn)個(gè)數(shù)丑搔,1輪詢發(fā)起復(fù)制
sentinel failover-timeout mymaster 180000 
#故障轉(zhuǎn)移超時(shí)時(shí)間

7.4.3 db02/db03命令

db01

rsync -avz /opt/* db02:/opt/
rsync -avz /opt/* db03:/opt/

db02

mkdir -p /data/redis_cluster/redis_26379
cd /opt/redis_cluster/redis
make install
sed -i 's#bind 10.0.0.51#bind 10.0.0.52#g' /opt/redis_cluster/redis_6379/conf/redis_6379.conf
sed -i 's#bind 10.0.0.51#bind 10.0.0.52#g' /opt/redis_cluster/redis_26379/conf/redis_26379.conf

db03

mkdir -p /data/redis_cluster/redis_26379
cd /opt/redis_cluster/redis
make install
sed -i 's#bind 10.0.0.51#bind 10.0.0.53#g' /opt/redis_cluster/redis_6379/conf/redis_6379.conf
sed -i 's#bind 10.0.0.51#bind 10.0.0.53#g' /opt/redis_cluster/redis_26379/conf/redis_26379.conf

7.4.4 配置主從關(guān)系

db02和db03

redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf
redis-cli slaveof 10.0.0.51 6379
ps -ef|grep redis

7.4.5 啟動(dòng)哨兵

3臺(tái)都操作

redis-sentinel /opt/redis_cluster/redis_26379/conf/redis_26379.conf

7.5 配置文件的變化

當(dāng)所有節(jié)點(diǎn)啟動(dòng)后,配置文件的內(nèi)容發(fā)生了變化,體現(xiàn)在三個(gè)方面:

1)Sentinel節(jié)點(diǎn)自動(dòng)發(fā)現(xiàn)了從節(jié)點(diǎn),其余Sentinel節(jié)點(diǎn)
2)去掉了默認(rèn)配置,例如parallel-syncs failover-timeout參數(shù)
3)添加了配置紀(jì)元相關(guān)參數(shù)

查看配置文件命令

[root@db01 ~]# tail -6 /opt/redis_cluster/redis_26379/conf/redis_26379.conf  
# Generated by CONFIG REWRITE
sentinel known-slave mymaster 10.0.0.52 6379
sentinel known-slave mymaster 10.0.0.53 6379
sentinel known-sentinel mymaster 10.0.0.53 26379 7794fbbb9dfb62f4d2d7f06ddef06bacb62e4c97
sentinel known-sentinel mymaster 10.0.0.52 26379 17bfab23bc53a531571790b9b31558dddeaeca40
sentinel current-epoch 0

7.6 哨兵常用操作API

登陸命令

[root@db01 ~]# redis-cli -h db01 -p 26379
Sentinel節(jié)點(diǎn)是一個(gè)特殊的Redis節(jié)點(diǎn),他們有自己專屬的API
Info Sentinel
Sentinel masters
Sentinel master <master name>
Sentinel slaves <master name> 
Sentinel sentinels <master name>
Sentinel get-master-addr-by-name <master name>   
Sentinel failover <master name>
Sentinel flushconfig

7.7 模擬故障轉(zhuǎn)移

停掉其中1個(gè)節(jié)點(diǎn)厦瓢,然后觀察其他節(jié)點(diǎn)的日志變化
故障轉(zhuǎn)移后配置文件變化
Redis Sentinel存在多個(gè)從節(jié)點(diǎn)時(shí),如果想將指定的從節(jié)點(diǎn)晉升為主節(jié)點(diǎn),可以將其他從節(jié)點(diǎn)的slavepriority配置為0,但是需要注意failover后,將slave-priority調(diào)回原值.

1.查詢命令:CONFIG GET slave-priority
2.設(shè)置命令:CONFIG SET slave-priority 0
3.主動(dòng)切換:sentinel failover mymaster

操作過程:
db02/db03操作

redis-cli -h db02 -p 6379 CONFIG SET slave-priority 0
redis-cli -h db03 -p 6379 CONFIG SET slave-priority 0

db01操作

redis-cli -h db01 -p 26379 Sentinel failover mymaster

第8章 Redis Cluster

8.1 集群介紹

Redis Cluster 是 redis的分布式解決方案,在3.0版本正式推出
當(dāng)遇到單機(jī)啤月、內(nèi)存煮仇、并發(fā)、流量等瓶頸時(shí)顽冶,可以采用Cluster架構(gòu)方案達(dá)到負(fù)載均衡目的欺抗。
Redis Cluster之前的分布式方案有兩種:
1)客戶端分區(qū)方案,優(yōu)點(diǎn)分區(qū)邏輯可控强重,缺點(diǎn)是需要自己處理數(shù)據(jù)路由绞呈,高可用和故障轉(zhuǎn)移等。

  1. 代理方案间景,優(yōu)點(diǎn)是簡化客戶端分布式邏輯和升級(jí)維護(hù)便利佃声,缺點(diǎn)加重架構(gòu)部署和性能消耗。
    官方提供的 Redis Cluster集群方案倘要,很好的解決了集群方面的問題

8.2 數(shù)據(jù)分布

分布式數(shù)據(jù)庫首先要解決把整個(gè)數(shù)據(jù)庫集按照分區(qū)規(guī)則映射到多個(gè)節(jié)點(diǎn)的問題圾亏,即把數(shù)據(jù)集劃分到多個(gè)節(jié)點(diǎn)上十拣,每個(gè)節(jié)點(diǎn)負(fù)責(zé)整體數(shù)據(jù)的一個(gè)子集,需要關(guān)注的是數(shù)據(jù)分片規(guī)則志鹃,Redis Cluster采用哈希分片規(guī)則夭问。

8.3 目錄規(guī)劃

# redis安裝目錄
/opt/redis_cluster/redis_{PORT}/{conf,logs,pid}
# redis數(shù)據(jù)目錄
/data/redis_cluster/redis_{PORT}/redis_{PORT}.rdb
# redis運(yùn)維腳本
/root/scripts/redis_shell.sh

8.4 集群拓?fù)?/h2>

不太合理的拓?fù)洌?/p>

合理的拓?fù)洌?/p>

8.5 手動(dòng)搭建部署集群

思路:
1)部署一臺(tái)服務(wù)器上的2個(gè)集群節(jié)點(diǎn)
2)發(fā)送完成后修改其他主機(jī)的IP地址
3)使用ansible批量部署
實(shí)現(xiàn)命令:
db01操作

mkdir -p /opt/redis_cluster/redis_{6380,6381}/{conf,logs,pid}
mkdir –p /data/redis_cluster/redis_{6380,6381}
cat >/opt/redis_cluster/redis_6380/conf/redis_6380.conf<<EOF
bind 10.0.0.51
port 6380
daemonize yes
pidfile "/opt/redis_cluster/redis_6380/pid/redis_6380.pid"
logfile "/opt/redis_cluster/redis_6380/logs/redis_6380.log"
dbfilename "redis_6380.rdb"
dir "/data/redis_cluster/redis_6380/"
cluster-enabled yes
cluster-config-file nodes_6380.conf
cluster-node-timeout 15000
EOF
cd /opt/redis_cluster/
cp redis_6380/conf/redis_6380.conf redis_6381/conf/redis_6381.conf
sed -i 's#6380#6381#g' redis_6381/conf/redis_6381.conf 
rsync -avz /opt/redis_cluster/redis_638* db02:/opt/redis_cluster/
rsync -avz /opt/redis_cluster/redis_638* db03:/opt/redis_cluster/
redis-server /opt/redis_cluster/redis_6380/conf/redis_6380.conf
redis-server /opt/redis_cluster/redis_6381/conf/redis_6381.conf

db02操作:

find /opt/redis_cluster/redis_638* -type f -name "*.conf"|xargs sed -i "/bind/s#51#52#g"
mkdir –p /data/redis_cluster/redis_{6380,6381}
redis-server /opt/redis_cluster/redis_6380/conf/redis_6380.conf
redis-server /opt/redis_cluster/redis_6381/conf/redis_6381.conf

db03操作

find /opt/redis_cluster/redis_638* -type f -name "*.conf"|xargs sed -i "/bind/s#51#53#g"
mkdir –p /data/redis_cluster/redis_{6380,6381}
redis-server /opt/redis_cluster/redis_6380/conf/redis_6380.conf
redis-server /opt/redis_cluster/redis_6381/conf/redis_6381.conf

8.5.1 手動(dòng)配置節(jié)點(diǎn)發(fā)現(xiàn)

當(dāng)把所有節(jié)點(diǎn)都啟動(dòng)后查看進(jìn)程會(huì)有cluster的字樣

但是登錄后執(zhí)行CLUSTER NODES命令會(huì)發(fā)現(xiàn)只有每個(gè)節(jié)點(diǎn)自己的ID,目前集群內(nèi)的節(jié)點(diǎn)
還沒有互相發(fā)現(xiàn),所以搭建redis集群我們第一步要做的就是讓集群內(nèi)的節(jié)點(diǎn)互相發(fā)現(xiàn).

在執(zhí)行節(jié)點(diǎn)發(fā)現(xiàn)命令之前我們先查看一下集群的數(shù)據(jù)目錄會(huì)發(fā)現(xiàn)有生成集群的配置文件

查看后發(fā)現(xiàn)只有自己的節(jié)點(diǎn)內(nèi)容,等節(jié)點(diǎn)全部發(fā)現(xiàn)后會(huì)把所發(fā)現(xiàn)的節(jié)點(diǎn)ID寫入這個(gè)文件

集群模式的Redis除了原有的配置文件之外又加了一份集群配置文件.當(dāng)集群內(nèi)節(jié)點(diǎn)
信息發(fā)生變化,如添加節(jié)點(diǎn),節(jié)點(diǎn)下線,故障轉(zhuǎn)移等.節(jié)點(diǎn)會(huì)自動(dòng)保存集群狀態(tài)到配置文件.
需要注意的是,Redis自動(dòng)維護(hù)集群配置文件,不需要手動(dòng)修改,防止節(jié)點(diǎn)重啟時(shí)產(chǎn)生錯(cuò)亂.

節(jié)點(diǎn)發(fā)現(xiàn)使用命令: CLUSTER MEET {IP} {PORT}
提示:在集群內(nèi)任意一臺(tái)機(jī)器執(zhí)行此命令就可以

[root@db01 ~]# sh redis_shell.sh login 6380
10.0.0.51:6380> CLUSTER MEET 10.0.0.51 6381
OK
10.0.0.51:6380> CLUSTER MEET 10.0.0.52 6380
OK
10.0.0.51:6380> CLUSTER MEET 10.0.0.53 6380
OK
10.0.0.51:6380> CLUSTER MEET 10.0.0.52 6381
OK
10.0.0.51:6380> CLUSTER MEET 10.0.0.53 6381
OK
10.0.0.51:6380> CLUSTER NODES
d03cb38d612802aead8f727b1726a3359c241818 10.0.0.51:6380 myself,master - 0 0 4 connected
67c8128df00b2fa304a41bafbadac25a654f196d 10.0.0.51:6381 master - 0 1562059947079 1 connected
a23ec7d444791a0b258ac454ef15cb4d6ab5abd2 10.0.0.53:6381 master - 0 1562059948087 5 connected
e57807d4d35daaaca05f4a9705e844eab15c7ce8 10.0.0.52:6381 master - 0 1562059949098 0 connected
aa9da67a594dfb357195f12ca4c44001804ee470 10.0.0.53:6380 master - 0 1562059945063 3 connected
5cb6895305520e6a0aa4198a6ea5f2c087530b41 10.0.0.52:6380 master - 0 1562059950108 2 connected

節(jié)點(diǎn)都發(fā)現(xiàn)完畢后我們再次查看集群配置文件
可以看到,發(fā)現(xiàn)到的節(jié)點(diǎn)的ID也被寫入到了集群的配置文件里

8.5.2 Redis Cluster 通訊流程

在分布式存儲(chǔ)中需要提供維護(hù)節(jié)點(diǎn)元數(shù)據(jù)信息的機(jī)制,所謂元數(shù)據(jù)是指:節(jié)點(diǎn)負(fù)責(zé)哪些數(shù)據(jù)曹铃,是否出現(xiàn)故障燈狀態(tài)信息缰趋,redis 集群采用 Gossip(流言)協(xié)議,Gossip 協(xié)議工作原理就是節(jié)點(diǎn)彼此不斷交換信息陕见,一段時(shí)間后所有的節(jié)點(diǎn)都會(huì)知道集群完整信息秘血,這種方式類似流言傳播。
通信過程:
1)集群中的每一個(gè)節(jié)點(diǎn)都會(huì)單獨(dú)開辟一個(gè) Tcp 通道评甜,用于節(jié)點(diǎn)之間彼此通信灰粮,通信端口在基礎(chǔ)端口上家10000.
2)每個(gè)節(jié)點(diǎn)在固定周期內(nèi)通過特定規(guī)則選擇結(jié)構(gòu)節(jié)點(diǎn)發(fā)送 ping 消息
3)接收到 ping 消息的節(jié)點(diǎn)用 pong 消息作為響應(yīng)。集群中每個(gè)節(jié)點(diǎn)通過一定規(guī)則挑選要通信的節(jié)點(diǎn)忍坷,每個(gè)節(jié)點(diǎn)可能知道全部節(jié)點(diǎn)粘舟,也可能僅知道部分節(jié)點(diǎn),只要這些節(jié)點(diǎn)彼此可以正常通信承匣,最終他們會(huì)打成一致的狀態(tài)蓖乘,當(dāng)節(jié)點(diǎn)出現(xiàn)故障,新節(jié)點(diǎn)加入韧骗,主從角色變化等,它能夠給不斷的ping/pong消息零聚,從而達(dá)到同步目的袍暴。
通訊消息類型:
Gossip
Gossip 協(xié)議職責(zé)就是信息交換,信息交換的載體就是節(jié)點(diǎn)間彼此發(fā)送Gossip 消息隶症。
常見 Gossip 消息分為:ping政模、 pong、 meet蚂会、 fail 等
meet
meet 消息:用于通知新節(jié)點(diǎn)加入淋样,消息發(fā)送者通知接受者加入到當(dāng)前集群,meet 消息通信正常完成后胁住,接收節(jié)點(diǎn)會(huì)加入到集群中并進(jìn)行ping趁猴、 pong 消息交換
ping
ping 消息:集群內(nèi)交換最頻繁的消息,集群內(nèi)每個(gè)節(jié)點(diǎn)每秒想多個(gè)其他節(jié)點(diǎn)發(fā)送 ping 消息彪见,用于檢測節(jié)點(diǎn)是否在線和交換彼此信息儡司。
pong
Pong 消息:當(dāng)接收到 ping,meet 消息時(shí)余指,作為相應(yīng)消息回復(fù)給發(fā)送方確認(rèn)消息正常通信捕犬,節(jié)點(diǎn)也可以向集群內(nèi)廣播自身的 pong 消息來通知整個(gè)集群對自身狀態(tài)進(jìn)行更新。
fail
fail 消息:當(dāng)節(jié)點(diǎn)判定集群內(nèi)另一個(gè)節(jié)點(diǎn)下線時(shí),回向集群內(nèi)廣播一個(gè)fail 消息碉碉,其他節(jié)點(diǎn)收到 fail 消息之后把對應(yīng)節(jié)點(diǎn)更新為下線狀態(tài)柴钻。
通訊示意圖:

8.5.3 Redis Cluster手動(dòng)分配槽位

雖然節(jié)點(diǎn)之間已經(jīng)互相發(fā)現(xiàn)了,但是此時(shí)集群還是不可用的狀態(tài),因?yàn)椴]有給節(jié)點(diǎn)分配槽位,而且必須是所有的槽位都分配完畢后整個(gè)集群才是可用的狀態(tài).
反之,也就是說只要有一個(gè)槽位沒有分配,那么整個(gè)集群就是不可用的.
測試命令:

[root@db01 ~]# sh redis_shell.sh login 6380 
10.0.0.51:6380> set k1 v1
(error) CLUSTERDOWN Hash slot not served

10.0.0.51:6380> CLUSTER INFO
cluster_state:fail
cluster_slots_assigned:0
cluster_slots_ok:0
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:0
cluster_current_epoch:5
cluster_my_epoch:4
cluster_stats_messages_sent:1200
cluster_stats_messages_received:1200
10.0.0.51:6380>

前面說了,我們雖然有6個(gè)節(jié)點(diǎn),但是真正負(fù)責(zé)數(shù)據(jù)寫入的只有3個(gè)節(jié)點(diǎn),其他3個(gè)節(jié)點(diǎn)只是作為主節(jié)點(diǎn)的從節(jié)點(diǎn),也就是說,只需要分配期中三個(gè)節(jié)點(diǎn)的槽位就可以了
分配槽位的方法:
分配槽位需要在每個(gè)主節(jié)點(diǎn)上來配置,此時(shí)有2種方法執(zhí)行:
1.分別登錄到每個(gè)主節(jié)點(diǎn)的客戶端來執(zhí)行命令
2.在其中一臺(tái)機(jī)器上用redis客戶端遠(yuǎn)程登錄到其他機(jī)器的主節(jié)點(diǎn)上執(zhí)行命令
每個(gè)節(jié)點(diǎn)執(zhí)行命令:

[root@db01 ~]# redis-cli -h db01 -p 6380 cluster addslots {0..5461}
OK
[root@db01 ~]# redis-cli -h db02 -p 6380 cluster addslots {5462..10922}
OK
[root@db01 ~]# redis-cli -h db03 -p 6380 cluster addslots {10923..16383}
OK

分配完所有槽位之后我們再查看一下集群的節(jié)點(diǎn)狀態(tài)和集群狀態(tài)
可以看到三個(gè)節(jié)點(diǎn)都分配了槽位,而且集群的狀態(tài)是OK的

8.5.4 手動(dòng)配置集群高可用

雖然這時(shí)候集群是可用的了,但是整個(gè)集群只要有一臺(tái)機(jī)器壞掉了,那么整個(gè)集群都是不可用的.
所以這時(shí)候需要用到其他三個(gè)節(jié)點(diǎn)分別作為現(xiàn)在三個(gè)主節(jié)點(diǎn)的從節(jié)點(diǎn),以應(yīng)對集群主節(jié)點(diǎn)故障時(shí)可以進(jìn)行自動(dòng)切換以保證集群持續(xù)可用.
注意:
1.不要讓復(fù)制節(jié)點(diǎn)復(fù)制本機(jī)器的主節(jié)點(diǎn), 因?yàn)槿绻菢拥脑挋C(jī)器掛了集群還是不可用狀態(tài), 所以復(fù)制節(jié)點(diǎn)要復(fù)制其他服務(wù)器的主節(jié)點(diǎn).
2.使用redis-trid工具自動(dòng)分配的時(shí)候會(huì)出現(xiàn)復(fù)制節(jié)點(diǎn)和主節(jié)點(diǎn)在同一臺(tái)機(jī)器上的情況,需要注意

8.5.5 測試集群

這一次我們采用在一臺(tái)機(jī)器上使用redis客戶端遠(yuǎn)程操作集群其他節(jié)點(diǎn)
注意:
1.需要執(zhí)行命令的是每個(gè)服務(wù)器的從節(jié)點(diǎn)
2.注意主從的ID不要搞混了.
執(zhí)行命令:

[root@db01 ~]# redis-cli -h db01 -p 6381 CLUSTER REPLICATE 5cb6895305520e6a0aa4198a6ea5f2c087530b41
OK
[root@db01 ~]# redis-cli -h db02 -p 6381 CLUSTER REPLICATE aa9da67a594dfb357195f12ca4c44001804ee470
OK
[root@db01 ~]# redis-cli -h db03 -p 6381 CLUSTER REPLICATE d03cb38d612802aead8f727b1726a3359c241818
OK

8.6 Redis Cluster測試集群

我們使用常規(guī)插入redis數(shù)據(jù)的方式往集群里寫入數(shù)據(jù)看看會(huì)發(fā)生什么

 [root@db01 ~]# redis-cli -h db01 -p 6380 set k1 v1
(error) MOVED 12706 10.0.0.53:6380

結(jié)果提示error, 但是給出了集群另一個(gè)節(jié)點(diǎn)的地址
那么這條數(shù)據(jù)到底有沒有寫入呢? 我們登錄這兩個(gè)節(jié)點(diǎn)分別查看

[root@db01 ~]# redis-cli -h db03 -p 6380 get k1    
(nil)

結(jié)果沒有,這是因?yàn)槭褂眉汉笥捎跀?shù)據(jù)被分片了,所以并不是說在那臺(tái)機(jī)器上寫入數(shù)據(jù)就會(huì)在哪臺(tái)機(jī)器的節(jié)點(diǎn)上寫入,集群的數(shù)據(jù)寫入和讀取就涉及到了另外一個(gè)概念,ASK路由

8.7 Redis Cluster ASK路由介紹

在集群模式下,Redis接受任何鍵相關(guān)命令時(shí)首先會(huì)計(jì)算鍵對應(yīng)的槽,再根據(jù)槽找出所對應(yīng)的節(jié)點(diǎn)
如果節(jié)點(diǎn)是自身,則處理鍵命令;
否則回復(fù)MOVED重定向錯(cuò)誤,通知客戶端請求正確的節(jié)點(diǎn),這個(gè)過程稱為Mover重定向.

知道了ask路由后,我們使用-c選項(xiàng)批量插入一些數(shù)據(jù)

[root@db01 ~]# cat input_key.sh 
#!/bin/bash
for i in $(seq 1 1000)
do
    redis-cli -c -h db01 -p 6380 set k_${i} v_${i} && echo "set k_${i} is ok"
done

寫入后我們同樣使用-c選項(xiàng)來讀取剛才插入的鍵值,然后查看下redis會(huì)不會(huì)幫我們路由到正確的節(jié)點(diǎn)上

[root@db01 ~]# redis-cli -c -h db01 -p 6380 
db01:6380> get k_1
"v_1"
db01:6380> get k_100
-> Redirected to slot [5541] located at 10.0.0.52:6380
"v_100"
10.0.0.52:6380> get k_1000
-> Redirected to slot [79] located at 10.0.0.51:6380
"v_1000"
10.0.0.51:6380>

8.8 模擬故障轉(zhuǎn)移

至此,我們已經(jīng)手動(dòng)的把一個(gè)redis高可用的集群部署完畢了, 但是還沒有模擬過故障
這里我們就模擬故障,停掉期中一臺(tái)主機(jī)的redis節(jié)點(diǎn),然后查看一下集群的變化
我們使用暴力的kill -9殺掉 db02上的redis集群節(jié)點(diǎn),然后觀察節(jié)點(diǎn)狀態(tài)
理想情況應(yīng)該是db01上的6381從節(jié)點(diǎn)升級(jí)為主節(jié)點(diǎn)

在db01上查看集群節(jié)點(diǎn)狀態(tài)

雖然我們已經(jīng)測試了故障切換的功能,但是節(jié)點(diǎn)修復(fù)后還是需要重新上線
所以這里測試節(jié)點(diǎn)重新上線后的操作
重新啟動(dòng)db02的6380,然后觀察日志

觀察db01上的日志

這時(shí)假如我們想讓修復(fù)后的節(jié)點(diǎn)重新上線,可以在想變成主庫的從庫執(zhí)行CLUSTER FAILOVER命令
這里我們在db02的6380上執(zhí)行

8.9 使用工具搭建部署Redis Cluster

手動(dòng)搭建集群便于理解集群創(chuàng)建的流程和細(xì)節(jié),不過手動(dòng)搭建集群需要很多步驟垢粮,當(dāng)集群節(jié)點(diǎn)眾多時(shí)贴届,必然會(huì)加大搭建集群的復(fù)雜度和運(yùn)維成本,因此官方提供了 redis-trib.rb的工具方便我們快速搭建集群足丢。
redis-trib.rb是采用 Ruby 實(shí)現(xiàn)的 redis 集群管理工具粱腻,內(nèi)部通過 Cluster相關(guān)命令幫我們簡化集群創(chuàng)建、檢查斩跌、槽遷移和均衡等常見運(yùn)維操作绍些,使用前要安裝 ruby 依賴環(huán)境
安裝命令:

yum makecache fast
yum install rubygems
gem sources --remove https://rubygems.org/
gem sources -a http://mirrors.aliyun.com/rubygems/
gem update - system
gem install redis -v 3.3.5

我們可以停掉所有的節(jié)點(diǎn),然后清空數(shù)據(jù)耀鸦,恢復(fù)成一個(gè)全新的集群柬批,所有機(jī)器執(zhí)行命令

pkill redis
rm -rf /data/redis_cluster/redis_6380/*
rm -rf /data/redis_cluster/redis_6381/*

全部清空之后啟動(dòng)所有的節(jié)點(diǎn),所有機(jī)器執(zhí)行

sh redis_shell.sh start 6380
sh redis_shell.sh start 6381

db01執(zhí)行創(chuàng)建集群命令

cd /opt/redis_cluster/redis/src/
./redis-trib.rb create --replicas 1 10.0.0.51:6380 10.0.0.52:6380 10.0.0.53:6380 10.0.0.51:6381 10.0.0.52:6381 10.0.0.53:6381

檢查集群完整性

./redis-trib.rb check 10.0.0.51:6380

檢查集群負(fù)載平衡

./redis-trib.rb rebalance 10.0.0.51:6380

8.10 工具擴(kuò)容節(jié)點(diǎn)

Redis集群的擴(kuò)容操作可分為以下幾個(gè)步驟
1)準(zhǔn)備新節(jié)點(diǎn)
2)加入集群
3)遷移槽和數(shù)據(jù)
擴(kuò)容流程圖:

我們在db01上創(chuàng)建2個(gè)新節(jié)點(diǎn)

mkdir -p /opt/redis_cluster/redis_{6390,6391}/{conf,logs,pid}
mkdir -p /data/redis_cluster/redis_{6390,6391}
cd /opt/redis_cluster/
cp redis_6380/conf/redis_6380.conf redis_6390/conf/redis_6390.conf
cp redis_6380/conf/redis_6380.conf redis_6391/conf/redis_6391.conf
sed -i 's#6380#6390#g' redis_6390/conf/redis_6390.conf
sed -i 's#6380#6391#g' redis_6391/conf/redis_6391.conf

啟動(dòng)節(jié)點(diǎn)

bash redis_shell.sh start 6390
bash redis_shell.sh start 6391

發(fā)現(xiàn)節(jié)點(diǎn)

redis-cli -c -h db01 -p 6380 cluster meet 10.0.0.51 6390
redis-cli -c -h db01 -p 6380 cluster meet 10.0.0.51 6391

在db01上使用工具擴(kuò)容

cd /opt/redis_cluster/redis/src/
./redis-trib.rb reshard 10.0.0.51:6380

打印出進(jìn)群每個(gè)節(jié)點(diǎn)信息后,reshard命令需要確認(rèn)遷移的槽數(shù)量,這里我們輸入4096個(gè):
How many slots do you want to move (from 1 to 16384)? 4096
輸入6390的節(jié)點(diǎn)ID作為目標(biāo)節(jié)點(diǎn),也就是要擴(kuò)容的節(jié)點(diǎn),目標(biāo)節(jié)點(diǎn)只能指定一個(gè)
What is the receiving node ID? xxxxxxxxx
之后輸入源節(jié)點(diǎn)的ID,這里分別輸入每個(gè)主節(jié)點(diǎn)的6380的ID最后輸入done,或者直接輸入all
Source node #1:all
遷移完成后命令會(huì)自動(dòng)退出,這時(shí)候我們查看一下集群的狀態(tài)(遷移過程數(shù)據(jù)不會(huì)丟失袖订,不會(huì)中斷)
./redis-trib.rb rebalance 10.0.0.51:6380

8.11 工具收縮節(jié)點(diǎn)

流程說明
1).首先需要確定下線節(jié)點(diǎn)是否有負(fù)責(zé)的槽,
如果是,需要把槽遷移到其他節(jié)點(diǎn),保證節(jié)點(diǎn)下線后整個(gè)集群槽節(jié)點(diǎn)映射的完整性.
2).當(dāng)下線節(jié)點(diǎn)不再負(fù)責(zé)槽或者本身是從節(jié)點(diǎn)時(shí),
就可以通知集群內(nèi)其他節(jié)點(diǎn)忘記下線節(jié)點(diǎn),當(dāng)所有的節(jié)點(diǎn)忘記該節(jié)點(diǎn)后可以正常關(guān)閉.

這里我們準(zhǔn)備將剛才新添加的節(jié)點(diǎn)下線,也就是6390和6391
收縮和擴(kuò)容遷移的方向相反,6390變?yōu)樵垂?jié)點(diǎn),其他節(jié)點(diǎn)變?yōu)槟繕?biāo)節(jié)點(diǎn),源節(jié)點(diǎn)把自己負(fù)責(zé)的4096個(gè)槽均勻的遷移到其他節(jié)點(diǎn)上,.
由于redis-trib..rb reshard命令只能有一個(gè)目標(biāo)節(jié)點(diǎn),因此需要執(zhí)行3次reshard命令,分別遷移1365,1365,1366個(gè)槽.
操作命令:

cd /opt/redis_cluster/redis/src/
./redis-trib.rb reshard 10.0.0.51:6380
How many slots do you want to move (from 1 to 16384)? 1365
輸入6380的id
輸入6390的id
done

8.12 忘記節(jié)點(diǎn)

由于我們的集群是做了高可用的,所以當(dāng)主節(jié)點(diǎn)下線的時(shí)候從節(jié)點(diǎn)也會(huì)頂上,所以最好我們先下線從節(jié)點(diǎn),然后在下線主節(jié)點(diǎn)

cd /opt/redis_cluster/redis/src/
./redis-trib.rb del-node 10.0.0.51:6391 ID
./redis-trib.rb del-node 10.0.0.51:6390 ID

第9章 Redis集群常用命令

集群(cluster)
CLUSTER INFO 打印集群的信息
CLUSTER NODES 列出集群當(dāng)前已知的所有節(jié)點(diǎn)(node)氮帐,以及這些節(jié)點(diǎn)的相關(guān)信息。 
節(jié)點(diǎn)(node)
CLUSTER MEET <ip> <port> 將 ip 和 port 所指定的節(jié)點(diǎn)添加到集群當(dāng)中洛姑,讓它成為集群的一份子上沐。
CLUSTER FORGET <node_id> 從集群中移除 node_id 指定的節(jié)點(diǎn)。
CLUSTER REPLICATE <node_id> 將當(dāng)前節(jié)點(diǎn)設(shè)置為 node_id 指定的節(jié)點(diǎn)的從節(jié)點(diǎn)楞艾。
CLUSTER SAVECONFIG 將節(jié)點(diǎn)的配置文件保存到硬盤里面参咙。 
槽(slot)
CLUSTER ADDSLOTS <slot> [slot ...] 將一個(gè)或多個(gè)槽(slot)指派(assign)給當(dāng)前節(jié)點(diǎn)。
CLUSTER DELSLOTS <slot> [slot ...] 移除一個(gè)或多個(gè)槽對當(dāng)前節(jié)點(diǎn)的指派硫眯。
CLUSTER FLUSHSLOTS 移除指派給當(dāng)前節(jié)點(diǎn)的所有槽蕴侧,讓當(dāng)前節(jié)點(diǎn)變成一個(gè)沒有指派任何槽的節(jié)點(diǎn)。
CLUSTER SETSLOT <slot> NODE <node_id> 將槽 slot 指派給 node_id 指定的節(jié)點(diǎn)两入,如果槽已經(jīng)指派給另一個(gè)節(jié)點(diǎn)净宵,那么先讓另一個(gè)節(jié)點(diǎn)刪除該槽>,然后再進(jìn)行指派裹纳。
CLUSTER SETSLOT <slot> MIGRATING <node_id> 將本節(jié)點(diǎn)的槽 slot 遷移到 node_id 指定的節(jié)點(diǎn)中择葡。
CLUSTER SETSLOT <slot> IMPORTING <node_id> 從 node_id 指定的節(jié)點(diǎn)中導(dǎo)入槽 slot 到本節(jié)點(diǎn)。
CLUSTER SETSLOT <slot> STABLE 取消對槽 slot 的導(dǎo)入(import)或者遷移(migrate)痊夭。 
鍵 (key)
CLUSTER KEYSLOT <key> 計(jì)算鍵 key 應(yīng)該被放置在哪個(gè)槽上刁岸。
CLUSTER COUNTKEYSINSLOT <slot> 返回槽 slot 目前包含的鍵值對數(shù)量。CLUSTER GETKEYSINSLOT <slot> <count> 返回 count 個(gè) slot 槽中的鍵她我。

第10章 Redis運(yùn)維工具

10.1 運(yùn)維腳本

[root@db01 ~]# cat redis_shell.sh 
#!/bin/bash

USAG(){
    echo "sh $0 {start|stop|restart|login|ps|tail} PORT"
}
if [ "$#" = 1 ]
then
    REDIS_PORT='6379'
elif 
    [ "$#" = 2 -a -z "$(echo "$2"|sed 's#[0-9]##g')" ]
then
    REDIS_PORT="$2"
else
    USAG
    exit 0
fi

REDIS_IP=$(hostname -I|awk '{print $1}')
PATH_DIR=/opt/redis_cluster/redis_${REDIS_PORT}/
PATH_CONF=/opt/redis_cluster/redis_${REDIS_PORT}/conf/redis_${REDIS_PORT}.conf
PATH_LOG=/opt/redis_cluster/redis_${REDIS_PORT}/logs/redis_${REDIS_PORT}.log

CMD_START(){
    redis-server ${PATH_CONF}
}

CMD_SHUTDOWN(){
    redis-cli -c -h ${REDIS_IP} -p ${REDIS_PORT} shutdown
}

CMD_LOGIN(){
    redis-cli -c -h ${REDIS_IP} -p ${REDIS_PORT}
}

CMD_PS(){
    ps -ef|grep redis
}

CMD_TAIL(){
    tail -f ${PATH_LOG}
}

case $1 in
    start)
        CMD_START
        CMD_PS
        ;;
    stop)
        CMD_SHUTDOWN
        CMD_PS
        ;;
    restart)
        CMD_START
        CMD_SHUTDOWN
        CMD_PS
        ;;
    login)
        CMD_LOGIN
        ;;
    ps)
        CMD_PS
        ;;
    tail)
        CMD_TAIL
        ;;
    *)
        USAG
esac

10.2 數(shù)據(jù)導(dǎo)入導(dǎo)出工具

需求背景
剛切換到redis集群的時(shí)候肯定會(huì)面臨數(shù)據(jù)導(dǎo)入的問題,所以這里推薦使用redis-migrate-tool工具來導(dǎo)入單節(jié)點(diǎn)數(shù)據(jù)到集群里
官方地址:
http://www.oschina.net/p/redis-migrate-tool
安裝工具

cd /opt/redis_cluster/
git clone https://github.com/vipshop/redis-migrate-tool.git
cd redis-migrate-tool/
autoreconf -fvi
./configure
make && make install 

創(chuàng)建配置文件

[root@db01 ~]# cat > redis_6379_to_6380.conf   << eof
[source]
type: single
servers:
- 10.0.0.51:6379

[target]
type: redis cluster
servers:
- 10.0.0.51:6380 

[common]
listen: 0.0.0.0:8888
source_safe: true

生成測試數(shù)據(jù)

[root@db01 ~]# cat input_key.sh 
#!/bin/bash
for i in $(seq 1 1000)
do
    redis-cli -c -h db01 -p 6379 set k_${i} v_${i} && echo "set k_${i} is ok"
done

執(zhí)行導(dǎo)入命令

[root@db01 ~]# redis-migrate-tool -c redis_6379_to_6380.conf 

數(shù)據(jù)校驗(yàn)

[root@db01 ~]# redis-migrate-tool -c redis_6379_to_6380.conf -C redis_check

10.3 分析鍵值大小

需求背景
redis的內(nèi)存使用太大鍵值太多,不知道哪些鍵值占用的容量比較大,而且在線分析會(huì)影響性能.
安裝工具

yum install python-pip gcc python-devel 
cd /opt/
git clone https://github.com/sripathikrishnan/redis-rdb-tools
cd redis-rdb-tools
python setup.py install

使用方法

cd /data/redis_cluster/redis_6380/
rdb -c memory redis_6380.rdb -f redis_6380.rdb.csv

分析rdb并導(dǎo)出

awk -F ',' '{print $4,$2,$3,$1}' redis_6380.rdb.csv |sort  > 6380.txt

10.4 監(jiān)控過期鍵

需求背景
因?yàn)殚_發(fā)重復(fù)提交虹曙,導(dǎo)致電商網(wǎng)站優(yōu)惠卷過期時(shí)間失效
問題分析
如果一個(gè)鍵已經(jīng)設(shè)置了過期時(shí)間迫横,這時(shí)候在set這個(gè)鍵,過期時(shí)間就會(huì)取消
解決思路
如何在不影響機(jī)器性能的前提下批量獲取需要監(jiān)控鍵過期時(shí)間
1.Keys * 查出來匹配的鍵名酝碳。然后循環(huán)讀取ttl時(shí)間
2.scan * 范圍查詢鍵名矾踱。然后循環(huán)讀取ttl時(shí)間
Keys 重操作,會(huì)影響服務(wù)器性能疏哗,除非是不提供服務(wù)的從節(jié)點(diǎn)
Scan 負(fù)擔(dān)小呛讲,但是需要去多次才能取完,需要寫腳本
腳本內(nèi)容:

cat 01get_key.sh 
#!/bin/bash
key_num=0
> key_name.log
for line in $(cat key_list.txt)
do
    while true
    do
        scan_num=$(redis-cli -h 192.168.47.75 -p 6380 SCAN ${key_num} match ${line}\* count 1000|awk 'NR==1{print $0}')
        key_name=$(redis-cli -h 192.168.47.75 -p 6380 SCAN ${key_num} match ${line}\* count 1000|awk 'NR>1{print $0}')
        echo ${key_name}|xargs -n 1 >> key_name.log
        ((key_num=scan_num))
        if [ ${key_num} == 0 ]
           then
           break
        fi
    done
done

第11章 故障案例

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末返奉,一起剝皮案震驚了整個(gè)濱河市贝搁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌芽偏,老刑警劉巖雷逆,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異污尉,居然都是意外死亡膀哲,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進(jìn)店門被碗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來某宪,“玉大人,你說我怎么就攤上這事锐朴⌒宋梗” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵焚志,是天一觀的道長瞻想。 經(jīng)常有香客問我,道長娩嚼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任滴肿,我火速辦了婚禮岳悟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘泼差。我一直安慰自己贵少,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布堆缘。 她就那樣靜靜地躺著滔灶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吼肥。 梳的紋絲不亂的頭發(fā)上录平,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天麻车,我揣著相機(jī)與錄音,去河邊找鬼斗这。 笑死动猬,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的表箭。 我是一名探鬼主播赁咙,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼免钻!你這毒婦竟也來了彼水?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤极舔,失蹤者是張志新(化名)和其女友劉穎凤覆,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體姆怪,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡叛赚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了稽揭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片俺附。...
    茶點(diǎn)故事閱讀 38,650評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖溪掀,靈堂內(nèi)的尸體忽然破棺而出事镣,到底是詐尸還是另有隱情,我是刑警寧澤揪胃,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布璃哟,位于F島的核電站,受9級(jí)特大地震影響喊递,放射性物質(zhì)發(fā)生泄漏随闪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一骚勘、第九天 我趴在偏房一處隱蔽的房頂上張望铐伴。 院中可真熱鬧,春花似錦俏讹、人聲如沸当宴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽户矢。三九已至,卻和暖如春殉疼,著一層夾襖步出監(jiān)牢的瞬間梯浪,已是汗流浹背捌年。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留驱证,地道東北人延窜。 一個(gè)月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像抹锄,于是被迫代替她去往敵國和親逆瑞。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容

  • redis集群分為服務(wù)端集群和客戶端分片伙单,redis3.0以上版本實(shí)現(xiàn)了集群機(jī)制获高,即服務(wù)端集群,3.0以下使用客戶...
    hadoop_null閱讀 1,586評論 0 6
  • NOSQL類型簡介鍵值對:會(huì)使用到一個(gè)哈希表吻育,表中有一個(gè)特定的鍵和一個(gè)指針指向特定的數(shù)據(jù)念秧,如redis,volde...
    MicoCube閱讀 3,961評論 2 27
  • 本文是對Redis的集群部署模式一個(gè)學(xué)習(xí)總結(jié)布疼,共包括如下章節(jié)內(nèi)容: 概述 主從集群模式 “哨兵”集群模式 Clus...
    我是老薛閱讀 934評論 0 4
  • 本篇就一下方面展開分析 如何使用主從復(fù)制摊趾? 主從復(fù)制的原理(重點(diǎn)是全量復(fù)制和部分復(fù)制、以及心跳機(jī)制) 實(shí)際應(yīng)用中需...
    lucode閱讀 989評論 0 5
  • 1 Redis介紹1.1 什么是NoSql為了解決高并發(fā)、高可擴(kuò)展贱案、高可用肛炮、大數(shù)據(jù)存儲(chǔ)問題而產(chǎn)生的數(shù)據(jù)庫解決方...
    克魯?shù)吕?/span>閱讀 5,274評論 0 36