DBA数据库学习

DBA数据库笔记之(七)Redis基础知识

2024-01-20  本文已影响0人  Mr培

Redis常见类型及常见命令

redis应用场景

  1. 缓存
  2. 计数器
  3. 排行榜
  4. 地理位置
  5. 队列
  6. 评论和弹幕

Redis6安装启动

redis官网安装教程

# 源码编译安装
wget https://download.redis.io/releases/redis-6.2.13.tar.gz
# 解压
tar zxvf redis-6.2.13.tar.gz
# 安装redis依赖
yum install gcc -y
# 进入解压包
cd redis-6.2.13/
# PREFIX指定软件安装的路径
make && make install PREFIX=/usr/local/redis6
# 创建其它目录文件
make /data/redis7001/{conf,data,log} -p
vim /data/redis7001/conf/redis.conf
# 内容
# 启动端口
port 7001
# yes后台运行
daemonize yes
# 指定redis进程pid文件路径
pidfile "/data/redis7001/data/redis.pid"
# redis日志的详细程度
loglevel notice
# 日志文件的路径和文件名
logfile "/data/redis7001/log/redis.log"
# 支持的数据库数量
databases 16
# redis的快照条件;1800秒以内只要有一次更改就执行一次快照保存(rdb落盘)
#save 1800 1
# rdb文件名称
dbfilename "dump.rdb"
# 持久性文件的目录
dir "/data/redis7001/data"

# 运行使用的最大内存量
maxmemory 1gb
# 当redis内存达到上限时所使用的淘汰策略
maxmemory-policy volatile-lru

# 是否开启aof持久化
appendonly no
# aof日志文件的名称
appendfilename "appendonly.aof"
# 慢查询时间的预值 单位 微秒
slowlog-log-slower-than 10000
# 慢查询日志的最大长度,最多记录多少条慢查询
slowlog-max-len 128

# redis的密码;生产环境建议设置密码
requirepass "IdfaUqTcdad82"
/usr/local/redis6/bin/redis-server /data/redis7001/conf/redis.conf
# 查看是否启动
ps -ef | grep redis 

# 修改环境变量
vim /etc/profile
# 增加
export PATH="/usr/local/redis6/bin:$PATH"
source /etc/profile

redis-cli -v

# 登录redis
redis-cli -p 7001 -a IdfaUqTcdad82
数据类型 描述
string 字符串类型,一个key对应一个value
hash 键值对集合
list 字符串列表,按插入顺序排队
set string类型的无序集合,集合中元素是唯一的
zset 有序集合,它类似于SET,但每个元素都会关联一个分数(score),分数用来对元素进行排序
HyperlogLog 用于估计集合基数的数据类型
bitmap 用户存储位数据,适用于布尔值和计数值
GEO 存储地理位置数据,支持地理位置相关操作

常用数据类型的用法

# 设置
set string_test aaa
# 获取
get string_test
# 删除
del string_test

# 计数
incr count_test
# 增加指定计数量
incrby count_test 3
# 减去
decr count_test
# 减去指定数量
decrby count_test 2
# 查询
get count_test
# 设置
hset user:01 name martin
hset user:01 age 18
# 获取
hget user:01 name
# 获取所有字段和值
hgetall user:01
# 获取hash表中字段数量
hlen user:01
# 获取hash表中所有字段
hkeys user:01
# 删除某个字段
hdel user:01 age
# 插入列表头部
lpush list_test aaa
lpush list_test bbb
# 获取所有元素
lrange list_test 0 -1
# 插入到列表尾部
rpush list_test ccc
# 获取指定范围的元素
lrange list_test 0 0
# 查询前两个元素
lrange list_test 0 1
# 获取列表长度
llen list_test
# 移除并且获取列表的第一个元素
lpop list_test
# 移除并且获取列表的最后一个元素
rpop list_test
# 添加元素
sadd set_test one
# 添加多个元素2
sadd set_test two three
# 返回集合中所有元素
smembers set_test
# 判断元素是否在集合中 返回1代表存在;0不存在
sismember set_test onne
# 删除集合中的元素
srem set_test two
# 添加元素
zadd zset_test 1 zhangshan
zadd zset_test 2 lishi
zadd zset_test 3 wangwu
# 查看元素
zrange zset_test 0 -1
# 查看元素和分数
zrange zset_test 0 -1 withscores
# 获取指定元素的分数
zscore zset_test "lishi"
# 从有序集合中移除元素
zrem zset_test "lishi"
# 获取有序集合元素个数
zcard zset_test
# 添加元素
pfadd hll_test "apple" "banana" "cherry"
# 获取集合中元素数量
pfcount hll_test
# 签到场景
# 第一天有签到记录
setbit user:1001 0 1
# 第二天有签到记录
setbit user:1001 1 1
# 第三天没有签到记录
setbit user:1001 2 0
setbit user:1001 4 1
# 查看某一天是否签到
getbit user:1001 1
getbit user:1001 2
# 统计签到数量
bitcount user:1001
# 增加地理位置
geoadd geo_test 20 30 "a"
geoadd geo_test 40 60 "b"
# 求a和b之前的距离 单位km
geodist geo_test "a" "b" km
# 查询指定范围的地点 经度 25 纬度 35 范围1000km以内的地点
georadius geo_test 25 35 1000 km

redis常用管理命令

redis-cli -p 7001 -a IdfaUqTcdad82
或者
redis-cli -p 7001
auth IdfaUqTcdad82
info 
# 查看某一块的信息
info CPU

redis info官方文档

keys *
keys name*
# 查找以name开头的key。--scan 扫描,--pattern 模式匹配 
redis-cli -p 7001 -a IdfaUqTcdad82 --scan --pattern "name*" 
# 并且删除,xargs 代表对前面的结果进行处理,-L 5000  每次处理5000条数据
redis-cli -p 7001 -a IdfaUqTcdad82 --scan --pattern "name*" | xargs -L 5000 redis-cli -p 7001 -a IdfaUqTcdad82 del
set hehe 1111
# 改名,重复会覆盖
rename hehe hehe_bak
get hehe_bak

或者
set one 111
# renamenx 新名字必须是之前不存在的
renamenx one two
# 返回 1 存在,0不存在
exists hehe
type hehe_bak
# 单位字节
memory usage hehe_bak
debug object hehe_bak
# key存放的内存地址:引用计数:键的编码方式:key的序列化长度:key的lru值,最近最少使用的值:键自从上一次访问的空闲时间
set martin 111
# 300秒过期
expire martin 300
# 查看过期时间
ttl martin
# 移除key的过期时间
persist martin
# 第一个窗口
SUBSCRIBE chat
# 第二个窗口
PUBLISH chat "hello redis"
# 第一个窗口就会收到对应的消息
# 默认在0数据库,切换到2
select 2
set aaa 111
info keyspace
dbsize
flushdb
flushall
# 查看所有配置
config get *
# 查看最大内存
config get maxmemory
# 查看包含关键字的配置
config get *memory*
# 修改配置
config set maxmemory 2G
# 将修改的配置持久化到配置文件
config rewrite

# 查看配置文件
vim /data/redis7001/conf/redis.conf
# 获取5条
slowlog get 5
# 查看与慢查询有关的参数
config get slow*
# slowlog-max-len 最多记录多少条慢查询记录;slowlog-log-slower-than 超过这个时间就会记录到慢查询,单位微秒
client list
client kill 192.168.12.162:50732
redis-cli -p 7001 -a IdfaUqTcdad82 info
redis-cli -p 7001 -a IdfaUqTcdad82 client list
debug segfault
ps -ef | grep 7001
# 启动
/usr/local/redis6/bin/redis-server /data/redis7001/conf/redis.conf
# 在redis命令里执行,建议此方式关闭redis
shutdown

详解Redis RDB

把内存中的数据存储到磁盘中,当redis重启会读取RDB文件恢复数据

几种RDB持久化场景

# 这个命令会在主线程执行,会导致阻塞,线上环境禁止使用
save
# 启用子进程来持久化,避免主线程阻塞
bgsave
# 查看数据目录
config get dir
# 确定bgsave是否正确执行,查看RDB相关参数
info persistence

loading:0 ;当前是否在进行RDB文件的加载操作
current_cow_size:0 ;写时复制技术占用的内存
current_cow_size_age:0 ;上一次current_cow_size的时间,单位秒
current_fork_perc:0.00 ;当前fork进程的进度百分比
current_save_keys_processed:0 ;当前RDB操作已处理keys的数量
current_save_keys_total:0 ;当前RDB持久化进程一共需要处理的键数量
rdb_changes_since_last_save:0 ;从上一次执行RDB以来更改的数量
rdb_bgsave_in_progress:0 ;是否有RDB持久化的后台进程正在进行,0表示RDB已经操作完成
rdb_last_save_time:1694702221 ;上次执行RDB持久化的时间戳
rdb_last_bgsave_status:ok ;上次执行RDB持久化的执行状态
rdb_last_bgsave_time_sec:0 ;上一次执行RDB持久化所花费的时间
rdb_current_bgsave_time_sec:-1 ;当前正在执行的RDB持久化操作花费的时间
rdb_last_cow_size:409600 ;上一次RDB持久化操作中使用的写时复制技术的内存大小
aof_enabled:0 ;
aof_rewrite_in_progress:0 ;
aof_rewrite_scheduled:0 ;
aof_last_rewrite_time_sec:-1 ;
aof_current_rewrite_time_sec:-1 ;
aof_last_bgrewrite_status:ok ;
aof_last_write_status:ok ;
aof_last_cow_size:0 ;
module_fork_in_progress:0 ;
module_fork_last_cow_size:0 ;

# 查看配置文件
vim /data/redis7001/conf/redis.conf

# 启动端口
port 7001
# yes后台运行
daemonize yes
# 指定redis进程pid文件路径
pidfile "/data/redis7001/data/redis.pid"
# redis日志的详细程度
loglevel notice
# 日志文件的路径和文件名
logfile "/data/redis7001/log/redis.log"
# 支持的数据库数量
databases 16

# redis的快照条件;1800秒以内只要有一次更改就执行一次快照保存(rdb落盘)
#⚠️save 1800 1  新增下列三行参数
save 900 1
save 300 10
save 60 10000

# rdb文件名称
dbfilename "dump.rdb"
# 持久性文件的目录
dir "/data/redis7001/data"

# 运行使用的最大内存量
maxmemory 1gb
# 当redis内存达到上限时所使用的淘汰策略
maxmemory-policy volatile-lru

# 是否开启aof持久化
appendonly no
# aof日志文件的名称
appendfilename "appendonly.aof"
# 慢查询时间的预值 单位 微秒
slowlog-log-slower-than 10000
# 慢查询日志的最大长度,最多记录多少条慢查询
slowlog-max-len 128

# redis的密码;生产环境建议设置密码
requirepass "IdfaUqTcdad82"


# 重启 或者在redis命令行执行
config set save "900 1"

在新建redis主从复制的时候,主节点会执行一次bgsave保存RDB文件到本地,然后再发送给从节点;
在执行shutdown的时候,如果没有开启aof就会自动执行bgsave将内存中的数据进行落盘,保证在启动的时候数据不会丢失。

RDB扩展

# 查看配置参数 默认开启,建议开启
config get rdbcompression
# 创建目录
mkdir /data/redis7001/tem_data
# 修改路径
config get dir
config set dir /data/redis7001/tem_data/

# 测试
bgsave

RDB注意事项

详解Redis AOF

AOF介绍

它会记录Redis收到的每一条写命令,如果Redis发生了崩溃,重启之后就会更具日志文件的内容将写操作重头到尾执行一次,以完成数据的恢复。

vim /data/redis7001/conf/redis.conf
# 修改参数
appendonly yes
# 启动

# 查看配置
config get appendonly
# 动态修改
config set appendonly yes
# 默认在数据目录

AOF相关配置

config get appendfsync

everysec :表示每秒写回,每个写命令执行完,只是先把日志写到AOF的内存缓存区,每隔一秒把缓冲区中的内容写到磁盘
always :表示同步写回,每个写命令执行完立马同步到磁盘
no :表示操作系统控制写回,每个写命令执行完只是先把日志写到AOF的内存缓存区,由操作系统决定何时将缓存区的内容写回到磁盘
配置建议: 对性能要求很高并且对数据可靠性要求不高 no;高可靠性保证always;允许数据有一点丢失,性能不受太大影响 everysec。

如果实例运行比较久并且修改比较频繁那么Redis的AOF文件可能会比较大,通过AOF重写机制解决。会把AOF的内容重写只保留可以恢复数据的最小指令集。
AOF文件为什么可以变小?

  1. 旧日志文件中的多条命令再重写后新日志中就变成了一条命令
  2. 已经过期的key就不再写入新的AOF文件中
# 手动触发一次AOF重写
bgrewriteaof

# 配置参数让AOF自动触发重写,超过一次这个大小就会触发一次AOF重写
config get "auto-aof-rewrite-min-size"
# 当前AOF文件空间超过上一次重写后AOF文件空间的多少百分比就会触发重写
config get "auto-aof-rewrite-percentage"
info persistence

loading:0 ;当前是否在进行RDB文件的加载操作
current_cow_size:0 ;写时复制技术占用的内存
current_cow_size_age:0 ;上一次current_cow_size的时间,单位秒
current_fork_perc:0.00 ;当前fork进程的进度百分比
current_save_keys_processed:0 ;当前RDB操作已处理keys的数量
current_save_keys_total:0 ;当前RDB持久化进程一共需要处理的键数量
rdb_changes_since_last_save:0 ;从上一次执行RDB以来更改的数量
rdb_bgsave_in_progress:0 ;是否有RDB持久化的后台进程正在进行,0表示RDB已经操作完成
rdb_last_save_time:1694702221 ;上次执行RDB持久化的时间戳
rdb_last_bgsave_status:ok ;上次执行RDB持久化的执行状态
rdb_last_bgsave_time_sec:0 ;上一次执行RDB持久化所花费的时间
rdb_current_bgsave_time_sec:-1 ;当前正在执行的RDB持久化操作花费的时间
rdb_last_cow_size:409600 ;上一次RDB持久化操作中使用的写时复制技术的内存大小
aof_enabled:0 ;AOF是否开启
aof_rewrite_in_progress:0 ;是否有AOF重写操作正在进行
aof_rewrite_scheduled:0 ;是否有AOF重写操作已经被调度
aof_last_rewrite_time_sec:-1 ;上一次AOF重写操作的执行时间
aof_current_rewrite_time_sec:-1 ;当前正在执行的AOF重写操作花费的时间
aof_last_bgrewrite_status:ok ;上一次AOF重写操作的执行状态
aof_last_write_status:ok ;上一次AOF写入操作的执行状态
aof_last_cow_size:0 ;上一次AOF操作中使用的cow机制内存大小,cow=copy on write 写时复制技术
module_fork_in_progress:0 ;
module_fork_last_cow_size:0 ;
aof_current_size:127 ;AOF当前大小
aof_base_size:127 ;AOF基础大小
aof_pending_rewrite:0 ;等待执行AOF重写的数量
aof_buffer_length:0 ;AOF缓冲区的大小
aof_rewrite_buffer_length:0 ;AOF重写缓冲区的大小
aof_pending_bio_fsync:0 ;等待执行AOF fsync操作的数量
aof_delayed_fsync:0 ;延迟执行AOF fsync操作的数量

  1. 写入数据
  2. 关闭Redis并删除RDB文件
shutdown
ps -ef | grep redis
cd /data/redis7001/data/
rm -rf dump.rdb
  1. 再启动Redis并确定数据
  1. 构造AOF异常场景
    修改AOF文件
  2. 重启尝试
shutdown
# 再重启,无法正常启动
# 去查看日志
cd /data/redis7001/log/
tail -f redis.log
  1. 修复AOF文件
redis-check-aof --fix ../data/appendonly.aof
# 再启动redis

Redis 7.0 AOF变化

# 控制AOF文件夹的名字
config get appenddirname
# 开启AOF
config set appendonly yes
# 进入数据目录,有个默认的文件夹 appendonlydir
cd /data/redis7201/data/
cd appendonlydir 
ls

.base.rdb ;基础的AOF,一个
.incr.aof ;增量AOF,可以有多个
.aof.manifest ;AOF的清单文件

AOF的一些相关问题

WAL :很多数据库都是采用WAL,先把修改的数据记录到日志中再进行写数据的提交,可以方便通过日志进行数据恢复
AOF :先执行写命令,再把数据写入到内存中再写日志文件;可以避免错误命令的情况,AOF是在命令执行后再记录日志所以不会堵塞当前的写操作

建议:只做缓存建议都不开启,当数据库用需要备份,可以在从库开启AOF和RDB落盘

Redis主从复制

准备复制环境

# 在从库 
# 配置主库的密码
config set masterauth IdfaUqTcdad82
# 建立关系,配置主库的ip和端口
replicaof 192.168.12.161 7001 

# 主从关系配置持久化
vim /data/redis7001/conf/redis.conf
# 新增参数
masterauth "IdfaUqTcdad82"
replicaof 192.168.12.161 7001 
# 在从库redis
info replication

Redis复制原理

Redis复制原理.jpg

复制相关维护

# 在主节点执行
info replication

slave0:ip=192.168.12.162,port=7001,state=online,offset=77035,lag=1
offset 表示从库的偏移量
master_repl_offset:77035 主库的偏移量,两个一样代表没有延迟

config get repl-backlog-size
# 在从库redis,情况主节点信息;断开后不会清除已经复制的数据
replicaof no one

复制架构调整

# 建立复制关系
config set masterauth IdfaUqTcdad82
replicaof 192.168.12.161 7001 
info replication

# 切换主节点,切换主节点会删除已经复制的数据然后复制新主节点的数据
replicaof 192.168.12.163 7001 
# 161->162->163
#在 162执行
replicaof no one
config set masterauth IdfaUqTcdad82
replicaof 192.168.12.161 7001
# 在 163执行
replicaof no one
config set masterauth IdfaUqTcdad82
replicaof 192.168.12.162 7001

# 查看复制状态
info replication

# 如果需要配置持久化
config rewrite
  1. 建议在低峰时进行新的主从配置
  2. 建议一个主节点别挂载太多的从节点
  3. 建议一台物理机上运行尽可能少的主节点

Redis主从之哨兵

哨兵的工作流程

Redis哨兵的工作流程.jpg

哨兵的选主逻辑

# 参数越小优先级越高
config get replica-priority
info replication
# salve_repl_offset 越大同步越靠前

部署哨兵集群

# 清空两台从库配置关系
replicaof no one

# 每个实例修改
config set masterauth IdfaUqTcdad82
# 在两个从库执行
replicaof 192.168.12.161 7001

# 在主库查看信息
info replication
# 在每个Redis实例 创建哨兵文件夹(3个)
mkdir /data/sentinel26379/{data,conf,log} -p
# 在每个节点增加配置文件(3个)
vim /data/sentinel26379/conf/sentinel.conf

# 哨兵端口
port 26379
# 后台运行
daemonize yes
# 日志文件
logfile "/data/sentinel26379/log/26379.log"
# 数据目录
dir /data/sentinel26379/data/
# sentinel监控的Redis,监控的集群名是mymaster,主的ip和端口,2表示至少有两个哨兵同意就进行故障切
sentinel monitor mymaster 192.16812.161 7001 2
# 被监控Redis的密码
sentinel auth-pass mymaster IdfaUgTcdad82
# 判断Reids 主观下线的阈值,单位毫秒
sentinel down-after-milliseconds mymaster 10000
# 在每个实例启动
redis-sentinel /data/sentinel26379/conf/sentinel.conf
# 查看是否启动
ps -ef|grep sentinel
# 哨兵启动后会在配置文件自动新增一些参数

哨兵常用命令

# 登录哨兵
redis-cli -p 26379
# 显示其他哨兵的状态
sentinel sentinels mymaster
sentinel masters
# 查看某一个master的状态
sentinel master mymaster
# 查看某一个master的地址
sentinel get-master-addr-by-name mymaster
# 查看被监控主的从库状态
sentinel replicas mymaster
sentinel failover mymaster
# 查看
sentinel get-master-addr-by-name mymaster
# 在去新的主查看
info replication

Go程序通过哨兵操作Redis

  1. 通过chatgpt编写操作Redis的程序

编写一个Go程序,能连接Redis的哨兵,有3个哨兵实例19216812161:26379,19216812162:26379,19216812163:26379,Redis密码是xxx
帮忙每秒往Redis里面写一个唯一的key
写入成功,输出success;
写入失败,输出错误,但是循环继续

  1. 修改代码(redis密码)
  2. 测试代码

故障切换测试

  1. 关闭住主实例并查看程序输出
# 关闭主
info replication
shutdown
  1. 分析故障恢复过程的哨兵日志
# 查看日志文件
tail -n 30 /data/sentinel26379/log/26379.log
  1. 确定新的复制架构
# 在新主查看信息
info replication
# 再启动关闭的实力
redis-sentinel /data/sentinel26379/conf/sentinel.conf
# 再查看信息
info replication

关于哨兵的建议

  1. 至少需要3个sentinel实例才能实现稳健的部署
  2. sentinel放在不同的机柜上
  3. 需要保证客户端支持sentinel

Redis Cluster架构

Redis Cluster架构.jpg

Redis Cluster部署

需要部署六台redis

# 与常规安装redis相比新增集群参数
# 开启集群
cluster-enabled yes
cluster-config0file /data/redis8001/data/nodes8001.conf
# 节点的超时事件,毫秒
cluster-node-timeout 5000

# 需要密码的话
masterauth "IdfaUqTcdad82"
# 随便一台机器执行; --cluster 表示加集群的参数;create 创建集群;后面跟集群节点;--cluster-replicas 表示每个节点分配几个从节点;-a 表示密码(生产环境也是建议每个节点分配一个从节点)
redis-cli --cluster create 192.168.12.161:8001 192.168.12.161:8002 192.168.12.162:8001 192.168.12.162:8002 192.168.12.163:8001 192.168.12.163:8002 --cluster-replicas 1 -a IdfaUqTcdad82

# 查看集群的状态
redis-cli --cluster check 192.168.12.161:8001 -a IdfaUqTcdad82

# 查看集群配置文件(启动集群后redis自动创建)
cat /data/redis8001/data/node8001.conf

集群使用

# Redis Cluster 可以通过任意一个节点redis连接集群;-c 表示按集群的方式连接redis
redis-cli -p 8001 -a IdfaUqTcdad82 -c

# 查看集群信息,在redis内执行
cluster nodes
# 查看某个key在哪个槽上
cluster keyslot aaa
# 查看某个槽有多少个key,只能查询本节点槽的数量
cluster countkeysinslot 10439
# 返回某个槽的某些key;10 查询槽中10个key
cluster getkeysinslot 13785 10

通过Go程序连接Redis Cluster

查看某些开发语言怎么连接redis官方文档

编写Go程序,需要连接带密码的Redis Cluster
每秒写入一个唯一的key
写入成功和失败都输出带时间的日志

故障恢复测试

# 登录redis后执行
shutdown
cluster nodes
# 新启动的实例会变成从节点
/usr/local/redis6/bin/redise-serrver /data/redis8001/conf/redis.conf
# 极端场景,主和从都挂掉,是否继续提供服务参数;yes 表示主和从不可用的时候整个集群就不可用;no 这个主从节点不可用,其他节点可用,但是挂的节点的数据不可查询
config get cluster-require-full-coverage

Redis Cluster扩容

# 在两台实例上各部署一个Redis
# 192.168.12.161:8003 新增的节点;192.168.12.161:8001 已经存在的任一节点
redis-cli --cluster add-node 192.168.12.161:8003 192.168.12.161:8001 -a IdfaUqTcdad82
# 查看集群状态
redis-cli --cluster check 192.168.12.161:8001 -a IdfaUqTcdad82

# 为新增的主实例添加从实例;192.168.12.162:8003 新增的节点;192.168.12.161:8001 已经存在的任一节点;--cluster-slave 以从节点加入;--cluster-master-id 主节点的id
redis-cli --cluster add-node 192.168.12.162:8003 192.168.12.161:8001 --cluster-slave --cluster-master-id 70502ee36d2476e6f39d335d56373d141daa4653  -a IdfaUqTcdad82

# 查看集群状态;此时新加的主从节点还没有槽
redis-cli --cluster check 192.168.12.161:8001 -a IdfaUqTcdad82
# 192.168.12.161:8001 集群任一节点;reshard 重新分配槽;槽总数/主从个数=新增节点的槽
redis-cli --cluster reshard 192.168.12.161:8001 -a IdfaUqTcdad82

Redis Cluster缩容

# --cluster-from 表示要迁移槽的源节点;...a4777 要迁移到哪个节点;--cluster-slots 要迁移槽的数量;192.168.12.161:8001 集群任意一节点的ip和端口
redis-cli --cluster reshard --cluster-from 70502ee36d2476e6f39d335d56373d141daa4653 --cluster-to 70502ee36d2476e6f39d335d56373d141daa4777 --cluster-slots 1365 192.168.12.161:8001 -a IdfaUqTcdad82
# 迁移时最好迁移到连续编号的槽节点
# 192.168.12.161:8001 集群任意一节点的ip和端口;...a4653 要删除的节点
redis-cli --cluster del-node 192.168.12.161:8001 70502ee36d2476e6f39d335d56373d141daa4653 -a IdfaUqTcdad82
redis-cli --cluster del-node 192.168.12.161:8001 70502ee36d2476e6f39d335d56373d141daa4666 -a IdfaUqTcdad82
# 查看集群状态
redis-cli --cluster check 192.168.12.161:8001 -a IdfaUqTcdad82

Redis Cluster原理解析

Redis Cluster采用虚拟槽分区,一个集群有16384个虚拟槽,虚拟槽类似数据分区,每个键值对都会根据它的key再按照CRC16算法计算一个16bit的值,然后这个16bit的值对16384进行取模,通过模来映射到槽中。

# 有时候想要某些key在一个槽里面,可以用哈希标签
redis-cli -p 8001 -a IdfaUqTcdad82 -c
set {user001}.name aaa
set {user001}.email aaa@qq.com
# 查看在哪个槽
cluster keyslot {user001}.name
# 查看这个槽下所有key
cluster getkeysinslot 1390 10

# 不能过度使用,可能会导致数据分表不均匀

在客户端和集群建立连接后,实例就会把hash槽的分片信息发送给客户端,每个实例会把自己的hash槽信息发送给集群内其它实例,这样每个实例都会知道所有hash槽和实例的对应关系。

集群内每个节点都会定期向集群中其它节点发送ping命令,互相探测,这样可以交换节点状态信息。

# 选取资格判断参数
config get cluster-node-timeout

# 如果这个参数设置为0,那么不管断开多久多会参与选举
config get cluster-slave-validity-factor

Redis Cluster的优势

  1. 无中心架构
  2. 动态扩缩容
  3. 高可用性

Redis Cluster的限制

  1. key批量操作支持有限
  2. 不能将一个大的键值对象映射到不同的节点
  3. 只支持单个库
上一篇 下一篇

猜你喜欢

热点阅读