redis

redis重要特性

1.速度快
Redis 所有的數(shù)據(jù)都存放在內(nèi)存中
Redis 使用c語言實現(xiàn)
Redis 使用單線程架構

2.基于鍵值對的數(shù)據(jù)結構服務器
5種數(shù)據(jù)結構:字符串,哈希,列表,集合,有序集合

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

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

5.客戶端語言多
java,PHP,python,C,C++,Nodejs等

6.數(shù)據(jù)持久化
把所有的數(shù)據(jù)都存在內(nèi)存中
RDB和AOF

7.主從復制
8.高可用和分布式
哨兵 redis-sentinel
集群 redis-cluster

redis應用場景

1.緩存-鍵過期時間
緩存session會話
緩存用戶信息,找不到再去mysql查,查到然后回寫到redis
優(yōu)惠卷過期時間

2.排行榜-列表&有序集合
熱度排名排行榜
發(fā)布時間排行榜

3.計數(shù)器應用-天然支持計數(shù)器
帖子瀏覽數(shù)
視頻播放次數(shù)
商品瀏覽數(shù)

4.社交網(wǎng)絡-集合
踩/贊,粉絲,共同好友/喜好,推送,打標簽

5.消息隊列系統(tǒng)-發(fā)布訂閱
配合elk實現(xiàn)日志收集

redis安裝部署

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

2.安裝命令

編輯hosts文件

[root@db01 ~]# tail -3 /etc/hosts
10.0.0.51 db01
10.0.0.52 db02
10.0.0.53 db03

yum install gcc -y
make distclean && make
mkdir -p /data/soft
mkdir -p /data/redis_6379
mkdir -p /opt/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/
ln -s /opt/redis-3.2.9/ /opt/redis
cd /opt/redis
make && make install

3.配置文件
cat >/opt/redis_6379/conf/redis_6379.conf <<EOF

以守護進程模式啟動

daemonize yes

綁定的主機地址

bind 10.0.0.51

監(jiān)聽端口

port 6379

pid文件和log文件的保存地址

pidfile /opt/redis_6379/pid/redis_6379.pid
logfile /opt/redis_6379/logs/redis_6379.log

設置數(shù)據(jù)庫的數(shù)量垦搬,默認數(shù)據(jù)庫為0

databases 16

指定本地持久化文件的文件名,默認是dump.rdb

dbfilename redis_6379.rdb

本地數(shù)據(jù)庫的目錄

dir /data/redis_6379
EOF

4.啟動redis
redis-server /opt/redis_6379/conf/redis_6379.conf

5.檢查是否啟動
ps -ef|grep redis
netstat -lntup|grep redis

6.進入redis
redis-cli

redis全局命令操作命令

0.寫入key
set k1 v1
set k2 v2
set k3 v3

1.查看所有的key!線上禁止使用!
keys *

2.查看有多少個key,注意,是估值
DBSIZE

3.查看是否存在這個KEY
EXISTS k1
EXISTS k1 k2 k3

狀態(tài)碼:
0 表示這個key不存在
1 表示這個key存在
N 表示有的N個key存在

4.刪除key
DEL k1
DEL k1 k2 k3

狀態(tài)碼:
0 表示這個key不存在
1 表示這個key存在,并且刪除成功
N 表示有的N個key存在,并且刪除N個Key

5.鍵過期
設置過期時間
EXPIRE k1 100

取消過期時間
PERSIST k1

狀態(tài)碼:
0: 表示這個key不存在
1: 表示這個key存在,并且設置過期時間成功

查看key是否過期
TTL k1

狀態(tài)碼:
-1 :這個key存在,并且永不過期
-2 :這個key不存在
N :這個key存在,并且在N秒后過期

過期后的key直接會被刪除

字符串操作:

1.設置一個key
set k1 v1

2.查看一個key
get k1

3.設置多個key
MSET k1 v1 k2 v2 k3 v3

4.查看多個key
MGET k1 k2 k3

5.天然計數(shù)器
加1:
set k1 1
INCR k1
get k1

加N:
INCRBY k1 100

減1:
INCRBY k1 -1

減N:
INCRBY k1 -N

列表:

插入列表:
LPUSH:從列表左側插入數(shù)據(jù)
RPUSH:從列表右側插入數(shù)據(jù)

LPUSH list1 1
LPUSH list1 2
LPUSH list1 3
RPUSH list1 4
RPUSH list1 5
RPUSH list1 6

查看列表的長度:
LLEN list1

查看列表的內(nèi)容:
127.0.0.1:6379> LRANGE list1 0 -1

  1. "3"
  2. "2"
  3. "1"
  4. "4"
  5. "5"
  6. "6"

刪除列表元素:
LPOP: 從列表左側刪除
RPOP: 從列表右側刪除

LPOP list1
RPOP list1

刪除列表內(nèi)容:
DEL list1

哈希:

Hash看起來就像一個’hash’的樣子.由鍵值對組成
HMSET指令設置hash中的多個域
HGET取回單個域
HMGET取回一系列的值

生成一個hash類型:
HMSET user:1 name xiaozhang job it age 28
HMSET user:2 name abc job it age 28
HMSET user:3 name def job it age 28

查看hash里的一個值
HMGET user:1 name

查看hash里的多個值
HMGET user:1 name age job

查看hash里的所有的值
HGETALL user:1

mysql數(shù)據(jù)和redis哈希對比:
user表

uid name job age
1 xiaozhang it 28
2 xiaoya it 28
3 yazhang it 28

mysql查詢數(shù)據(jù)
select * from user where id = 3

redis緩存mysql數(shù)據(jù)
名字 key1 k1值 key2 k2的值 key3 k3的值
uid:1 name xiaozahng job it age 28
uid:2 name xiaoya job it age 28
uid:3 name yazahng job it age 28

集合

創(chuàng)建集合
db01:6379> SADD set1 1 2 3
(integer) 3
db01:6379> SADD set2 1 3 5 7
(integer) 4

查看集合的成員:
db01:6379> SMEMBERS set1

  1. "1"
  2. "2"
  3. "3"
    db01:6379> SMEMBERS set2
  4. "1"
  5. "3"
  6. "5"
  7. "7"

查看集合的差集,以前面一個集合為基準對比后面的,前面有,后面沒有則選出來
db01:6379> SDIFF set1 set2

  1. "2"
    db01:6379> SDIFF set2 set1
  2. "7"

查看集合的交集
db01:6379> SINTER set1 set2

  1. "1"
  2. "3"
  3. "5"

查看集合的并集
db01:6379> SUNION set1 set2

  1. "1"
  2. "2"
  3. "3"
  4. "5"
  5. "7"
    db01:6379> SUNION set1 set2 set3
  6. "1"
  7. "2"
  8. "3"
  9. "5"
  10. "7"
  11. "9"

集合不允許出現(xiàn)重復的值

Redis持久化

1.RDB和AOF優(yōu)缺點
RDB: 快照,把當前內(nèi)存里的狀態(tài)快照到磁盤上
優(yōu)點: 恢復速度快
缺點: 可能會丟失數(shù)據(jù)

AOF: 類似于mysql的binlog,重寫,1秒寫一次
優(yōu)點: 安全,有可能會丟失1秒的數(shù)據(jù)
缺點: 文件比較大,恢復速度慢

2.配置RDB
save 900 1
save 300 10
save 60 10000
dir /data/redis_6379/
dbfilename redis_6379.rdb

結論:
1.執(zhí)行shutdown的時候,內(nèi)部會自動執(zhí)行bgsave,然后再執(zhí)行shutdown
2.pkill kill killall 都類似于執(zhí)行shutdown命令.會觸發(fā)bgsave持久化
3.恢復的時候,rdb文件名稱要和配置文件里寫的一樣
4.如果沒有配置save參數(shù),執(zhí)行shutdown不會自動bgsave持久化
5.如果沒有配置save參數(shù),可以手動執(zhí)行bgsave觸發(fā)持久化保存

常用命令:
ll /data/redis_6379/
cat /opt/redis_6379/conf/redis_6379.conf
vim /opt/redis_6379/conf/redis_6379.conf
pkill redis
redis-server /opt/redis_cluster/redis_6379/conf/redis_6379.conf
redis-cli -h db01
redis-cli -h db01 shutdown
bash for.sh

3.配置AOF
appendfilename "redis_6379.aof"
appendonly yes
appendfsync everysec

實驗:
如果aof和rdb文件同時存在,redis會如何讀取:

實驗步驟:
1.插入一條數(shù)據(jù)
aof: 有記錄
rdb: 沒有記錄
2.復制到其他地方
3.把redis停掉
4.清空數(shù)據(jù)目錄
5.把數(shù)據(jù)文件拷貝過來
aof: 有記錄
rdb: 沒有記錄
6.啟動redis
7.測試,如果有新插入的數(shù)據(jù),就表示讀取的是aof,如果沒有,就表示讀取的是rdb

實驗結論:
如果2種數(shù)據(jù)格式都存在,優(yōu)先讀取aof

Redis用戶認證

1.配置文件
requirepass 123456

2.使用密碼登錄
兩種方式:
第一種:
redis-cli -h db01
AUTH 123456

第二種:
redis-cli -h db01 -a 123456 get k_1

主從復制命令:

方法1:臨時生效
SLAVEOF 10.0.0.51 6379

方法2:寫入配置文件
SLAVEOF 10.0.0.51 6379

取消同步命令:
SLAVEOF no one

主從復制流程:
從庫發(fā)起同步請求
11:55:12.686 * Connecting to MASTER 10.0.0.51:6379
11:55:12.687 * MASTER <-> SLAVE sync started
11:55:12.687 * Non blocking connect for SYNC fired the event.
11:55:12.687 * Master replied to PING, replication can continue...
11:55:12.688 * Partial resynchronization not possible (no cached master)
11:55:12.690 * Full resync from master: c63b80909e49adfa3880dcc87ccffb89d148a564:436

主庫接收請求
11:55:12.694 * Slave 10.0.0.52:6379 asks for synchronization
11:55:12.694 * Full resync requested by slave 10.0.0.52:6379

主庫開始BGSAVE
11:55:12.694 * Starting BGSAVE for SYNC with target: disk
11:55:12.695 * Background saving started by pid 13009
11:55:12.700 * DB saved on disk
11:55:12.700 * RDB: 6 MB of memory used by copy-on-write

從庫接收主庫的數(shù)據(jù),清空自己的數(shù)據(jù),然后將主庫發(fā)送過來的RDB文件加載到內(nèi)存中
11:55:12.780 * MASTER <-> SLAVE sync: receiving 12887 bytes from master
11:55:12.781 * MASTER <-> SLAVE sync: Flushing old data
11:55:12.781 * MASTER <-> SLAVE sync: Loading DB in memory
11:55:12.782 * MASTER <-> SLAVE sync: Finished with success

主庫接收從庫消息,主從復制成功
11:55:12.786 * Background saving terminated with success
11:55:12.786 * Synchronization with slave 10.0.0.52:6379 succeeded

Redis主從復制

快速創(chuàng)建第二臺redis節(jié)點命令:
rsync -avz /opt/* db02:/opt/
rsync -avz /data db02:/
cd /opt/redis
make install
sed -i 's#51#52#g' /opt/redis_6379/conf/redis_6379.conf
rm -rf /data/redis_6379/*
redis-server /opt/redis_6379/conf/redis_6379.conf

配置方法:
方法1: 臨時生效
[root@db-02 ~]# redis-cli -h 10.0.1.52
10.0.0.52:6379> SLAVEOF 10.0.1.51 6379
OK

方法2: 寫入配置文件
SLAVEOF 10.0.1.51 6379

主從復制流程:
1.從節(jié)點發(fā)送同步請求到主節(jié)點
2.主節(jié)點接收到從節(jié)點的請求之后,做了如下操作

  • 立即執(zhí)行bgsave將當前內(nèi)存里的數(shù)據(jù)持久化到磁盤上
  • 持久化完成之后,將rdb文件發(fā)送給從節(jié)點
    3.從節(jié)點從主節(jié)點接收到rdb文件之后,做了如下操作
  • 清空自己的數(shù)據(jù)
  • 載入從主節(jié)點接收的rdb文件到自己的內(nèi)存里
    4.后面的操作就是和主節(jié)點實時的了

取消主從復制
SLAVEOF no one

注意!!!
1.從節(jié)點只讀不可寫
2.從節(jié)點不會自動故障轉(zhuǎn)移,它會一直同步主
10.0.1.52:6379> set k1 v1
(error) READONLY You can't write against a read only slave.
3.主從復制故障轉(zhuǎn)移需要人工介入

  • 修改代碼指向REDIS的IP地址
  • 從節(jié)點需要執(zhí)行SLAVEOF no one

注意!!!
1.從節(jié)點會清空自己原有的數(shù)據(jù),如果同步的對象寫錯了,就會導致數(shù)據(jù)丟失

安全的操作:
1.無論是同步,無論是主節(jié)點還是從節(jié)點
2.先備份一下數(shù)據(jù)

Redis哨兵

哨兵操作
1.快速安裝3個redis節(jié)點
rsync -avz 10.0.0.51:/opt/* /opt/
mkdir /data/redis_6379 -p
cd /opt/redis
make install
sed -i 's#51#53#g' /opt/redis_6379/conf/redis_6379.conf
rm -rf /data/redis_6379/*
redis-server /opt/redis_6379/conf/redis_6379.conf
redis-cli

2.安裝部署3個哨兵節(jié)點

!!!!注意!!!!
三個節(jié)點的bind IP修改為自己的IP地址
===========================
mkdir -p /data/redis_26379
mkdir -p /opt/redis_26379/{conf,pid,logs}

3.配置哨兵的配置文件
db01的配置:
cat >/opt/redis_26379/conf/redis_26379.conf << EOF
bind 10.0.0.51
port 26379
daemonize yes
logfile /opt/redis_26379/logs/redis_26379.log
dir /data/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
EOF

db02的配置:
cat >/opt/redis_26379/conf/redis_26379.conf << EOF
bind 10.0.0.52
port 26379
daemonize yes
logfile /opt/redis_26379/logs/redis_26379.log
dir /data/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
EOF

db03的配置:
cat >/opt/redis_26379/conf/redis_26379.conf << EOF
bind 10.0.0.53
port 26379
daemonize yes
logfile /opt/redis_26379/logs/redis_26379.log
dir /data/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
EOF

4.啟動所有的單節(jié)點
redis-server /opt/redis_6379/conf/redis_6379.conf

5.配置主從復制
redis-cli -h db02 slaveof 10.0.0.51 6379
redis-cli -h db03 slaveof 10.0.0.51 6379

6.啟動哨兵
redis-sentinel /opt/redis_26379/conf/redis_26379.conf

7.驗證主節(jié)點
redis-cli -h db01 -p 26379 Sentinel get-master-addr-by-name mymaster
redis-cli -h db02 -p 26379 Sentinel get-master-addr-by-name mymaster
redis-cli -h db03 -p 26379 Sentinel get-master-addr-by-name mymaster

8.模擬故障轉(zhuǎn)移

  • 關閉主節(jié)點服務上的所有redis進程
  • 觀察其他2個節(jié)點會不會發(fā)生選舉
  • 查看配置文件里會不會自動更新
  • 查看新的主節(jié)點能不能寫入
  • 查看從節(jié)點能否正常同步

9.模擬故障修復上線

  • 啟動單節(jié)點
  • 啟動哨兵

10.模擬權重選舉

  • 設置其他節(jié)點的權重為0
  • 手動發(fā)起重新選舉
  • 觀察所有節(jié)點消息是否同步
  • 觀察切換結果是否符合預期

命令解釋:
1.查詢命令:CONFIG GET slave-priority
2.設置命令:CONFIG SET slave-priority 0
3.主動切換:sentinel failover mymaster

操作命令:
redis-cli -h db02 -p 6379 CONFIG SET slave-priority 0
redis-cli -h db03 -p 6379 CONFIG SET slave-priority 0
redis-cli -h db01 -p 26379 sentinel failover mymaster

驗證選舉結果:
redis-cli -h db01 -p 26379 Sentinel get-master-addr-by-name mymaster
哨兵節(jié)點常用命令
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

Redis哨兵+主從+密碼

主從密碼配置文件里添加2行參數(shù):
requirepass "123456"
masterauth "123456"

哨兵配置文件添加一行參數(shù):
sentinel auth-pass mymaster 123456

基于密碼認證的哨兵配置文件
db01的單節(jié)點配置:
cat >/opt/redis_6379/conf/redis_6379.conf <<EOF
daemonize yes
bind 10.0.0.51 127.0.0.1
port 6379
pidfile /opt/redis_6379/pid/redis_6379.pid
logfile /opt/redis_6379/logs/redis_6379.log
databases 16
dir /data/redis_6379
dbfilename redis_6379.rdb
requirepass "123456"
masterauth "123456"
EOF

db02的單節(jié)點配置:
cat >/opt/redis_6379/conf/redis_6379.conf <<EOF
daemonize yes
bind 10.0.0.52 127.0.0.1
port 6379
pidfile /opt/redis_6379/pid/redis_6379.pid
logfile /opt/redis_6379/logs/redis_6379.log
databases 16
dir /data/redis_6379
dbfilename redis_6379.rdb
requirepass "123456"
masterauth "123456"
EOF

db03的單節(jié)點配置:
cat >/opt/redis_6379/conf/redis_6379.conf <<EOF
daemonize yes
bind 10.0.0.53 127.0.0.1
port 6379
pidfile /opt/redis_6379/pid/redis_6379.pid
logfile /opt/redis_6379/logs/redis_6379.log
databases 16
dir /data/redis_6379
dbfilename redis_6379.rdb
requirepass "123456"
masterauth "123456"
EOF

db01的配置:
cat >/opt/redis_26379/conf/redis_26379.conf << EOF
bind 10.0.0.51
port 26379
daemonize yes
logfile /opt/redis_26379/logs/redis_26379.log
dir /data/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
sentinel auth-pass mymaster 123456
EOF

db02的配置:
cat >/opt/redis_26379/conf/redis_26379.conf << EOF
bind 10.0.0.52
port 26379
daemonize yes
logfile /opt/redis_26379/logs/redis_26379.log
dir /data/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
sentinel auth-pass mymaster 123456
EOF

db03的配置:
cat >/opt/redis_26379/conf/redis_26379.conf << EOF
bind 10.0.0.53
port 26379
daemonize yes
logfile /opt/redis_26379/logs/redis_26379.log
dir /data/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
sentinel auth-pass mymaster 123456
EOF

停止redis進程
pkill redis

啟動單節(jié)點
redis-server /opt/redis_6379/conf/redis_6379.conf

配置主從復制
redis-cli -h 10.0.0.52 -p 6379 -a 123456 slaveof 10.0.0.51 6379

redis-cli -h 10.0.0.53 -p 6379 -a 123456 slaveof 10.0.0.51 6379

啟動哨兵
redis-sentinel /opt/redis_26379/conf/redis_26379.conf

Redis哨兵設置權重手動故障轉(zhuǎn)移

1.查看權重
CONFIG GET slave-priority

2.設置權重
在其他節(jié)點把權重設為0
CONFIG SET slave-priority 0

3.主動發(fā)起重新選舉
sentinel failover mymaster

4.恢復默認的權重
CONFIG SET slave-priority 100

CLUSTER MEET 10.0.0.51 6381
CLUSTER NODES
CLUSTER INFO
CLUSTER ADDSLOTS {0..5460}
CLUSTER REPLICATE 節(jié)點ID
CLUSTER FAILOVER

for i in {1..10000};do redis-cli -c -h 10.0.0.51 -p 6380 set {i}{i};echo "${i}";done

redis集群安裝部署

0.重要概念
每個槽分配到的key的概率足夠隨機,足夠平均
redis集群一共有16384個槽位
只要有一個槽不正常,整個集群不可用
平均分配到每個槽位的概率是大致一樣的
重要的是槽的數(shù)量,而不是連不連續(xù)

0.所有節(jié)點刪除前面實驗的數(shù)據(jù)
pkill redis
rm -rf /opt/redis_*
rm -rf /data/redis_*

1.目錄規(guī)劃
主節(jié)點 6380
從節(jié)點 6381

2.db01創(chuàng)建命令
pkill redis
rm -rf /opt/redis_*
rm -rf /data/redis_*
mkdir -p /opt/redis_{6380,6381}/{conf,logs,pid}
mkdir -p /data/redis_{6380,6381}
cat >/opt/redis_6380/conf/redis_6380.conf<<EOF
bind 10.0.0.51
port 6380
daemonize yes
pidfile "/opt/redis_6380/pid/redis_6380.pid"
logfile "/opt/redis_6380/logs/redis_6380.log"
dbfilename "redis_6380.rdb"
dir "/data/redis_6380/"
cluster-enabled yes
cluster-config-file nodes_6380.conf
cluster-node-timeout 15000
EOF
cd /opt/
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_638* db02:/opt/
rsync -avz /opt/redis_638* db03:/opt/
redis-server /opt/redis_6380/conf/redis_6380.conf
redis-server /opt/redis_6381/conf/redis_6381.conf
ps -ef|grep redis

3.db02操作命令
find /opt/redis_638* -type f -name "*.conf"|xargs sed -i "/bind/s#51#52#g"
mkdir –p /data/redis_{6380,6381}
redis-server /opt/redis_6380/conf/redis_6380.conf
redis-server /opt/redis_6381/conf/redis_6381.conf
ps -ef|grep redis

4.db03操作命令
find /opt/redis_638* -type f -name "*.conf"|xargs sed -i "/bind/s#51#53#g"
mkdir –p /data/redis_{6380,6381}
redis-server /opt/redis_6380/conf/redis_6380.conf
redis-server /opt/redis_6381/conf/redis_6381.conf
ps -ef|grep redis

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

redis-cli -h db01 -p 6380 CLUSTER MEET 10.0.0.51 6381
redis-cli -h db01 -p 6380 CLUSTER MEET 10.0.0.52 6380
redis-cli -h db01 -p 6380 CLUSTER MEET 10.0.0.52 6381
redis-cli -h db01 -p 6380 CLUSTER MEET 10.0.0.53 6380
redis-cli -h db01 -p 6380 CLUSTER MEET 10.0.0.53 6381
redis-cli -h db01 -p 6380 CLUSTER NODES
redis-cli -h db01 -p 6380 CLUSTER INFO

手動分配槽位

0.前提條件
無論集群有幾個節(jié)點,都平均分配16384個槽

1.槽位規(guī)劃
db01:6380 0-5460
db02:6380 5461-10921
db03:6380 10922-16383

2.分配槽位
redis-cli -h db01 -p 6380 CLUSTER ADDSLOTS {0..5460}
redis-cli -h db02 -p 6380 CLUSTER ADDSLOTS {5461..10922}
redis-cli -h db03 -p 6380 CLUSTER ADDSLOTS {10923..16383}
如果10922添加不了彻坛,進redis-cli -h db02 -p 6380
執(zhí)行CLUSTER ADDSLOTS 10922
3.查看集群狀態(tài)
redis-cli -h db01 -p 6380 CLUSTER info

手動部署復制關系

1.將集群節(jié)點信息保存在文本里,刪除不必要的信息,刪除81的信息
redis-cli -h 10.0.0.51 -p 6381 CLUSTER NODES
#db01的6380的ID 10.0.0.51:6380
#db02的6380的ID 10.0.0.52:6380
#db03的6380的ID 10.0.0.53:6380

2.操作其他節(jié)點
redis-cli -h 10.0.0.51 -p 6381 CLUSTER REPLICATE #db02的6380的ID
redis-cli -h 10.0.0.52 -p 6381 CLUSTER REPLICATE #db03的6380的ID
redis-cli -h 10.0.0.53 -p 6381 CLUSTER REPLICATE #db01的6380的ID

測試集群

1.嘗試插入一條數(shù)據(jù)發(fā)現(xiàn)報錯
10.0.1.51:6380> set k1 v1
(error) MOVED 12706 10.0.1.53:6380

2.目前的現(xiàn)象

  • 在db01的6380節(jié)點插入數(shù)據(jù)提示報錯
  • 報錯內(nèi)容提示應該移動到db03的6380上
  • 在db03的6380上執(zhí)行相同的插入命令可以插入成功
  • 在db01的6380節(jié)點插入數(shù)據(jù)有時候可以,有時候不行
  • 使用-c參數(shù)后,可以正常插入命令,并且節(jié)點切換到了提示的對應節(jié)點上

3.問題原因
因為集群模式又ASK路由規(guī)則,加入-c參數(shù)后,會自動跳轉(zhuǎn)到目標節(jié)點處理
并且最后由目標節(jié)點返回信息

4.測試足夠隨機足夠平均

 #!/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

使用工具搭建部署Redis Cluster

1.安裝依賴-只要在db01上操作
yum makecache fast
yum install rubygems -y
gem sources --remove https://rubygems.org/
gem sources -a http://mirrors.aliyun.com/rubygems/
gem update –system
gem install redis -v 3.3.5

2.還原環(huán)境-所有節(jié)點都執(zhí)行!!!
pkill redis
rm -rf /data/redis_6380/*
rm -rf /data/redis_6381/*

3.啟動集群節(jié)點-所有節(jié)點都執(zhí)行
redis-server /opt/redis_6380/conf/redis_6380.conf
redis-server /opt/redis_6381/conf/redis_6381.conf
ps -ef|grep redis

4.使用工具搭建部署Redis
cd /opt/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

5.檢查集群完整性
./redis-trib.rb check 10.0.0.51:6380

6.檢查集群負載是否合規(guī)
./redis-trib.rb rebalance 10.0.0.51:6380

使用工具擴容節(jié)點

1.創(chuàng)建新節(jié)點-db01操作
mkdir -p /opt/redis_{6390,6391}/{conf,logs,pid}
mkdir -p /data/redis_{6390,6391}
cd /opt/
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
redis-server /opt/redis_6390/conf/redis_6390.conf
redis-server /opt/redis_6391/conf/redis_6391.conf
ps -ef|grep redis
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
redis-cli -c -h db01 -p 6380 cluster nodes

2.使用工具擴容步驟
cd /opt/redis/src/
./redis-trib.rb reshard 10.0.0.51:6380

第一次交互:每個節(jié)點保留多少個槽位
How many slots do you want to move (from 1 to 16384)? 4096

第二次交互:接收節(jié)點的ID是什么
What is the receiving node ID? 6390的ID

第三次交互:哪個節(jié)點需要導出
Source node #1: all

第四次交互:確認是否執(zhí)行分配
Do you want to proceed with the proposed reshard plan (yes/no)? yes

3.檢查集群完整性
./redis-trib.rb check 10.0.0.51:6380

4.檢查集群負載是否合規(guī)
./redis-trib.rb rebalance 10.0.0.51:6380

5.調(diào)整復制順序
redis-cli -h 10.0.0.53 -p 6381 CLUSTER REPLICATE 51-6390的ID
redis-cli -h 10.0.0.51 -p 6391 CLUSTER REPLICATE 51-6380的ID

6.測試寫入腳本
[root@db01 ~]# cat for.sh

!/bin/bash

for i in (seq 1 100000) do redis-cli -c -h db01 -p 6380 set k_{i} v_{i} && echo "set k_{i} is ok"
done

7.測試讀腳本

[root@db03 ~]# cat du.sh

 #!/bin/bash 

 for i in $(seq 1 100000)
do
redis-cli -c -h db01 -p 6380 get k_${i}
sleep 0.1 
done

使用工具收縮節(jié)點

1.使用工具收縮節(jié)點
cd /opt/redis/src/
./redis-trib.rb reshard 10.0.0.51:6380

2.第一次交互: 要遷移多少個
How many slots do you want to move (from 1 to 16384)? 1365

3.第二次交互: 輸入第一個需要接收節(jié)點的ID
What is the receiving node ID? db01的6380的ID

4.第三次交互: 輸入需要導出的節(jié)點的ID
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
Source node #1: db01的6390的ID
Source node #2: done

5.第四次交互: 確認
Do you want to proceed with the proposed reshard plan (yes/no)? yes

6.繼續(xù)重復的操作,直到6390所有的槽位都分配給了其他主節(jié)點

7.確認集群狀態(tài)是否正常,確認6390槽位是否都遷移走了

8.忘記以及下線節(jié)點
./redis-trib.rb del-node 10.0.0.51:6390 baf9585a780d9f6e731972613a94b6f3e6d3fb5e
./redis-trib.rb del-node 10.0.0.51:6391 e54a79cca258eb76fb74fc12dafab5ebac26ed90
CLUSTER SETSLOT 941 STABLE 恢復槽位的欄桿
集群快速從做(沒有數(shù)據(jù)情況)
redis-cli -h 10.0.0.51 -p 6380 CLUSTER RESET
redis-cli -h 10.0.0.51 -p 6381 CLUSTER RESET
redis-cli -h 10.0.0.52 -p 6380 CLUSTER RESET
redis-cli -h 10.0.0.52 -p 6381 CLUSTER RESET
redis-cli -h 10.0.0.53 -p 6380 CLUSTER RESET
redis-cli -h 10.0.0.53 -p 6381 CLUSTER RESET

redis-cli -h 10.0.0.51 -p 6380 CLUSTER meet 10.0.0.51 6381
redis-cli -h 10.0.0.51 -p 6380 CLUSTER meet 10.0.0.52 6380
redis-cli -h 10.0.0.51 -p 6380 CLUSTER meet 10.0.0.52 6381
redis-cli -h 10.0.0.51 -p 6380 CLUSTER meet 10.0.0.53 6380
redis-cli -h 10.0.0.51 -p 6380 CLUSTER meet 10.0.0.53 6381
redis-cli -h 10.0.0.51 -p 6380 cluster nodes

redis-cli -h 10.0.0.51 -p 6380 cluster addslots {0..5460}
redis-cli -h 10.0.0.52 -p 6380 cluster addslots {5461..10922}
redis-cli -h 10.0.0.53 -p 6380 cluster addslots {10923..16383}
redis-cli -h 10.0.0.51 -p 6380 cluster info

數(shù)據(jù)遷移

1.安裝工具
yum install libtool autoconf automake -y
cd /opt/
git clone https://github.com/vipshop/redis-migrate-tool.git
cd redis-migrate-tool/
autoreconf -fvi
./configure
make && make install

2.編寫配置文件
cat > 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
EOF

3.單節(jié)點生成測試數(shù)據(jù)
mkdir -p /data/redis_6379
mkdir -p /opt/redis_6379/{conf,pid,logs}
cat >/opt/redis_6379/conf/redis_6379.conf <<EOF
daemonize yes
bind 10.0.0.51 127.0.0.1
port 6379
pidfile /opt/redis_6379/pid/redis_6379.pid
logfile /opt/redis_6379/logs/redis_6379.log
databases 16
dir /data/redis_6379
dbfilename redis_6379.rdb
EOF
redis-server /opt/redis_6379/conf/redis_6379.conf

cat >input_6379.sh <<EOF

!/bin/bash

for i in {1..1000}
do
redis-cli -c -h db01 -p 6379 set oldzhang_${i} oldzhang_${i}
echo "set oldzhang_${i} is ok"
done
EOF

4.運行工具遷移單節(jié)點數(shù)據(jù)到集群
redis-migrate-tool -c 6379_to_6380.conf

5.運行工具驗證數(shù)據(jù)是否遷移完成
redis-migrate-tool -c 6379_to_6380.conf
redis-migrate-tool -c 6379_to_6380.conf -C redis_check

第七章 RDB文件遷移到集群

1.先把集群的RDB文件都收集起來

  • 在從節(jié)點上執(zhí)行bgsave命令生成RDB文件
    redis-cli -h db01 -p 6381 BGSAVE
    redis-cli -h db02 -p 6381 BGSAVE
    redis-cli -h db03 -p 6381 BGSAVE

2.把從節(jié)點生成的RDB文件拉取過來
mkdir rdb_backup
cd rdb_backup/
scp db01:/data/redis_6381/redis_6381.rdb db01_6381.rdb
scp db02:/data/redis_6381/redis_6381.rdb db02_6381.rdb
scp db03:/data/redis_6381/redis_6381.rdb db03_6381.rdb

3.清空所有節(jié)點的數(shù)據(jù)
redis-cli -h db01 -p 6380 FLUSHALL
redis-cli -h db02 -p 6380 FLUSHALL
redis-cli -h db03 -p 6380 FLUSHALL

4.編寫配置文件
cat >rdb_to_cluter.conf<<EOF
[source]
type: rdb file
servers:

  • /root/rdb_backup/db01_6381.rdb
  • /root/rdb_backup/db02_6381.rdb
  • /root/rdb_backup/db03_6381.rdb

[target]
type: redis cluster
servers:

  • 10.0.0.51:6380

[common]
listen: 0.0.0.0:8888
source_safe: true
EOF

8.使用工具導入
redis-migrate-tool -c rdb_to_cluter.conf

使用工具分析key的大小

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

1.安裝命令:
yum install python-pip gcc python-devel -y
cd /opt/
git clone https://github.com/sripathikrishnan/redis-rdb-tools
cd redis-rdb-tools
pip install python-lzf
python setup.py install

2.生成測試數(shù)據(jù):
redis-cli -h db01 -p 6379 set txt $(cat txt.txt)

3.執(zhí)行bgsave生成rdb文件
redis-cli -h db01 -p 6379 BGSAVE

3.使用工具分析:
cd /data/redis_6379/
rdb -c memory redis_6379.rdb -f redis_6379.rdb.csv

4.過濾分析
awk -F"," '{print 4,3}' redis_6379.rdb.csv |sort -r

5.將結果整理匯報給領導,詢問開發(fā)這個key是否可以刪除

生產(chǎn)注意:

1.一定要限制內(nèi)存最大使用
maxmemory <bytes>

2.限制內(nèi)存多少
redis本身使用了5G 系統(tǒng)內(nèi)存為32G
10G用滿后 分析一下鍵值大小
16G用滿后 分析一下鍵值大小
最多給到24G 剩下的內(nèi)存給系統(tǒng)和持久化時候用
24G用滿后

maxmemory-policy noeviction

3.硬盤用SSD

4.集群注意
數(shù)據(jù)遷移或者主從關系發(fā)生改變,盡量在業(yè)務低峰期操作
一定要等集群狀態(tài)穩(wěn)定之后,在操作下一步

5.集群下線節(jié)點
先下線從節(jié)點,在下線主節(jié)點

6.禁止使用keys *
替代方案使用scan

7.故障轉(zhuǎn)移時間不要調(diào)太短

8.RDB持久化可以在從節(jié)點上操作

9.如果同時需要RDB和AOF
掛載2塊SSD
通過配置,AOF和RDB保存在不同的磁盤上

10.redis的機器上不要跑其他的服務,專機專用

11.網(wǎng)卡要快

12.監(jiān)控要跟上

13.不要使用swap分區(qū)

故障案例

問題背景:
使用工具執(zhí)行槽位遷移的時候,遷移過程中中斷了

問題現(xiàn)象:

1.使用工具check的時候提示941槽的狀態(tài)為import導入狀態(tài)
[ERR] Nodes don't agree about c onfigu ration !
5P Check for open sLots
[WARNING] Node 10.0.0.51:6390 has slots in inporting state (941).

2.登錄到不同節(jié)點查看集群節(jié)點信息發(fā)現(xiàn)不同的節(jié)點,顯示的槽位不一樣
6390顯示 941 槽在 6380身上
6380顯示 941 槽在 6390身上

3.登錄到6380上查看槽位顯示一切正常
登錄到6390顯示槽位不正常,有一個導入的符號941<節(jié)點ID
941<節(jié)點ID

排查步驟:
1.使用工具fix,行不通,報錯
2.登錄到有問題的節(jié)點6390身上,執(zhí)行恢復槽位狀態(tài)的命令,執(zhí)行完之后,槽位狀態(tài)顯示正常
CLUSTER SETSLOT 941 STABLE
3.再次嘗試使用fix,還是行不通,依然報錯
4.嘗試登陸6390,刪除941槽位
CLUSTER DELSLOTS 941
5.再次嘗試使用fix,還是行不通,依然報錯
6.嘗試登陸6380,刪除941槽位
7.再次嘗試使用fix,不報錯了
8.嘗試使用check,不報錯
9.重新分配槽位


QQ圖片20191203152748.png
槽位.png
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末覆醇,一起剝皮案震驚了整個濱河市玛痊,隨后出現(xiàn)的幾起案子赴恨,更是在濱河造成了極大的恐慌商玫,老刑警劉巖箕憾,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異拳昌,居然都是意外死亡袭异,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門炬藤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來御铃,“玉大人碴里,你說我怎么就攤上這事〕┞颍” “怎么了并闲?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長谷羞。 經(jīng)常有香客問我帝火,道長,這世上最難降的妖魔是什么湃缎? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任犀填,我火速辦了婚禮,結果婚禮上嗓违,老公的妹妹穿的比我還像新娘九巡。我一直安慰自己,他們只是感情好蹂季,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布冕广。 她就那樣靜靜地躺著,像睡著了一般偿洁。 火紅的嫁衣襯著肌膚如雪撒汉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天涕滋,我揣著相機與錄音睬辐,去河邊找鬼。 笑死宾肺,一個胖子當著我的面吹牛溯饵,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播锨用,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼丰刊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了增拥?” 一聲冷哼從身側響起藻三,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎跪者,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體熄求,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡渣玲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了弟晚。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片忘衍。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡逾苫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出枚钓,到底是詐尸還是另有隱情铅搓,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布搀捷,位于F島的核電站星掰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏嫩舟。R本人自食惡果不足惜氢烘,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望家厌。 院中可真熱鬧播玖,春花似錦、人聲如沸饭于。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽掰吕。三九已至果覆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間畴栖,已是汗流浹背随静。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留吗讶,地道東北人燎猛。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像照皆,于是被迫代替她去往敵國和親重绷。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348

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

  • Redis Sentinel 介紹與部署 1. Sentinel介紹 1.1 主從復制的問題 Redis主從復制可...
    56c60a7e3495閱讀 1,008評論 0 1
  • 0. NoSQL 產(chǎn)品(key-value) 1膜毁、Redis功能介紹 2昭卓、企業(yè)緩存產(chǎn)品介紹 3、Redis使用場景...
    極光01閱讀 322評論 0 0
  • 架構 OS:Centos6.8 Redis01:172.17.100.130(sentinel-1瘟滨,sentine...
    飛翔的Tallgeese閱讀 623評論 0 2
  • 本文將要介紹的哨兵候醒,它基于 Redis 主從復制,主要作用便是解決主節(jié)點故障恢復的自動化問題杂瘸,進一步提高系統(tǒng)的高可...
    java成功之路閱讀 2,201評論 0 4
  • 我倒淫,作為園藝界資深殺手,雖然對每片肉肉都照顧有加败玉,然而還是培育死了n多可愛的肉肉敌土,再也不忍買肉肉來養(yǎng)了镜硕。于是開始畫...
    黎璃曉閱讀 357評論 0 2