redis学习

第一章 关系型和非关系型

关系型: MySQL Oracle

非关系型: Redis MongoDB Elasticsearch

第二章 Redis重要特性

1.速度快:C语言编写,代码简洁,单线程架构

2.支持多种数据结构:字符串,哈希,列表,集合,有序集合

3.丰富的功能:天然计数器,键过期功能,消息队列

4.支持客户端语言多:PHP,Java,go,Python

5.支持数据持久化:所有在运行的数据都是放在内存中,支持多种数据持久化格式,RDB,AOF,混合持久化

6.自带多种高可用架构:主从,哨兵,集群

第三章 Redis应用场景

1.缓存-键过期:把session数据存在Redis里,过期删除。 缓存用户信息,缓存MySQL部分的数据,用户先访问Redis,如果Redis没命中,再访问MySQL,然后回写给Redis。商城优惠价过期。短信验证码过期。

2.排行榜-列表&有序集合:热度/点击量。直播间礼物打赏排行榜。

3.计数器-天然计数器:帖子浏览数,视频播放次数,评论次数,点赞/踩。

4.社交网络-集合:粉丝,共同好友/可能认识的人,兴趣爱好/标签。

5.消息队列:elk缓存日志,聊天记录等。

第四章 Redis的安装部署

1.Redis官网下载地址

https://redis.io/download

2.版本选择

2.x 非常老
3.x 主流 redis-cluster
4.x 支持混合持久化
5.x 最新稳定版 新增了流处理类型

3.规划目录

/data/soft                       下载目录
/opt/redis_6379/{conf,logs,pid}  安装目录,日志目录,pid目录,配置目录
/data/redis_6379                 数据目录

4.安装命令

[root@redis01 ~]# mkdir /data/soft -p
[root@redis01 ~]# cd /data/soft/
[root@redis01 soft]# wget http://download.redis.io/releases/redis-5.0.7.tar.gz
[root@redis01 soft]# tar zxf redis-5.0.7.tar.gz -C /opt/
[root@redis01 soft]# cd /opt/
[root@redis01 opt]# ln -s redis-5.0.7/ redis
[root@redis01 opt]# cd redis
[root@redis01 redis]# make
[root@redis01 redis]# make install

5.编写配置文件

[root@redis01 redis]# mkdir -p /opt/redis_6379/{conf,logs,pid}
[root@redis01 redis]# mkdir -p /data/redis_6379
[root@redis01 redis]# cat >/opt/redis_6379/conf/redis_6379.conf<<EOF
daemonize yes
bind 127.0.0.1 10.0.0.51
port 6379
pidfile /opt/redis_6379/pid/redis_6379.pid
logfile /opt/redis_6379/logs/redis_6379.log
EOF

6.启动命令

[root@redis01 redis]# redis-server /opt/redis_6379/conf/redis_6379.conf

7.检查

[root@redis01 redis]# ps -ef|grep redis
root      11742      1  0 19:05 ?        00:00:00 redis-server 127.0.0.1:6379

[root@redis01 redis]# netstat -lntup|grep redis
tcp        0      0 10.0.0.51:6379          0.0.0.0:*               LISTEN      11742/redis-server  
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      11742/redis-server

8.连接测试Redis

[root@redis01 redis]# redis-cli
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> get k1
"v1"

9.关闭命令

第一种
[root@redis01 redis]# redis-cli
127.0.0.1:6379> SHUTDOWN

第二种
[root@redis01 redis]# redis-cli shutdown

第三种
[root@redis01 redis]# kill
[root@redis01 redis]# pkill

10.system启动配置

[root@redis01 redis]# groupadd redis -g 1000
[root@redis01 redis]# useradd redis -u1000 -g1000 -M -s /sbin/nologin
[root@redis01 redis]# chown -R redis. /opt/redis*
[root@redis01 redis]# chown -R redis. /data/redis*
[root@redis01 redis]# cat >/usr/lib/systemd/system/redis.service<<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/redis-server /opt/redis_6379/conf/redis_6379.conf --supervised systemd
ExecStop=/usr/local/bin/redis-cli shutdown
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
[root@redis01 redis]# systemctl daemon-reload
[root@redis01 redis]# systemctl start redis

第5章 Redis全局命令

1.Redis数据格式

key:value
 键:值

2.写入测试命令

[root@redis01 redis]# redis-cli
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> set k3 v3
OK

3.查看所有key 注意!!!线上生产禁止执行keys *

127.0.0.1:6379> keys *
1) "k2"
2) "k1"
3) "k3"

4.查看有多少个key

127.0.0.1:6379> DBSIZE
(integer) 3

5.查看某个key是否存在

127.0.0.1:6379> EXISTS k5
(integer) 0
127.0.0.1:6379> EXISTS k1
(integer) 1

状态码:
0:表示这个key不存在
1:表示这个key存在
N:表示有N个key存在

6.删除key

127.0.0.1:6379> DEL k1
(integer) 1
127.0.0.1:6379> DEL k1 k2
(integer) 1

状态码:
0:要删除的key不存在
1:表示这个key存在,并且删除成功了
N:表示N个key存在,并且被删除成功了

7.键过期

设置键过期时间
127.0.0.1:6379> EXPIRE k1 10
(integer) 0
127.0.0.1:6379> EXPIRE k3 10
(integer) 1

状态码:
0:表示这个key不存在
1: 表示这个key存在,并且设置过期时间成功
查看key是否过期
127.0.0.1:6379> TTL k1
(integer) 94

状态码:
-1:这个key存在,没有设置过期时间,永不过期
-2:这个key不存在
N:表示这个key存在,还有N秒过期
取消过期时间
第一种方法
127.0.0.1:6379> set k1 v1

第二种方法
127.0.0.1:6379> PERSIST k1

第6章 字符串操作

1.设置一个key

127.0.0.1:6379> set k1 v1
127.0.0.1:6379> set k1 v1 EX 10 #设置一个值为v1的k1键 过期时间10秒

2.查看一个key

127.0.0.1:6379> get k1

3.设置多个key

127.0.0.1:6379> MSET k1 v1 k2 v2 k3 v3
OK

4.查看多个key

127.0.0.1:6379> MGET k1 k2 k3
1) "v1"
2) "v2"
3) "v3"

5.天然计数器

加1:
127.0.0.1:6379> Set k1 1
OK
127.0.0.1:6379> INCR k1
(integer) 2
127.0.0.1:6379> GET k1
"2"

加N:
127.0.0.1:6379> INCRBY k1 100
(integer) 102

减1:
127.0.0.1:6379> INCRBY k1 -1
(integer) 101

减N:
127.0.0.1:6379> INCRBY k1 -50
(integer) 51

故障案例

问题背景:
某⽇,突然在公司办公室集体访问不了公司⽹站了,访问其他⽹站都正常,⽤⼿机流量访问公司⽹站
却正常

排查过程:
笔记本⽤⼿机流量热点,连上了IDC机房的VPN服务器,连上反向代理负载均衡查看,发现公司出⼝
IP地址被防⽕墙封掉了。

紧急恢复:
先放开规则,恢复访问。再排查问题

排查步骤:
为什么办公室会被封?
防⽕墙上做了限制访问次数,如果访问超过1分钟200次,就⾃动封掉这个IP,24⼩时后再放开。

内⽹是谁在⼤量访问呢?
通过路由器查看那个交换机流量⼤
通过交换机确认哪个端⼝的流量异常
拔掉⽹线,然后等待尖叫声

问题真正原因:
供应商软⽂有指标,需要把热度炒起来,所以同事⽤浏览器⾃动刷新⽹⻚的插件不断的刷新⽹⻚。
从⽽触发了防⽕墙的限制,⼜因为防⽕墙没有设置⽩名单,所以导致整个办公室唯⼀的出⼝IP被封
掉。

解决⽅案:
开发在后台添加新功能,输⼊帖⼦ID和期望的访问数,操作Redis字符串的计数器功能⾃动添加访问
量
防⽕墙设置⽩名单,放开公司办公室出⼝IP

第7章 列表操作

1.插入列表

从左边压⼊数据:
127.0.0.1:6379> LPUSH list1 A
(integer) 1

从右边压⼊数据:
127.0.0.1:6379> RPUSH list1 D
(integer) 2

2.查看列表长度

127.0.0.1:6379>  LLEN list1
(integer) 2

3.查看列表内容

127.0.0.1:6379> LRANGE list1 0 -1
1) "A"
2) "D"

4.删除列表元素

127.0.0.1:6379> RPOP list1
"D"

127.0.0.1:6379> LPOP list1
"A"

5.删除整个列表

127.0.0.1:6379> DEL list1

第8章 HASH操作

1.mysql数据格式如何缓存到redis

mysql数据格式:
user表
id  name   job  age
1   boss   it   18
2   wei    it   24
3   cookz  it   30

hash类型存储格式:
key field1 value field2 value field3 value
user:1 name boss job it age 18
user:2 name wei job it age 18
user:3 name cookz job it age 18

2.创建⼀个HASH数据

HMSET user:1 name boss job it age 18
HMSET user:2 name wei job it age 24
HMSET user:3 name cooz job it age 30

3.查看hash⾥的指定字段的值

127.0.0.1:6379> HMGET user:1 name
1) "boss"

127.0.0.1:6379> HMGET user:1 name job age
1) "boss"
2) "it"
3) "18"

4.查看hash⾥的所有字段的值

127.0.0.1:6379> HGETALL user:1
1) "name"
2) "boss"
3) "job"
4) "it"
5) "age"
6) "18"

第9章 集合操作

1.创建集合

127.0.0.1:6379> SADD set1 1 2 3
(integer) 3

127.0.0.1:6379> SADD set2 1 3 5 7
(integer) 4

2.查看集合成员

127.0.0.1:6379> SMEMBERS set1
1) "1"
2) "2"
3) "3"

4.查看集合的差集

127.0.0.1:6379> SMEMBERS set1
1) "1"
2) "2"
3) "3"

127.0.0.1:6379> SMEMBERS set2
1) "1"
2) "3"
3) "5"
4) "7"

127.0.0.1:6379> SDIFF set1 set2
1) "2"

127.0.0.1:6379> SDIFF set2 set1
1) "5"
2) "7"

5.查看集合的并集

127.0.0.1:6379> SUNION set1 set2
1) "1"
2) "2"
3) "3"
4) "5"
5) "7"

第10章 有序集合

1.添加有序集合

127.0.0.1:6379> ZADD bj67 100 wei
(integer) 1

127.0.0.1:6379> ZADD bj67 10 cookzhang
(integer) 1

127.0.0.1:6379> ZADD bj67 99 jun
(integer) 1

2.计算成员个数

127.0.0.1:6379> ZCARD bj67
(integer) 3

3.计算某个成员分数

127.0.0.1:6379> ZSCORE bj67 wei
"100"

4.按照升序查看成员名次

127.0.0.1:6379> ZRANK bj67 cookzhang
(integer) 0

5.按照降序查看成员名次

127.0.0.1:6379> ZREVRANK bj67 cookzhang
(integer) 2

6.删除成员

127.0.0.1:6379> ZREM bj67 cookzhang
(integer) 1

7.返回指定排名范围的成员

127.0.0.1:6379>  ZRANGE bj67 0 -1
1) "jun"
2) "wei"

127.0.0.1:6379>  ZRANGE bj67 0 -1 WITHSCORES
1) "jun"
2) "99"
3) "wei"
4) "100"

127.0.0.1:6379> ZRANGE bj67 1 3
1) "wei"

8.返回指定分数范围的成员

127.0.0.1:6379> ZRANGEBYSCORE bj67 50 100
1) "jun"
2) "wei"

127.0.0.1:6379> ZRANGEBYSCORE bj67 50 100 WITHSCORES
1) "jun"
2) "99"
3) "wei"
4) "100"

9.增加成员分数

127.0.0.1:6379> ZINCRBY bj67 50 wei
"150"

第11章 持久化

1.RDB持久化和AOF持久化

RDB: 类似于快照,当前内存⾥的数据的状态持久化到硬盘
优点:压缩格式/恢复速度快
缺点:不是实时的,可能会丢数据,操作⽐较重量

AOF:类似于mysql的binlog,可以设置成每秒/每次操作都以追加的形式保存在⽇志⽂件中
优点:安全,最多只损失1秒的数据,具备⼀定的可读性
缺点:⽂件⽐较⼤,恢复速度慢

2.配置RDB持久化

save 900 1
save 300 10
save 60 10000
dbfilename redis.rdb
dir /data/redis_6379/

[root@redis01 redis]# cat  /opt/redis_6379/conf/redis_6379.conf 
daemonize yes
bind 127.0.0.1 10.0.0.51
port 6379
pidfile /opt/redis_6379/pid/redis_6379.pid
logfile /opt/redis_6379/logs/redis_6379.log

save 900 1
save 300 10
save 60 10000
dbfilename redis.rdb
dir /data/redis_6379/

[root@redis01 redis]# systemctl restart redis

3.RDB持久化结论:

没配置save参数时:
1.shutdown/pkill/kill都不会持久化保存
2.可以⼿动执⾏bgsave

配置save参数时:
1.shutdown/pkill/kill均会⾃动触发bgsave持久化保存数据
2.pkill -9 不会触发持久化

恢复时:
1.持久化数据⽂件名要和配置⽂件⾥定义的⼀样才能被识别
2.RDB⽂件只有⼀个数据⽂件,迁移和备份只要这⼀个RDB⽂件即可

注意:
RDB⾼版本兼容低版本,低版本不能兼容⾼版本
3.x >> 5.X >> OK
5.x >> 3.x >> NoOK

4.AOF持久化配置

appendonly yes
appendfilename "redis.aof"
appendfsync everysec

[root@redis01 redis]# cat /opt/redis_6379/conf/redis_6379.conf 
daemonize yes
bind 127.0.0.1 10.0.0.51
port 6379
pidfile /opt/redis_6379/pid/redis_6379.pid
logfile /opt/redis_6379/logs/redis_6379.log

save 900 1
save 300 10
save 60 10000

appendonly yes
appendfilename "redis.aof"
appendfsync everysec

dbfilename redis.rdb
dir /data/redis_6379/

[root@redis01 redis]# systemctl restart redis

5.AOF重写机制

执⾏的命令      aof记录         redis⾥的数据
set k1 v1     set k1            k1
set k2 v2     set k1            k1 k2
              set k2
              
set k3 v3     set k1            k1 k2 k3
              set k2
              set k3
              
del k1        set k1            k2 k3
              set k2
              set k3
              del k1
              
del k2        set k1            k3
              set k2
              set k3
              del k1
              del k2
              
aof⽂件⾥实际有意义的只有⼀条记录:
set k3

6.AOF和RDB读取实验

实验背景:aof和rdb同时存在,redis重启会读取哪⼀个数据?

实验步骤:
set k1 v1
set k2 v2
bgsave rbd保存 k1 k2
mv redis.rdb /opt/
flushall
set k3 v3
set k4 v4 aof保存 k3 k4
mv redis.aof /opt/
redis-cli shutdown
rm -rf /data/redis_6379/*
mv /opt/redis.aof /data/redis_6379/
mv /opt/redis.rdb /data/redis_6379/

systemctl start redis

实验结论:当aof和rdb同时存在的时候,redis会优先读取aof的内容

7.AOF模拟故障

损坏实验结论:

1.aof修复命令不要⽤,因为他的修复⽅案⾮常粗暴,⼀⼑切,从出错的地⽅到最后全部删除
2.任何操作之前,先备份数据

kill -9 实验:

for i in {1..10000};do redis-cli set key_${i} v_${i} && echo "${i} is
ok";done

ps -ef|grep redis|grep -v grep|awk '{print "kill -9",$2}'

结论:

aof相对⽐较安全,最多丢失1秒数据

8.如果设置了过期时间,恢复数据后会如何处理?

1.aof⽂件会记录下过期时间
2.恢复的时候会去对⽐过期时间和当前时间,如果超过了,就删除key
3.key的过期时间不受备份影响

9.AOF和RDB如何选择

https://redis.io/topics/persistence
1.开启混合模式
2.开启aof
3.不开启rdb
4.rdb采⽤定时任务的⽅式定时备份
5.可以从库开启RDB进⾏备份

第12章 redis⽤户验证

1.配置密码认证功能

requirepass 123456

2.使⽤密码

第一种:
[root@redis01 redis]# redis-cli
127.0.0.1:6379> set k1 v1
(error) NOAUTH Authentication required.
127.0.0.1:6379> AUTH 123456
OK
127.0.0.1:6379> keys *
1) "k1"

第二种:
[root@redis01 redis]# redis-cli -a '123456' get k1
Warning: Using a password with '-a' or '-u' option on the command line
interface may not be safe.
"v1"

3.为什么redis的密码认证这么简单?

1.redis⼀般都部署在内⽹环境,默认是相对⽐较安全的

2.有人担⼼密码写在配置⽂件⾥,不⽤担⼼,因为开发不允许SSH登陆到Linux服务器,但是可以远
程连接Redis,所以设置密码还是有作⽤的

第13章 禁⽤或重命名危险命令

1.禁⽤危险命令

rename-command KEYS ""
rename-command SHUTDOWN ""
rename-command CONFIG ""
rename-command FLUSHALL ""

2.重命名危险命令

rename-command KEYS "QQ632368167"
rename-command SHUTDOWN ""
rename-command CONFIG ""
rename-command FLUSHALL ""

第14章 主从复制

1.快速部署第⼆台Redis服务器

[root@redis02 ~]# rsync -avz 10.0.0.51:/opt/redis* /opt/
[root@redis02 ~]# rsync -avz 10.0.0.51:/usr/local/bin/redis* /usr/local/bin/
[root@redis02 ~]# rsync -avz 10.0.0.51:/usr/lib/systemd/system/redis.service /usr/lib/systemd/system/
[root@redis02 ~]# sed -i 's#51#52#g' /opt/redis_6379/conf/redis_6379.conf
[root@redis02 ~]# mkdir -p /data/redis_6379
[root@redis02 ~]# groupadd redis -g 1000
[root@redis02 ~]# useradd redis -u 1000 -g 1000 -M -s /sbin/nologin
[root@redis02 ~]# chown -R redis:redis /opt/redis*
[root@redis02 ~]# chown -R redis:redis /data/redis*
[root@redis02 ~]# systemctl daemon-reload
[root@redis02 ~]# systemctl start redis

报错总结:

1.在db01上执⾏了命令
2.配置⽂件⾥的密码没删掉
3.配置⽂件⾥的重命名参数没删掉
4.⽤户id和组id冲突
5.没有rsync
6.拷⻉过来的配置⽂件没有修改IP地址

2.db01插⼊测试命令

[root@redis01 redis]# for i in {1..1000};do redis-cli set key_${i} v_${i} && echo "${i} is ok";done

3.配置主从复制

⽅法1:临时⽣效

[root@redis01 redis]# redis-cli -h 10.0.0.52 SLAVEOF 10.0.0.51 6379
OK

⽅法2:写进配置⽂件永久⽣效

SLAVEOF 10.0.0.51 6379

查看主从状态

[root@redis01 redis]# redis-cli
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.0.52,port=6379,state=online,offset=308,lag=0
master_replid:9e515a351ed85a02e000cc2a7de9e105349e5239
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:308
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:308
127.0.0.1:6379>

4.主从复制流程

1.从节点发送同步请求到主节点
2.主节点接收到从节点的请求之后,做了如下操作
 - ⽴即执⾏bgsave将当前内存⾥的数据持久化到磁盘上
 - 持久化完成之后,将rdb⽂件发送给从节点
3.从节点从主节点接收到rdb⽂件之后,做了如下操作
 - 清空⾃⼰的数据
 - 载⼊从主节点接收的rdb⽂件到⾃⼰的内存⾥
4.后⾯的操作就是和主节点实时的了

5.取消复制

127.0.0.1:6379> SLAVEOF no one

6.主从复制注意

1.从节点只读不可写
2.从节点不会⾃动故障转移,他会⼀直尝试同步主节点,并且依然不可写
3.主从复制故障转移需要介⼊的地⽅
 - 修改代码指向新主的IP
 - 从节点需要执⾏slaveof no one
4.从库建⽴同步时会清空⾃⼰的数据,如果同步对象写错了,就清空了
5.从库也可以正常的RDB持久化

7.安全的操作

⼀定要做好数据备份,⽆论是主节点还是从节点,操作前最好做下备份

第15章 Redis Sentinel(哨兵)

1.哨兵的作⽤

1.解决主从复制需要⼈为⼲预的问题
2.提供了⾃动的⾼可⽤⽅案

2.⽬录和端⼝规划

redis节点 6379
哨兵节点 26379

3.部署3台redis单节点主从关系

redis01操作

pkill redis

cat >/opt/redis_6379/conf/redis_6379.conf <<EOF
daemonize yes
bind 127.0.0.1 10.0.0.51
port 6379
pidfile "/opt/redis_6379/pid/redis_6379.pid"
logfile "/opt/redis_6379/logs/redis_6379.log"
dbfilename "redis.rdb"
dir "/data/redis_6379"
appendonly yes
appendfilename "redis.aof"
appendfsync everysec
EOF

systemctl start redis
redis-cli

redis02和redis03操作

ssh-keygen
ssh-copy-id 10.0.0.51
pkill redis
rm -rf /opt/redis*
rsync -avz 10.0.0.51:/usr/local/bin/redis-* /usr/local/bin
rsync -avz 10.0.0.51:/usr/lib/systemd/system/redis.service
/usr/lib/systemd/system/
mkdir /opt/redis_6379/{conf,logs,pid} -p
mkdir /data/redis_6379 -p

cat >/opt/redis_6379/conf/redis_6379.conf <<EOF
daemonize yes
bind 127.0.0.1 $(ifconfig eth0|awk 'NR==2{print $2}')
port 6379
pidfile "/opt/redis_6379/pid/redis_6379.pid"
logfile "/opt/redis_6379/logs/redis_6379.log"
dbfilename "redis.rdb"
dir "/data/redis_6379"
appendonly yes
appendfilename "redis.aof"
appendfsync everysec
EOF

useradd redis -M -s /sbin/nologin
chown -R redis:redis /opt/redis*
chown -R redis:redis /data/redis*
systemctl daemon-reload
systemctl start redis
redis-cli

4.配置主从复制

redis-cli -h 10.0.0.52 slaveof 10.0.0.51 6379
redis-cli -h 10.0.0.53 slaveof 10.0.0.51 6379
redis-cli -h 10.0.0.51 info replication

5.部署哨兵节点-3台机器都操作

mkdir -p /data/redis_26379
mkdir -p /opt/redis_26379/{conf,pid,logs}

cat >/opt/redis_26379/conf/redis_26379.conf << EOF
bind $(ifconfig eth0|awk 'NR==2{print $2}')
port 26379
daemonize yes
logfile /opt/redis_26379/logs/redis_26379.log
dir /data/redis_26379
sentinel monitor myredis 10.0.0.51 6379 2
sentinel down-after-milliseconds myredis 3000
sentinel parallel-syncs myredis 1
sentinel failover-timeout myredis 18000
EOF

chown -R redis:redis /data/redis*
chown -R redis:redis /opt/redis*

cat >/usr/lib/systemd/system/redis-sentinel.service<<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/redis-sentinel
/opt/redis_26379/conf/redis_26379.conf --supervised systemd
ExecStop=/usr/local/bin/redis-cli -h $(ifconfig eth0|awk 'NR==2{print
$2}') -p 26379 shutdown
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl start redis-sentinel
redis-cli -h 10.0.0.51 -p 26379

关键配置解释:

sentinel monitor myredis 10.0.0.51 6379 2
# myredis主节点别名 主节点IP 端⼝ 需要2个哨兵节点同意

sentinel down-after-milliseconds myredis 3000
# 认定服务器已经断线所需要的毫秒数

sentinel parallel-syncs myredis 1
#向主节点发给复制操作的从节点个数,1表示轮训发起复制

sentinel failover-timeout myredis 18000
#故障转移超时时间

6.哨兵注意

1.哨兵发起故障转移的条件是master节点失去联系,从节点挂掉不会发起故障转移
2.哨兵会⾃⼰维护配置⽂件,不需要⼿动修改
3.如果主从的结构发⽣变化,哨兵之间会⾃动同步最新的消息并且⾃动更新配置⽂件
4.哨兵启动完成之后,不要再⾃⼰去设置主从关系

7.验证主机点

redis-cli -h 10.0.0.51 -p 26379 SENTINEL get-master-addr-by-name myredis

8.哨兵的常⽤命令

redis-cli -h 10.0.0.51 -p 26379 SENTINEL get-master-addr-by-name myredis
redis-cli -h 10.0.0.51 -p 26379 SENTINEL master myredis
redis-cli -h 10.0.0.51 -p 26379 SENTINEL slaves myredis
redis-cli -h 10.0.0.51 -p 26379 SENTINEL ckquorum myredis

9.模拟故障转移

模拟⽅法:

关闭redis当前的主节点
观察其他2个节点会不会发⽣选举
查看哨兵配置⽂件会不会更新
查看从节点配置⽂件会不会更新
查看主节点能不能写⼊
查看从节点是否同步正常

流程:

1)在从节点列表中选出⼀个节点作为新的主节点,选择⽅法如下:
a)过滤:“不健康”(主观下线、断线)、5秒内没有回复过Sentinel节
点ping响应、与主节点失联超过down-after-milliseconds*10秒。
b)选择slave-priority(从节点优先级)最⾼的从节点列表,如果存在则
返回,不存在则继续。
c)选择复制偏移量最⼤的从节点(复制的最完整),如果存在则返
回,不存在则继续。
d)选择runid最⼩的从节点

结论:

主节点挂掉,哨兵会选举新的主节点
在新主节点上执⾏slaveof no one
在从节点执⾏slave of 新主节点
⾃动更新哨兵配置
⾃动更新从节点配置

10.故障修复重新上线

启动单节点
检查是否变成从库

11.哨兵加权选举

查看权重

redis-cli -h 10.0.0.51 -p 6379 CONFIG GET slave-priority
redis-cli -h 10.0.0.52 -p 6379 CONFIG GET slave-priority
redis-cli -h 10.0.0.53 -p 6379 CONFIG GET slave-priority

暗箱操作:假如选中53作为最新的master

redis-cli -h 10.0.0.51 -p 6379 CONFIG SET slave-priority 0
redis-cli -h 10.0.0.52 -p 6379 CONFIG SET slave-priority 0

检查:

redis-cli -h 10.0.0.51 -p 6379 CONFIG GET slave-priority
redis-cli -h 10.0.0.52 -p 6379 CONFIG GET slave-priority
redis-cli -h 10.0.0.51 -p 26379 sentinel get-master-addr-by-name myredis

主动发⽣选举

redis-cli -h 10.0.0.51 -p 26379 sentinel failover myredis
redis-cli -h 10.0.0.51 -p 26379 sentinel get-master-addr-by-name myredi

第16章 Redis集群-最新版5.x

1.哨兵的不⾜

1.主库写压⼒太⼤
2.资源利⽤率不⾼
3.连接过程繁琐,效率低

2.集群的重要概念

1.Redis集群,⽆论有⼏个节点,⼀共只有16384个槽位
2.所有的槽都必须被正确分配,哪怕有1个槽不正常,整个集群都不可⽤
3.每个节点的槽的顺序不重要,重要的是槽的数量
4.HASH算法⾜够平均,⾜够随机
5.每个槽被分配到数据的概率是⼤致相当的
6.集群的⾼可⽤依赖于主从复制
7.集群节点之间槽位的数量允许在2%的误差范围内
8.集群通讯会使⽤基础端⼝号+10000的端⼝,⾃动创建的,不是配置⽂件配置的,⽣产要注意的是防
⽕墙注意要放开此端⼝

3.⽬录规划

主节点 6380
从节点 6381

4.redis01的操作

#1.发送SSH认证,⽅便后⾯传输
ssh-keygen
ssh-copy-id 10.0.0.52
ssh-copy-id 10.0.0.53

#2.创建⽬录
pkill redis
mkdir -p /opt/redis_{6380,6381}/{conf,logs,pid}
mkdir -p /data/redis_{6380,6381}

#3.⽣成主节点配置⽂件
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/"
appendonly yes
appendfilename "redis.aof"
appendfsync everysec
cluster-enabled yes
cluster-config-file nodes_6380.conf
cluster-node-timeout 15000
EOF

#4.复制主节点的配置⽂件到从节点并更改端⼝号
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

#5.更改授权为redis
chown -R redis:redis /opt/redis_*
chown -R redis:redis /data/redis_*

#6.⽣成主节点的systemd启动⽂件
cat >/usr/lib/systemd/system/redis-master.service<<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/redis-server /opt/redis_6380/conf/redis_6380.conf
--supervised systemd
ExecStop=/usr/local/bin/redis-cli -h $(ifconfig eth0|awk 'NR==2{print
$2}') -p 6380 shutdown
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF

#7.复制master节点的启动⽂件给slave节点并修改端⼝号
cd /usr/lib/systemd/system/
cp redis-master.service redis-slave.service
sed -i 's#6380#6381#g' redis-slave.service

#8.重载并启动集群节点
systemctl daemon-reload
systemctl start redis-master
systemctl start redis-slave
ps -ef|grep redis

#9.把创建好的⽬录和启动⽂件发送给db02和db03
rsync -avz /opt/redis_638* 10.0.0.52:/opt/
rsync -avz /opt/redis_638* 10.0.0.53:/opt/
rsync -avz /usr/lib/systemd/system/redis-*.service
10.0.0.52:/usr/lib/systemd/system/
rsync -avz /usr/lib/systemd/system/redis-*.service
10.0.0.53:/usr/lib/systemd/system/

5.db02的操作

#1.替换db01发送过来的⽂件并修改IP地址
pkill redis
find /opt/redis_638* -type f -name "*.conf"|xargs sed -i "/bind/s#51#52#g"
cd /usr/lib/systemd/system/
sed -i 's#51#52#g' redis-*.service
mkdir –p /data/redis_{6380,6381}
chown -R redis:redis /opt/redis_*
chown -R redis:redis /data/redis_*
systemctl daemon-reload
systemctl start redis-master
systemctl start redis-slave
ps -ef|grep redis

6.db03的操作

#1.替换db01发送过来的⽂件并修改IP地址
pkill redis
find /opt/redis_638* -type f -name "*.conf"|xargs sed -i "/bind/s#51#53#g"
cd /usr/lib/systemd/system/
sed -i 's#51#53#g' redis-*.service
mkdir –p /data/redis_{6380,6381}
chown -R redis:redis /opt/redis_*
chown -R redis:redis /data/redis_*
systemctl daemon-reload
systemctl start redis-master
systemctl start redis-slave
ps -ef|grep redis

7.集群⼿动发现节点

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.53 6380
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 6381
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

8.集群⼿动分配槽位

1.槽位规划

db01:6380 5461 0-5460
db02:6380 5461 5461-10921
db03:6380 5462 10922-16383

2.分配槽位

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..10921}
redis-cli -h 10.0.0.53 -p 6380 CLUSTER ADDSLOTS {10922..16383}

3.查看集群状态

redis-cli -h 10.0.0.51 -p 6380 CLUSTER NODES
redis-cli -h 10.0.0.51 -p 6380 CLUSTER INFO

9.⼿动分配复制关系

1.先获取集群节点信息

redis-cli -h 10.0.0.52 -p 6381 CLUSTER nodes

2.过滤删除不必要的信息

6380的ID 10.0.0.51
6380的ID 10.0.0.53
6380的ID 10.0.0.52

3.画图

4.配置复制关系

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

5.检查复制关系

redis-cli -h 10.0.0.51 -p 6381 CLUSTER NODES

第17章 集群写⼊数据

1.尝试插⼊⼀条数据

[root@redis01 redis]# redis-cli -h 10.0.0.51 -p 6380
10.0.0.51:6380> set k1 v1
(error) MOVED 12706 10.0.0.53:6380
[root@redis01 redis]# redis-cli -c -h 10.0.0.51 -p 6380
10.0.0.51:6380>
10.0.0.51:6380> set k4 v4
-> Redirected to slot [8455] located at 10.0.0.52:6380
OK
10.0.0.52:6380> keys *
1) "k4"
10.0.0.52:6380> get k4
"v4"

2.⽬前的现象

1.在db01的6380上插⼊数据提示错误
2.报错提示应该移动到db03的6380上
3.根据提示在db03的6380上执⾏相同的命令可以写⼊成功
4.db01的6380有的数据可以写⼊,有的不⾏
5.使⽤-c参数后,可以正常写⼊命令,并且由⽬标节点返回信息

3.问题原因

因为集群模式有ASK规则,加⼊-c参数后,会⾃动跳转到⽬标节点处理并由⽬标节点返回信息。

第18章 验证集群hash是否⾜够随机⾜够平均

1.写⼊测试命令

for i in {1..1000};do redis-cli -c -h 10.0.0.51 -p 6380 set k_${i} v_${i}
&& echo "${i} is ok";done

2.验证⾜够平均

[root@redis01 redis]# redis-cli -c -h 10.0.0.51 -p 6380 DBSIZE
(integer) 339
[root@redis01 redis]# redis-cli -c -h 10.0.0.52 -p 6380 DBSIZE
(integer) 326
[root@redis01 redis]# redis-cli -c -h 10.0.0.53 -p 6380 DBSIZE
(integer) 335

3.验证⾜够随机

redis-cli -c -h 10.0.0.51 -p 6380 keys \* > keys.txt

cat keys.txt |awk -F "_" '{print $2}'|sort -rn

4.允许节点的槽个数误差在2%以内的依据

[root@redis01 redis]# redis-cli --cluster rebalance 10.0.0.51:6380
>>> Performing Cluster Check (using node 10.0.0.51:6380)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
*** No rebalancing needed! All nodes are within the 2.00% threshold.

5.检查集群健康状态

[root@redis01 redis]# redis-cli --cluster info 10.0.0.51:6380
10.0.0.51:6380 (f765d849...) -> 3343 keys | 5461 slots | 1 slaves.
10.0.0.52:6380 (5ff2b711...) -> 3314 keys | 5461 slots | 1 slaves.
10.0.0.53:6380 (de167d13...) -> 3343 keys | 5462 slots | 1 slaves.
[OK] 10000 keys in 3 masters.
0.61 keys per slot on average.

第19章 使⽤⼯具⾃动部署redis集群-通⽤ruby法

1.安装依赖-只要在db01上操作

yum install -y rubygems
gem sources -a http://mirrors.aliyun.com/rubygems/
gem sources --remove http://rubygems.org/
gem install redis -v 3.3.3

2.还原集群环境

redis-cli -c -h 10.0.0.51 -p 6380 flushall
redis-cli -c -h 10.0.0.52 -p 6380 flushall
redis-cli -c -h 10.0.0.53 -p 6380 flushall
redis-cli -h 10.0.0.51 -p 6380 CLUSTER RESET
redis-cli -h 10.0.0.52 -p 6380 CLUSTER RESET
redis-cli -h 10.0.0.53 -p 6380 CLUSTER RESET
redis-cli -h 10.0.0.51 -p 6381 CLUSTER RESET
redis-cli -h 10.0.0.52 -p 6381 CLUSTER RESET
redis-cli -h 10.0.0.53 -p 6381 CLUSTER RESET

3.快速部署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

第20章 使⽤⼯具⾃动部署redis集群-⾼科技版

1.还原集群状态

redis-cli -c -h 10.0.0.51 -p 6380 flushall
redis-cli -c -h 10.0.0.52 -p 6380 flushall
redis-cli -c -h 10.0.0.53 -p 6380 flushall
redis-cli -h 10.0.0.51 -p 6380 CLUSTER RESET
redis-cli -h 10.0.0.52 -p 6380 CLUSTER RESET
redis-cli -h 10.0.0.53 -p 6380 CLUSTER RESET
redis-cli -h 10.0.0.51 -p 6381 CLUSTER RESET
redis-cli -h 10.0.0.52 -p 6381 CLUSTER RESET
redis-cli -h 10.0.0.53 -p 6381 CLUSTER RESET

2.快速部署Redis集群

redis-cli --cluster create 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 --cluster-replicas 1

3.检查集群

redis-cli --cluster info 10.0.0.51:6380

第21章 使⽤⼯具扩容

1.需要考虑的问题

1.迁移时槽的数据会不会迁过去
2.迁移过程集群读写受影响吗
3.需要限速吗
4.如何确保迁移后的完整性

2.如何设计实验验证迁移过程是否受影响

1.迁移过程中,⼀个窗⼝读数据,⼀个窗⼝写数据
2.观察是否会中断

3.创建新节点

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 10.0.0.51 -p 6380 cluster meet 10.0.0.51 6390
redis-cli -c -h 10.0.0.51 -p 6380 cluster meet 10.0.0.51 6391
redis-cli -c -h 10.0.0.51 -p 6380 cluster nodes

4.扩容步骤

#重新分配槽位
redis-cli --cluster reshard 10.0.0.51:6380
#第⼀次交互:每个节点最终分配多少个槽
How many slots do you want to move (from 1 to 16384)? 4096
#第⼆次交互:接受节点的ID
What is the receiving node ID? 6390的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:all
#第四次交互:确认信息
Do you want to proceed with the proposed reshard plan (yes/no)? yes

5.验证命令

写命令
for i in {1..1000};do redis-cli -c -h 10.0.0.51 -p 6380 set k_${i} v_${i}
&& echo ${i} is ok;sleep 0.5;done
读命令
for i in {1..1000};do redis-cli -c -h 10.0.0.51 -p 6380 get k_${i};sleep
0.5;done

第22章 使⽤⼯具收缩

1.缩容命令

#重新分配槽
redis-cli --cluster reshard 10.0.0.51:6380
#第⼀次交互:需要迁移多少个槽
How many slots do you want to move (from 1 to 16384)? 1365
#第三次交互:接受节点ID是多少
What is the receiving node ID? db01的6380的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: 6390的ID
Source node #2: done
#第四次交互:确认信息
Do you want to proceed with the proposed reshard plan (yes/no)? yes
重复上述操作,知道6390所有的槽都被分配完毕

2.检查命令

redis-cli --cluster info 10.0.0.51:6380

3.解决⽅法-归⼀再分配法

归⼀:
把要缩容节点的数据都扔到其中⼀个节点
分配:
然后利⽤集群重新负载均衡命令重新分配
redis-cli --cluster rebalance 10.0.0.51:6380

第23章 模拟故障转移

1.关闭主节点,测试集群是否依然可⽤

10.0.0.51:6381> CLUSTER NODES
f765d849975ddfda7029d16be717ddffcc4c4bc7 10.0.0.51:6380@16380 slave
2a55b4454e33b3c5a953264c9d69a58a56ab1a85 0 1587000834939 20 connected
5ff2b711ff5b377bf06ce5ef878b3a7aaf881a98 10.0.0.52:6380@16380 slave
7d1328883b4a162d2728f8719fffc53d5fb3d801 0 1587000838082 22 connected
de167d131d45eedcb9b56ef0021ae110d6e55d46 10.0.0.53:6380@16380 slave
aef2cbf60bc3109ba76253d52d691e2dba7bd3e5 0 1587000837000 21 connected
aef2cbf60bc3109ba76253d52d691e2dba7bd3e5 10.0.0.51:6381@16381 myself,master
- 0 1587000837000 21 connected 10923-16383
2a55b4454e33b3c5a953264c9d69a58a56ab1a85 10.0.0.52:6381@16381 master - 0
1587000837000 20 connected 0-5460
7d1328883b4a162d2728f8719fffc53d5fb3d801 10.0.0.53:6381@16381 master - 0
1587000837070 22 connected 5461-10922

2.主动发起故障转移

redis-cli -c -h 10.0.0.51 -p 6380 CLUSTER FAILOVER
redis-cli -c -h 10.0.0.52 -p 6380 CLUSTER FAILOVER
redis-cli -c -h 10.0.0.53 -p 6380 CLUSTER FAILOVER

第24章 迁移过程意外中断如何修复

1.模拟场景:迁移时⼈为中断,导致槽的状态不对

 [5754->-f765d849975ddfda7029d16be717ddffcc4c4bc7]

2.⼿动修复

redis-cli -c -h 10.0.0.52 -p 6380 CLUSTER SETSLOT 5754 STABLE

3.使⽤⼯具修复-⽣产建议使⽤⼯具修复

 redis-cli --cluster fix 10.0.0.51:6380

第24章 ⾃动化-⿊客帝国版

1.ansible部署redis集群5.x

⽬录结构

redis_cluster/
!"" files
# !"" redis_6380
# # !"" conf
# # !"" logs
# # $"" pid
# !"" redis_6381
# # !"" conf
# # !"" logs
# # $"" pid
# $"" redis_cmd
# !"" redis-benchmark
# !"" redis-check-aof
# !"" redis-check-rdb
# !"" redis-cli
# $"" redis-server
!"" handlers
# $"" main.yaml
!"" tasks
# $"" main.yaml
$"" templates
 !"" redis_6380.conf.j2
 !"" redis_6381.conf.j2
 !"" redis-master.service.j2
 $"" redis-slave.service.j2

调⽤⽂件

cat >/etc/ansible/redis_cluster.yaml <<EOF
- hosts: redis_cluster
  roles:
    - redis_cluster
EOF

tasks内容:

cat >>/etc/ansible/roles/redis_cluster/tasks/main.yaml <<EOF
#01.创建⽤户组
- name: 01_create_group
  group:
    name: redis
    gid: 777
#02.创建⽤户
- name: 02_create_user
  user:
    name: redis
    uid: 777
    group: redis
    shell: /sbin/nologin
    create_home: no

#03.拷⻉执⾏⽂件
- name: 03_copy_cmd
  copy:
    src: redis_cmd/
    dest: /usr/local/bin/
    mode: '0755'
#04.拷⻉运⾏⽬录
- name: 04_mkdir_conf
  copy:
    src: "{{ item }}"
    dest: /opt/
    owner: redis
    group: redis
  loop:
    - redis_6380
    - redis_6381 
    
#05.创建数据⽬录
- name: 05_mkdir_data
  file:
    dest: "/data/{{ item }}"
    state: directory
    owner: redis
    group: redis
  loop:
    - redis_6380
    - redis_6381
    
#06.拷⻉配置⽂件模版
- name: 06_copy_conf
  template:
    src: "{{ item.src}}"
    dest: "{{ item.dest }}"
    backup: yes
  loop:
    - { src: 'redis_6380.conf.j2', dest: '/opt/redis_6380/conf/redis_6380.conf' }
    - { src: 'redis_6381.conf.j2', dest: '/opt/redis_6381/conf/redis_6381.conf' }
    - { src: 'redis-master.service.j2', dest: '/usr/lib/systemd/system/redis-master.service' }
    - { src: 'redis-slave.service.j2', dest: '/usr/lib/systemd/system/redis-slave.service' }
  notify:
    - restart redis-master
    - restart redis-slave
    
#07.启动服务
- name: 07_start_redis
  systemd:
    name: "{{ item }}"
    state: started
    daemon_reload: yes
  loop:
    - redis-master
    - redis-slave
EOF

handlers

[root@m01 ~]# cat /etc/ansible/roles/redis_cluster/handlers/main.yaml
- name: restart redis-master
  service:
    name: redis-master
    state: restarted
- name: restart redis-slave
  service:
    name: redis-slave
    state: restarted

template

cat >/etc/ansible/roles/redis_cluster/templates/redis_6380.conf.j2 <<EOF
bind {{ ansible_facts.eth0.ipv4.address }}
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/"
appendonly yes
appendfilename "redis.aof"
appendfsync everysec
cluster-enabled yes
cluster-config-file nodes_6380.conf
cluster-node-timeout 15000
EOF

cat >/etc/ansible/roles/redis_cluster/templates/redis-master.service.j2
<<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/redis-server /opt/redis_6380/conf/redis_6380.conf
--supervised systemd
ExecStop=/usr/local/bin/redis-cli -h {{ ansible_facts.eth0.ipv4.address }}
-p 6380 shutdown
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF

2.免交互初始化集群

echo "yes"|redis-cli --cluster create 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 --clusterreplicas
1

3.免交互扩容

添加主节点

redis-cli --cluster add-node 10.0.0.51:6390 10.0.0.51:6380

添加从节点

redis-cli --cluster add-node 10.0.0.51:6391 10.0.0.51:6380 --cluster-slave
--cluster-master-id $(redis-cli -c -h 10.0.0.51 -p 6380 cluster nodes|awk
'/51:6390/{print $1}')

重新分配槽

redis-cli --cluster reshard 10.0.0.51:6380 --cluster-from all --cluster-to
$(redis-cli -c -h 10.0.0.51 -p 6380 cluster nodes|awk '/51:6390/{print
$1}') --cluster-slots 4096 --cluster-yes

4.免交互收缩

迁移槽

redis-cli --cluster rebalance 10.0.0.51:6380 --cluster-weight $(redis-cli -
c -h 10.0.0.51 -p 6390 cluster nodes|awk '/51:6390/{print $1}')=0

下线节点

redis-cli --cluster del-node 10.0.0.51:6391 $(redis-cli -c -h 10.0.0.51 -p
6380 cluster nodes|awk '/51:6391/{print $1}')

redis-cli --cluster del-node 10.0.0.51:6390 $(redis-cli -c -h 10.0.0.51 -p
6380 cluster nodes|awk '/51:6390/{print $1}')

第25章 Redis常⽤运维⼯具

1.使⽤redis-cli数据迁移

4.x以前的数据迁移使⽤第三⽅⼯具

https://github.com/vipshop/redis-migrate-tool

不加copy参数相当于mv,⽼数据迁移完成后就删掉了

redis-cli --cluster import 10.0.0.51:6380 --cluster-from 10.0.0.51:6379

加了copy参数相当于cp,⽼数据迁移完成后会保留

redis-cli --cluster import 10.0.0.51:6380 --cluster-from 10.0.0.51:6379 --
cluster-copy

添加replace参数会覆盖掉同名的数据,如果不添加遇到同名的key会提示冲突,对新集群新增加的数据不受影响

redis-cli --cluster import 10.0.0.51:6380 --cluster-from 10.0.0.51:6379 --
cluster-copy --cluster-replace

验证迁移期间边写边导会不会影响: 同时开2个终端,⼀个写⼊key,

for i in {1..1000};do redis-cli set k_${i} v_${i};sleep 0.2;echo ${i};done

⼀个执⾏导⼊命令

redis-cli --cluster import 10.0.0.51:6380 --cluster-copy --cluster-replace
--cluster-from 10.0.0.51:6379

得出结论:

只会导⼊当你执⾏导⼊命令那⼀刻时,当前被导⼊节点的所有数据,类似于快照,对于后⾯再写⼊的数
据不会更新

2.分析key⼤⼩

使⽤redis-cli分析

redis-cli --bigkeys
redis-cli --memkeys

使⽤第三⽅分析⼯具:

安装命令

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

⽣成测试数据

redis-cli set txt $(cat txt.txt)

⽣成rdb⽂件

redis-cli bgsave

使⽤⼯具解析RDB⽂件

cd /data/redis_6379/
rdb -c memory redis_6379.rdb -f redis_6379.rdb.csv

过滤分析

awk -F"," '{print $4,$3}' redis_6379.rdb.csv |sort -r

汇报领导

将结果整理汇报给领导,询问开发这个key是否可以删除
删除之前,最好做次备份

3.性能测试

redis-benchmark -n 10000 -q

第26章 Redis内存管理

1.⽣产上⼀定要配置Redis内存限制

maxmemory N个G

2.内存回收机制

1.noevicition 默认策略,不会删除任务数据,拒绝所有写⼊操作并返回客户端错误信息,
此时只响应读操作

2.volatile-lru 根据LRU算法删除设置了超时属性的key,指导腾出⾜够空间为⽌,如果没
有可删除的key,则退回到noevicition策略

3.allkeys-lru 根据LRU算法删除key,不管数据有没有设置超时属性

4.allkeys-random 随机删除所有key

5.volatile-random 随机删除过期key

6.volatile-ttl 根据key的ttl,删除最近要过期的key

3.⽣产上redis限制多⼤内存

先空出来系统⼀半内存
48G ⼀共
24G 系统
24G redis
redis先给8G内存 满了之后,分析结果告诉⽼⼤和开发,让他们排查⼀下是否所有的key都是必须的
redis再给到12G内存 满了之后,分析结果告诉⽼⼤和开发,让他们排查⼀下是否所有的key都是必须
的
redis再给到16G内存 满了之后,分析结果告诉⽼⼤和开发,让他们排查⼀下是否所有的key都是必须
的
等到24G都⽤完了之后,汇报领导,要考虑买内存了。
等到35G的时候,就要考虑是加内存,还是扩容机器。

4.优化建议

1.专机专⽤,不要跑其他的服务
2.内存给够,限制内存使⽤⼤⼩
3.使⽤SSD硬盘
4.⽹络带宽够⼤
5.定期分析BigKey

第27章 实战-槽位分配错误如何调整

1.假如是在集群初始化状态下分配错了

解决难度: *
解决⽅法: 重新初始化

redis-cli -h 10.0.0.51 -p 6380 CLUSTER RESET
redis-cli -h 10.0.0.52 -p 6380 CLUSTER RESET
redis-cli -h 10.0.0.53 -p 6380 CLUSTER RESET
redis-cli -h 10.0.0.51 -p 6381 CLUSTER RESET
redis-cli -h 10.0.0.52 -p 6381 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.52 6380
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.51 6381
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 6381
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..10921}
redis-cli -h 10.0.0.53 -p 6380 CLUSTER ADDSLOTS {10922..16383}
redis-cli -h 10.0.0.52 -p 6381 CLUSTER NODES
redis-cli -h 10.0.0.52 -p 6381 CLUSTER INFO

2.假如已经有数据写⼊了的情况下,运⾏⼀段时间才分配错了

重新分配槽

3.集群命令

CLUSTER NODES
CLUSTER MEET
CLUSTER INFO
CLUSTER ADDSLOTS
CLUSTER DELSLOTS
CLUSTER FAILOVER
redis-cli --cluster rebalance 10.0.0.51:6380
redis-cli --cluster info 10.0.0.51:6380
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值