学习Redis(二)
阅读原文时间:2023年07月09日阅读:4

1、Redis应用场景

1、缓存(键过期时间)
1) 缓存session会话
2) 缓存用户信息,找不到再去mysql查,查到然后回写到redis
3) 商城优惠卷过期时间

2、排行榜(列表&有序集合)
1) 热度排名排行榜
2) 发布时间排行榜

3、计数器(自增)
1) 帖子浏览数
2) 视频播放次数
3) 商品浏览数

4、社交网络(集合)
1) 踩/赞,粉丝,共同好友/喜好,推送,打标签

5、消息队列系统-发布订阅
1) 配合elk实现日志收集

2、Redis安装部署

1、安装

mkdir -p /server/tools

mkdir -p /opt/redis/redis_6379/{conf,logs,pid}

tar xf redis-3.2.9.tar.gz -C /opt/

ln -s redis-3.2.9 redis

make && make install #make install 生成二进制文件,并放到/usr/local/bin

./utils/install_server.sh #生成配置、log、数据文件,启动脚本

2、配置文件

vim redis.conf

daemonize yes
bind 10.0.0.51 127.0.0.1
port 6379
logfile /data/redis_6379/redis.log
pidfile /var/run/redis6379.pid
databases 16
dir /data/redis_6379
dbfilename redis_6379.rdb

3、启动和关闭

redis-server 6379.conf #启动

redis-cli shutdown #关闭

3、Redis安全配置

1、设置密码

vim redis.conf

protected-mode yes #开启保护模式
bind 10.0.0.51 127.0.0.1 #绑定绑定ip
requirepass 123456 #设置登录密码
6379> CONFIG SET requirepass 123 #在线修改

redis-cli -a 123456 #密码登录

redis-cli

6379> auth 123456

2、禁用危险命令
1) 禁用命令
rename-command KEYS ""
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG ""
2) 危险命令重命名
rename-command KEYS "aaaa"
rename-command FLUSHALL "bbbb"
rename-command FLUSHDB "cccc"
rename-command CONFIG "dddd"

4、全局命令

6379> KEYS * #查看所有key(禁用)
6379> DBSIZE #查看有多少个key(大约)
6379> EXISTS key #查看KEY是否存在(0:不存在,1:存在)
6379> DEL key #删除key(0:不存在,1:存在并删除)
6379> EXPIRE key 10 #设置key的过期时间(0:不存在,1:存在并设置,单位是秒)
6379> PERSIST key #取消key的过期时间(0:不存在,1:存在并取消)
6379> TTL key #查看key是否过期,过期后的key会删除(-1:存在,-2:不存在)
6379> TYPE key #查看key的类型
6379> RENAME key key01 #更改key的名
6379> BGSAVE #缓存的数据保存到磁盘

5、string(字符串)

6379> SET k1 v1 #设置一个key
6379> GET k1 #查看一个key
6379> MSET k1 v1 k2 v2 #设置多个key
6379> MGET k1 k2 #查看多个key
6379> set k1 1 #设置一个key
6379> INCR k1 #自增1
6379> DECR k1 #自减1
6379> INCRBY k1 100 #自增100
6379> INCRBY k1 -100 #自减100
6379> DECRBY k1 100 #自减100

6、list(列表)

6379> LPUSH list1 A #从列表左(头部)插入数据
6379> RPUSH list1 B #从列表右(尾部)插入数据
6379> LLEN list1 #查看列表的长度
6379> LRANGE list1 0 -1 #查看列表的内容
6379> LPOP list1 #从列表左(头部)删除
6379> RPOP list1 #从列表右(尾部)删除
6379> DEL list1 #删除列表

7、hash(哈希)

1、mysql数据和redis哈希对比
1)mysql数据(user表)
uid name age job
1 tom 28 it
2)mysql查询数据:
select * from user where id=3
3)redis缓存mysql数据
key名 key1 key1值 key2 key2值 key3 key3值
uid:1 name tom age 28 job it

2、设置和查看哈希值
6379> HSET uid:1 name tom #设置一个哈希值
6379> HMSET uid:1 name tom age 28 job it #设置多个哈希值
6379> HGET uid:1 name #查看一个哈希值
6379> HMGET uid:1 name age job #查看多个哈希值
6379> HGETALL uid:1 #查看所有哈希值

8、set(集合)

1、无序集合
6379> SADD set1 1 2 3 #创建集合1(不允许重复的值)
6379> SADD set2 1 3 5 7 #创建集合2(有去重功能)
6379> SMEMBERS set1 #查看集合
6379> SREM set1 2 #删除指定的值
6379> SDIFF set1 set2 #查看集合的差集(set1减去set2,答案是2)
6379> SDIFF set2 set1 #查看集合的差集(以set2为基准对比,set2减set1)
6379> SINTER set1 set2 #查看集合的交集(set1和set2共同的值)
6379> SUNION set1 set2 #查看集合的并集(set1加set2,去重的值)

2、有序集合
6379> ZADD mysql 100 zhang3 #创建集合mysql(zhang3分数100)
6379> ZADD mysql 90 li4 50 wang5 10 zhao6 #添加集合
6379> ZCARD mysql #查看集合个数
6379> ZSCORE mysql zhang3 #查看zhang3的分数
6379> ZRANK mysql zhang3 #降序(从大到小,3:下面有3个人)
6379> ZREVRANK mysql li4 #升序(从小到大,1:上面有1个人)
6379> ZINCRBY mysql 5 li4 #加5个分数
6379> ZINCRBY mysql -5 li4 #减5个分数
6379> ZRANGE mysql 0 -1 withscores #升序(从小到大,取所有的值)
6379> ZRANGE mysql 0 2 withscores #升序(从小到大,取0到2的值)
6379> ZREVRANGE mysql 0 -1 withscores #降序(从大到小,取所有的值)
6379> ZRANGEBYSCORE mysql 50 100 withscores #查看指定分数的人
6379> ZCOUNT mysql 50 100 #统计指定分数的个数
6379> ZREN mysq li4 #删除li4及分数

9、Redis持久化

1、RDB和AOF介绍
1) RDB持久化
介绍: 在指定的时间内生成快照,并把内存的数据写到磁盘上,
优点: 恢复速度快,适合用于做备份,主从复制基于RDB持久化功能实现
缺点: 可能会丢失数据
2) AOF持久化
介绍: 类似于MySQL的binlog,记录所有写的操作,每次操作或1秒写一次,服务启动时,会重新执行命令还原数据
优点: 安全,有可能会丢失1秒数据
缺点: 文件比较大,恢复速度慢

2、配置RDB

vim redis.conf

save 900 1 #900秒1个改变
save 300 10 #300秒10个改变
save 60 10000 #60秒1万个改变
dir /data/redis_6379/
dbfilename redis_6379.rdb

3、配置AOF

vim redis.conf

appendonly yes #是否打开aof日志功能
appendfsync always #每1个命令,都立即同步到aof
appendfsync everysec #每秒写1次
appendfsync no #写入交给系统,由系统判断缓冲区大小,统一写入到aof
appendfilename "appendonly.aof"

4、redis持久化方式有哪些?有什么区别?
rdb: 基于快照的持久化,速度快,一般用作备份,主从复制依赖于rdb持久化功能
aof: 类似于MySQL的binlog,记录redis所有写的操作,安全性高

5、总结
1) 配置持久化参数,正常关闭(shutdown)时,会先执行bgsave,后在执行shutdown
2) pkill、kill、killall等,类似于shutdown命令,会触发持久化(bgsave命令)
3) 执行kill -9,redis不会触发持久化
4) rdb和aof同时存在,redis会优先读取aof文件

10、Redis主从复制

1、配置主从
方法1: 临时生效

redis-cli -h 10.0.0.52

6379> SLAVEOF 10.0.0.51 6379

redis-cli SLAVEOF 10.0.0.51 6379

方法2: 永久生效

vim 6379.conf

masterauth 123456 #主库密码
SLAVEOF 10.0.0.51 6379
方法3: 永久生效

redis-server redis.conf SLAVEOF 10.0.0.51 6379

2、解除主从
6379> SLAVEOF no one

redis-cli SLAVEOF no one

3、主从复制流程
1) 从库通过slaveof命令,连接主库,并发送同步请求SYNC给主库
2) 主库收到SYNC后,触发bgsave,后台保存RDB,并把rdb文件发送给从库
3) 从库收到rdb文件后,清空自己的数据,载入收到的rdb文件到的内存,并生成自己的rdb文件

4、总结
1、执行主从复制之前,先备份数据,从库会清空原有数据
2、在业务低峰期做主从复制,主从同步会占用网络带宽
3、配置主从复制后,从库只读不能写
4、从库不会自动故障转移,会一直同步主库

5、vim应用
1) f+要定位的数字(英文)
2) Ctrl + a 加1, 3 + Ctrl + a 加3
3) Ctrl + x 减1, 3 + Ctrl + x 减3
4) 命令模式下,:! 可执行liunx命令

11、Redis哨兵

1、介绍
1) redis-sentinel是Redis自带的命令
2) sentinel不断监控主库和从库状态(监控)
3) 当redis服务器有问题,可通过API向应用程序发送通知(提醒)
4) 当主库有问题,会自动故障迁移到从库上,并通知程序新主库的地址
5) 基于Redis的主从复制结构

2、安装部署redis-sentinel
1) 提前部署Redis的1主2从(3个节点)
2) 创建配置文件(3个节点)

vim 26379.conf

bind 10.0.0.51 #绑定ip(3个节点不同)
port 26379
daemonize yes
logfile /opt/redis/redis_26379/logs/redis_26379.log
dir /opt/redis/redis_26379/data/
sentinel monitor mymaster 10.0.0.51 6379 2 #监控mymaster(自定义组名)主库ip,1个节点必须2票,才切换主
sentinel down-after-milliseconds mymaster 3000 #主库宕机3秒,进行切库(单位是毫秒)
sentinel parallel-syncs mymaster 1 #向新主库发起主从复制的个数,1 轮询发起复制
sentinel failover-timeout mymaster 18000 #故障转移的超时时间
3) 启动哨兵

redis-sentinel redis_26379.conf

3、Redis哨兵+主从+密码
2) 配置主

vim redis_6379.conf

requirepass "123456" #本身密码
2) 配置从

vim redis_6379.conf

masterauth "123456" #主库密码
3) 配置哨兵

vim 26379.conf

sentinel auth-pass mymaster 123456 #主库密码

4、哨兵常用命令
26379> Info Sentinel #哨兵主库和从库信息
26379> Sentinel masters #所有主库信息
26379> Sentinel master #指定主库信息
26379> Sentinel slaves #所有从库信息
26379> Sentinel sentinels #查看指定组的列表及状态
26379> Sentinel get-master-addr-by-name #查看指定组的主库的ip和端口
26379> Sentinel failover #强制执行故障转移
26379> Sentinel flushconfig #强制重写配置信息到配置文件
26379> Sentinel reset #重置所有节点的配置,清除主节点相关状态,重新发现主和从节点
26379> Sentinel ckquorum #检测当前的节点总数

5、手动故障转移
1) 查看节点的权重

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

2) 设置节点的权重(51为100,52和53为0)

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

redis-cli -h 10.0.0.53 -p 6379 CONFIG SET slave-priority 0

3) 手动执行故障转移

redis-cli -h 10.0.0.51 -p 26379 sentinel failover mymaster

4) 查看结果

redis-cli -h 10.0.0.51 -p 26379 Sentinel get-master-addr-by-name mymaster

5) 恢复默认的权重(防止主库不能故障转移)

redis-cli -h 10.0.0.52 -p 6379 CONFIG SET slave-priority 100

redis-cli -h 10.0.0.53 -p 6379 CONFIG SET slave-priority 100

5) 总结
权重的id大的优先,默认是100,设置100以上可能有问题,推荐0-100

12、Redis Cluster集群

1、介绍
1) redis集群,无论有几个节点,一共只有16384个槽
2) 所有的槽位都必须分配,哪怕有1个槽位不正常,整个集群都不能用
3) 每个节点的槽的顺序不重要,重点是数量
4) hash算法足够随机,足够平均
5) 每个槽被分配到数据的概率是相当的
6) 集群的高可用依赖于主从复制
7) 集群拥有自己的配置文件,动态更新,不要手欠修改
8) 集群通讯会使用基础端口号+10000的端口,这个是自动创建的,不是配置文件配置的
9) 集群槽位分配比例允许误差在%2之间

2、环境规划
主节点 db01: 10.0.0.51:6380 db02: 10.0.0.52:6380 db03: 10.0.0.53:6380
从节点 db02: 10.0.0.52:6381 db03: 10.0.0.53:6381 db01: 10.0.0.51:6381

3、安装部署
1) 创建目录(所有节点)

mkdir -p /opt/redis_{6380,6381}/{conf,logs,pid}

mkdir -p /data/redis_{6380,6381}

2) 创建配置文件(所有节点,ip地址不同)

vim /opt/redis_6380/conf/redis_6380.conf

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 #集群node配置文件(动态更新)
cluster-node-timeout 15000 #集群的超时时间

vim /opt/redis_6381/conf/redis_6381.conf

bind 10.0.0.51
port 6381
daemonize yes
pidfile "/opt/redis_6381/pid/redis_6381.pid"
logfile "/opt/redis_6381/logs/redis_6381.log"
dbfilename "redis_6381.rdb"
dir "/data/redis_6381/"
appendonly yes
appendfilename "redis.aof"
appendfsync everysec
cluster-enabled yes
cluster-config-file nodes_6381.conf
cluster-node-timeout 15000
3) 启动集群(所有节点)

redis-server /opt/redis_6380/conf/redis_6380.conf

redis-server /opt/redis_6381/conf/redis_6381.conf

4、集群手动发现节点

redis-cli -h db01 -p 6380 CLUSTER MEET 10.0.0.52 6380 #节点发现

redis-cli -h db01 -p 6380 CLUSTER MEET 10.0.0.53 6380

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 6381

redis-cli -h db01 -p 6380 CLUSTER MEET 10.0.0.53 6381

redis-cli -h db01 -p 6380 CLUSTER NODES #查看节点

5、Redis Cluster 通讯流程
1) 集群中的每一个节点,内部通信的端口号,在基础端口上加10000(6380+10000)
2) 每个节点在固定周期内发送 ping 消息
3) 收到 ping 消息的节点,用 pong 消息作为响应
4) meet消息是通知新节点加入
5) fail消息是节点宕机后,正常的节点会发送faill消息给其他节点

6、Redis Cluster手动分配槽位
redis集群一共有16384个槽,所有的槽都必须分配完,有一个槽没分配,整个集群都不可用
1) 槽位规划
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..10921}

redis-cli -h db03 -p 6380 CLUSTER ADDSLOTS {10922..16382}

redis-cli -h 10.0.0.53 -p 6380 CLUSTER ADDSLOTS 16383

3) 查看集群状态

redis-cli -h db01 -p 6380 CLUSTER info

redis-cli -h db01 -p 6380 CLUSTER NODES

7、手动部署复制关系
1) 询集群的id

redis-cli -h 10.0.0.51 -p 6380 CLUSTER NODES

2) 设置主从复制

redis-cli -h db01 -p 6381 CLUSTER REPLICATE 35b56a(db02上6380的id)

redis-cli -h db02 -p 6381 CLUSTER REPLICATE 65baft(db03上6380的id)

redis-cli -h db03 -p 6381 CLUSTER REPLICATE a1d85c(db01上6380的id)

3) 检查复制关系

redis-cli -h db01 -p 6380 CLUSTER NODES

8、Redis Cluster ASK路由
1) 集群插入数据
6380> set k1 v1
2) 目前的现象
在db01的6380节点,插入数据有时候可以,有时候不行
3) 问题原因
因为集群模式有ASK路由规则,加-c参数,会自动跳转到目标节点处理,最后由目标节点返回信息

9、验证集群数据的随机和是否平均
1) 测试写入数据

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

2) 查看key数量是否平均(所有节点)
6380> DBSIZE
3) 验证随机

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

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

4) 允许节点误差2%

redis-cli --cluster rebalance 10.0.0.51 6380(5.0版本)

redis-trib.rb rebalance 10.0.0.51:6380(4.0版本,命令依赖ruby环境)

5) 检查集群健康状态

redis-cli --cluster info 10.0.0.51 6380

redis-trib.rb check 10.0.0.51:6380

10、使用工具自动部署redis集群(新版本)
1) 恢复集群初始化(所有节点)

redis-cli -h db01 -p 6380 FLUSHALL

redis-cli -h db01 -p 6381 FLUSHALL

redis-cli -h db01 -p 6380 CLUSTER RESET

redis-cli -h db01 -p 6381 CLUSTER RESET

2) 使用工具初始化

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 -h db01 -p 6380 CLUSTER NODES

redis-cli --cluster info 10.0.0.51 6380

redis-cli --cluster check 10.0.0.51 6380

11、使用工具自动部署redis集群(老版本)
1) 安装ruby环境

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

2) 恢复集群初始化(所有节点)

pkill redis

rm -rf /data/redis_cluster/redis_6380/

rm -rf /data/redis_cluster/redis_6381/

3) 启动集群节点(所有节点)

redis-server /opt/redis_6380/conf/redis_6380.conf

redis-server /opt/redis_6381/conf/redis_6381.conf

4) 使用工具部署集群(一台部署)

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-cli -h db01 -p 6380 CLUSTER NODES

redis-cli -h db02 -p 6381 CLUSTER REPLICATE a38fc2b2

redis-cli -h db03 -p 6381 CLUSTER REPLICATE afd9311d

6) 检查集群完整性

./redis-trib.rb check 10.0.0.51:6380

7) 检查集群负载平均

./redis-trib.rb rebalance 10.0.0.51:6380

8) 查看集群信息

./redis-trib.rb info 10.0.0.51:6380

12、案例
① 背景
部署集群时,不小心把所有的槽分配到1个节点上,写入了数据后,才发现问题
② 现象

redis-cli --cluster info 10.0.0.51 6380

10.0.0.51:6380 (ccaa5dcb…) -> 1000 keys | 16384 slots | 3 slaves.
10.0.0.53:6380 (a69e46ea…) -> 0 keys | 0 slots | 0 slaves.
10.0.0.52:6380 (b2719c41…) -> 0 keys | 0 slots | 0 slaves.
③ 解决方法1(获得所有key及value,再导入到集群)
1) 收集所有的key及value

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

2) 编写脚本(批量设置key及value)

vim get_key.sh

#!/bin/bash
for key in $(cat keys_all.txt)
do
value=$(redis-cli -c -h 10.0.0.51 -p 6380 get ${key})
echo redis-cli -c -h 10.0.0.51 -p 6380 set ${key} ${value} >> backup_all_key.txt
done
3) 重新初始化集群(所有节点)

redis-cli -h db01 -p 6380 FLUSHALL

redis-cli -h db01 -p 6381 FLUSHALL

redis-cli -h db01 -p 6380 CLUSTER RESET

redis-cli -h db01 -p 6381 CLUSTER RESET

4) 重新分配槽位

redis-cli -h db01 -p 6380 CLUSTER MEET 10.0.0.52 6380

redis-cli -h db01 -p 6380 CLUSTER MEET 10.0.0.53 6380

redis-cli -h db01 -p 6380 CLUSTER ADDSLOTS {0..5460}

redis-cli -h db02 -p 6380 CLUSTER ADDSLOTS {5461..10921}

redis-cli -h db03 -p 6380 CLUSTER ADDSLOTS {10922..16383}

redis-cli -h db01 -p 6380 CLUSTER NODES

redis-cli --cluster info 10.0.0.51 6380

5) 执行导入脚本

bash backup_all_key.txt

6) 检查集群的数据

redis-cli --cluster info 10.0.0.51 6380

④ 使用redis-cli工具重新分配槽位
重新分配槽位

redis-cli --cluster reshard 10.0.0.51:6380

第一次交互:输入迁出的槽的数量
How many slots do you want to move (from 1 to 16384)? 5461
第二次交互:输入接受的ID
What is the receiving node ID? afd9311d(db02的ID)
第三次交互:输入发送者的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: a38fc2b2(db01的ID)
Source node #2: done
第四次交互:YES!
重复上面的操作,分配所有的槽位

⑤ 直接使用工具在线导入

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

10.0.0.51:6380 #集群地址
10.0.0.51:6379 #外部redis(备份数据的Redis,把aof文件复制过来的)

⑥ 流水线 pipline
新版本redis默认开启混合模式,重新分配槽位,导入旧aof文件

redis-cli -c -h 10.0.0.51 -p 6380 --pipe < redis.aof

redis-cli -c -h 10.0.0.52 -p 6380 --pipe < redis.aof

redis-cli -c -h 10.0.0.53 -p 6380 --pipe < redis.aof

13、使用工具扩容节点
1) 创建新节点

mkdir -p /opt/redis_{6390,6391}/{conf,logs,pid}

mkdir -p /data/redis_{6390,6391}

cp redis_6380.conf redis_6390/conf/redis_6390.conf

cp 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

2) 启动节点

redis-server /opt/redis_6390/conf/redis_6390.conf

redis-server /opt/redis_6391/conf/redis_6391.conf

3) 发现节点

redis-cli -c -h db01 -p 6380 cluster meet 10.0.0.54 6390

redis-cli -c -h db01 -p 6380 cluster meet 10.0.0.54 6391

或用工具

./redis-trib.rb add-node 10.0.1.54:6390 10.0.1.51:6380

./redis-trib.rb add-node 10.0.1.54:6391 10.0.1.51:6380

4) 用工具扩容

redis-cli --cluster reshard 10.0.0.51:6380 #重新分配槽位

How many slots do you want to move (from 1 to 16384)? 4096 #每个节点分配多少个槽位
What is the receiving node ID? daf93ab(6390的ID) #目标节点ID
Source node #1: all #源节点ID(只能输入一个节点的ID,再输入done,或输入all)
5) 检查集群完整性

./redis-trib.rb check 10.0.0.51:6380

6) 检查集群负载均衡

./redis-trib.rb rebalance 10.0.0.51:6380

7) 调整主从关系

redis-cli -h 10.0.0.51 -p 6381 CLUSTER REPLICATE df23ew36(db04的6390主的ID)

redis-cli -h 10.0.0.54 -p 6391 CLUSTER REPLICATE u38s02ld(db01的6380主的ID)

14、使用工具收缩节点
1) 重新分配槽位

redis-cli --cluster reshard 10.0.0.51:6380 #重新分配槽位

How many slots do you want to move (from 1 to 16384)? 1365 #每个节点分配多少个槽位
What is the receiving node ID? w3k18ylq(db01-6380-ID) #目标节点ID
Source node #1: daf93ab(6390-ID) #源节点ID(只能输入一个节点的ID)
Source node #2: done
重复操作,分配6390所有的槽位
2) 检查集群状态,确认6390没有槽位

redis-cli --cluster info 10.0.0.51:6380

./redis-trib.rb info 10.0.0.51:6380

3) 删除节点

redis-cli --cluster del-node 10.0.0.54:6390 2b7a7b78(6390的ID)

redis-cli --cluster del-node 10.0.0.54:6391 c2d62daf(6391的ID)

./redis-trib.rb del-node 10.0.0.51:6391 2b7a7b78(6390的ID)

./redis-trib.rb del-node 10.0.0.51:6390 c2d62daf(6391的ID)

15、案例
1) 背景
迁移过程中,ctrl+c,集群出现问题
2) 检查,有报错

./redis-trib.rb check 10.0.0.51:6380

3) 解决办法(数据会丢)

./redis-trib.rb fix 10.0.0.51:6380 #尝试修复

redis-cli -h db01 -p 6380 CLUSTER NODES #找到有问题的槽位

redis-cli -h db01 -p 6380 cluster delslots 773 #删除有问题的槽位

redis-cli -h db01 -p 6380 cluster addslots 773 #重新添加新槽位

16、分析键值大小
1) 用自带工具分析

redis-cli --bigkeys

2) 用第三方工具分析
① 安装

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

② 用工具分析

rdb -c memory redis_6380.rdb -f redis_6380.rdb.csv

③ 过滤分析

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

17、监控过期键
1) Keys * 查出来匹配的键名,然后循环读取ttl时间(Keys 重操作,不提供服务的从节点)

redis-cli -h 10.0.0.55 -p 6381 keys * > key_list.txt

2) scan * 范围查询键名,然后循环读取ttl时间

cat check_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 10.0.0.51 -p 6380 SCAN ${key_num} match ${line}\* count 1000|awk 'NR==1{print $0}')
key_name=$(redis-cli -h 10.0.0.51 -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

18、新版本数据迁移
1) 相当于mv,集群的旧数据会删除

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

2) 相当于cp,集群的旧数据会保留

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

3) 相当于cp -f,集群的旧数据会覆盖

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

19、 redis的内存管理
1) 限制最大内存
6379> config set maxmemory 2G
2) 内存回收机制
noevicition 默认策略,不会删除数据,返回错误信息,拒绝所有写操作,只响应读操作
volatile-lru 根据LRU算法,删除过期时间的key,如果没有可删除的key,则退回到默认策略
allkeys-lru 根据LRU算法,删除所有key
allkeys-random 随机删除所有key
volatile-random 随机删除过期key
volatile-ttl 删除即将过期的key
6379> config set maxmemory-policy volatile-lru
3) 性能测试

redis-benchmark -n 10000 -q

20、命令总结
1) redis 常用命令
全局命令
keys *
DBSIZE
EXISTS k1
EXPIRE k1 10
TTL k1
DEL k1
字符串:
set k1 v1
get k1
mset k1 v1 k2 v2 k3 v3
mget k1 k2 k3
incr k1
incrby k1 N
列表:
LPUSH
RPUSH
LPOP
RPOP
LLEN
LRANGE list1 0 -1
HASH:
HMSET
HGET
HMGET
HGETALL
集合:
SADD
SDIFF
SINTER
SUNION
SREM
有序集合:
ZADD
ZCARD
ZSCORE
ZRANK
ZREVRANK
ZRANGE
ZRANGEBYSCORE
ZINCRBY
ZCOUNT
2) 集群常用命令
CLUSTER INFO #集群的信息
CLUSTER NODES #集群节点信息
CLUSTER MEET #发现节点
CLUSTER FORGET #移除节点
CLUSTER REPLICATE #设置主从复制
CLUSTER SAVECONFIG #节点的配置保存到文件
CLUSTER ADDSLOTS [slot …] #添加新槽位
CLUSTER DELSLOTS [slot …] #移除槽位
CLUSTER FLUSHSLOTS #移除所有槽位
CLUSTER SETSLOT NODE #分配槽位到指定的节点
CLUSTER SETSLOT MIGRATING #迁移槽位到指定的节点
CLUSTER SETSLOT IMPORTING #导入指定的节点的槽位
CLUSTER SETSLOT STABLE #取消槽位的的导入或迁移
CLUSTER KEYSLOT #计算key在槽的位置
CLUSTER COUNTKEYSINSLOT #槽中键值对的数量
CLUSTER GETKEYSINSLOT #槽中key的列表