redis
2020-05-11 14:34:18 0 举报
AI智能生成
redis知识点总结
作者其他创作
大纲/内容
全局命令
keys pattern
scan cursor
flushdb flushall
dbsize
exists key
expire key seconds,pexpire key millin
expireat key timestamp
persist key
ttl key,pttl key
rname key newkey
type key
object encoding key
object idletime key
del key
migrate迁移key
config set 配置名 配置值
config get 配置名
独立功能
位图(bitmaps)
setbit key offset 0|1
getbit key offset
bitcount [start][end]
多个key之间的位运算
bitop and destkey key[key...]
bitop or destkey key[key...]
bitop not destkey key[key...]
bitop xor destkey key[key...]
bitops key targetBit [start][end]
hyperLogLog
GEO
发布订阅
publish channelName message
subscribe channelName[channelName...]
unsubscribe channelName
psubscribe pattern
punsubscribe pattern
pubsub channels [pattern]
pubsub numsub [channelName...]
pubsub numpat
slow log
配置
slowlog-log-slower-than
slowlog-max-len
slowlog get n(条数)
slowlog len
slowlog reset
事务
multi 业务命令 exec
discard
watch
pipeline
lua
原理
lua环境
伪客户端
脚本字典
命令
eval lua脚本内容 key个数 key列表 参数列表
evalsha sha1 key个数 key列表 参数列表
script load lua脚本
script exists sha1[sha2...]
script flush
script kill
脚本复制
eval、script load、script flush会直接复制到从服务器上直接执行
evalsha
lua-time-limit
监视器
monitor
持久化
RDB
RDB文件持久化
手动触发
save命令
bgsave命令
自动触发
配置多长时间内数据集发生多少次修改触发自动RDB备份
从节点进行全量复制时触发主节点自动RDB备份
shutdown时若没开启AOF则触发RDB备份
RDB文件恢复redis
AOF
AOF文件文件持久化
命令追加(append)
aof_buf缓冲
文件写入
文件同步(sync)
always
everysec
no
定期AOF文件重写
触发机制
手动触发bgrewriteaof
自动触发
子进程写
子主题
aof重写缓冲区
重写缓冲区内容刷盘
AOF文件替换
载入与数据还原
AOF伪客户端(不带网络连接)
解析命令
伪客户端执行命令
键过期删除
键过期判定
删除策略
定时删除
惰性删除
定期删除
快模式 超时时间25毫秒
慢模式 超时时间1毫秒
redis使用的删除策略 定期删除+惰性删除
过期相关的文件
RDB
AOF
主从复制
客户端
客户端调用
发送命令
命令排队
执行命令
返回结果
命令
client list
id:客户端id
name:客户端name
addr:客户端的ip+端口
fd:套接字socket的文件描述符
qbuf:输入缓冲区总容量
qbuf_free:输入缓冲区剩余容量
obl:固定输出缓冲区长度
oll:动态输出缓冲区长度
omem:输出缓冲区已使用的字节数
age:客户端已经连接的时长
idle:客户端已经空闲的时长
maxclients:允许的最大客户端数,一旦超过新连接被拒绝
timeout:最大空闲时间,一旦超过,连接被关闭
flag:客户端类型
info clients
connected_clients:代表当前Redis节点的客户端连接数
client_biggest_input_buf 当前所有输入缓冲区中占用的最大容量
client_longest_output_list 当前所有输出缓冲区中队列对象个数的最
大值
大值
blocked_clients 正在执行阻塞命令(例如blpop、brpop、 brpoplpush)的客户端个数
info stats
total_connections_received:Redis自启动以来处理的客户端连接数总数
rejected_connections:Redis自启动以来拒绝的客户端连接数
client setName xxx | client getName
client kill ip:prot
client pause time(毫秒)
缓冲区
输入缓冲区
bigkey导致输入缓冲区爆满
阻塞导致输入缓冲区爆满
输出缓冲区
固定缓冲区obl (16k)
动态缓冲区oll
调优
适当增大slave客户端的输出缓冲区
限制monitor命令的使用
监控内存抖动
配置
maxclients
timeout
tcp-keepalive
tcp-backlog
常见问题
无法从连接池获取到连接
1、检查代码中配置的连接池个数是否太小
2、检查代码中是否归还连接
3、检查redis的maxclients配置
4、检查是否存在慢查询,导致连接不够用
客户端读写超时
1、检查读写超时配置
2、检查slowlog,是否存在阻塞
3、检查网络
客户端连接超时
1、检查连接超时时间配置
2、检查tcp-backlog配置
客户端缓冲区异常
1、使用info clients检查缓冲区
2、检查是否有bigkey
3、检查是否有monitor客户端存在
框架
jedis
基于bio
redission
基于netty
lettuce
基于netty
服务器
事件驱动
文件事件处理器
套接字
I/O多路复用程序
文件事件分派器
文件事件
客户端连接->AE_READABLE事件
客户端写入->AE_READABLE事件
客户端read操作->AE_WRITABLE事件
客户端关闭->AE_READABLE事件
事件处理器
定时任务(时间事件)
无序链表
时间事件执行器
应用场景
定期更新服务器各类统计信息,内存、时间、数据库占用情况
定期清理过期key
关闭和清理连接失效的客户端
尝试进行AOF或者RDB持久化操作
主服务器,定期对从服务进行同步
集群模式下,对集群定期同步和连接测试
命令执行过程
客户端将命令转换为协议格式发送给服务器
当事件为可读时,命令请求处理器处理命令
读取套接字中的命令请求并保存到客户端的输入缓冲区
解析命令,提取命令参数和参数个数
调用命令执行器执行命令
检查输入的命令是否合法
检查内存使用情况,是否需要先进行内存回收
调用命令的实现函数
将命令的返回结果写入客户端输出缓冲区,并关联事件回复处理器
如果开启慢查询日志,判断是否添加慢查询
若开启AOF,则将命令请求写入AOF缓冲区和AOF重写缓冲区
如果有从节点,将命令传播给所有从节点(异步)
当客户端为可写的时候,事件回复处理器将命令回复内容发送给客户端,并清空输出缓冲区
内存模型
命令
info memory
used_memory
used_memory_rss
mem_fragmentation_ratio
mem_allocator
jemalloc分配器(默认)
glibc分配器
tcmalloc分配器
结构
进程本身占用内存
fork子进程的时候会消耗
数据占用内存
缓冲内存
客户端输入缓冲区
客户端输出缓冲区
复制积压缓冲区
AOF缓冲区
AOF重写缓冲区
内存碎片
重启服务器解决内存碎片
频繁的更新和键过期会导致内存碎片
内存管理
设置maxmemory
设置0的时候不限制,会无限使用内存
如果内存达到该值,会触发内存淘汰策略
内存淘汰策略
noeviction(默认)
volatile-lru
allkeys-lru
allkeys-random
volatile-random
volatile-ttl
虚拟内存
只有value可能会置换到磁盘上,key对象不会
vm-enabled = yes开启虚拟内存
vm-max-memory 使用内存超过该值时将value存储到磁盘上
vm-page-size 配置虚拟内存磁盘页大小
vm-max-threads 操作文件交换的io线程个数
配置
maxmemory
maxmemory-policy
maxmemory-samples
优化
使用整型/长整型节约空间,利用对象共享
设置合理的内存淘汰策略
减小key的长度
使用高效的键值压缩算法,如protostuff
使用合适的对象类型,如使用hash替换string
编码优化,调整参数控制对象的内部编码
关注碎片化率,调整内存大小
关闭虚拟内存
数据库
dict
expires
数据结构
SDS
int(long类型的整数)
embstr编码的简单动态字符串
raw
双端双向链表linkedlist
字典hashtable
跳跃表skiplist
整数集合intset
压缩列表ziplist
对象
字符串(string)
setnx
set xx
mset key value[key value]
mget
incr key ,decr key,incrbyfloat
append key value
getset key value
getrange key start end
哈希(hash)
hset key field value
hsetnx
hget key field[field...]
hdel key field[field...]
hlen key
hmset key field value[field value...]
hmget key field[field...]
hexists key field
hkeys key
hvals key
hgetall key
hincryby key field
列表(list)
rpush key value[value...]
lpush key value[value...]
lrange key start end
linsert key before|after prekey value
lindex key idx
llen key
lpop key, rpop key
lrem key count value
ltrim key start end
lset key idx value
blpop key[key...] timeout,brpop key[key...] timeout
集合(set)
sadd key ele[ele...]
srem key ele[ele...]
smembers key
scard key
sismember key ele
spop key
集合之间操作
sinter key[key...]
suion key[key...]
sdiff key[key]
有序集合(zset)
zadd key score member[score member...]
zcard key
zscore key member
zrank key member,zrevrank key member
zrem key member[member...]
zincrby key score member
zrange key start end,zrevrange key start end
zrangebyscore key min max, zrevrangebyscore key min max
zremrangebyrank key start end
zremrangebyscore key min max
集合间操作
zinterstore
zunionstore
高可用
复制
命令
slaveof ip port
slaveof no one
slaveof{newMasterIp} {newMasterPort}
psync
psync <runid> <offset>
info relication
原理
初始同步
从节点保存主节点ip和端口信息
从节点定时任务每秒跟新的主节点建立套接字连接
连接成功后从节点发送ping命令
主节点pong回复
权限验证
从节点向主节点发送psync命令
主节点fork子线程生成rdb文件,发送给从节点
从节点清空数据后加载RDB文件
断线重同步
实现原理
主复制偏移量
从复制偏移量
主复制积压缓冲区
主节点运行id
同步类型
部分重同步
完全重同步
实时命令传播
异步
延迟
心跳(用于补发同步缺失内容)
主服务器发起的心跳检查
从服务器发起的心跳检查
配置
slave-read-only=yes
repl-timeout
repl-diskless-sync
repl-disable-tcp-nodelay
repl-ping-slave-period
repl-backlog-size
min-slaves-to-write
min-slaves-max-lag
slave-serve-stale-data
拓扑结构
一主一从
一主多从
树状主从结构
常见问题
避免全量复制
主节点运行id重启后改变
复制积压缓冲区不足
主从配置不一致
主从数据不一致
数据延迟
哨兵
目的就是为了解决主从复制无法自动故障转移的问题,实现以下步骤的自动化
1、挑选一个从节点升级为主节点 slaveof no one
2、控制其他从节点同步新的主节点
3、监控已经下线的主节点,当其上线的时候同步新的主节点
4、通知客户端连接新的主节点
哨兵是什么
运行在特定模式下的redis服务器
不存储信息
不持久化文件
基于Raft算法构建集群,所以部署3+奇数个节点
集群各节点之间是平等的
重新指派主节点时,哨兵需要基于raft算法选出一个leader去操作
可以监控多个主从架构
redis-sentinel redis-sentinel-26379.conf 启动命令
配置提供者,不是代理,客户端连接时提供主节点信息
原理
配置文件指定要监控的主节点的信息,哨兵每个节点都使用 masters字典存储监控节点信息
三个定时
每10秒向主节点(发现的从节点)发送 info 命令,获取到主从节点信息,新发现的从节点信息存储到 slaves字典中
每隔2秒向所有数据节点的__sentinel__:hello频道发送哨兵节点信息以及对主从判断的信息
每隔1秒每个Sentinel节点会向主节点、从节点、其余Sentinel节点 发送一条ping命令做一次心跳检测,用于判断主观下线
每个哨兵节点都通过订阅__sentinel__:hello频道,发现其他哨兵节点,存储并建立连接
所有结点(哨兵、主从节点)互相建立通信
ping检测主观下线 vs 客观下线
哨兵选leader
故障转移
客户端连接
1、客户端连接时,Sentinel节点集合和 masterName两个参数
2、遍历Sentinel节点集合获取一个可用的Sentinel节点
3、通过sentinel get-master-addr-by-name master-name这个API来获取对应 主节点的相关信息
4、验证当前获取的“主节点”是真正的主节点,这样做的目的是为了防止故障转移期间主节点的变化
5、客户端基于获取的主节点信息,初始化连接池
6、订阅哨兵节点上的+switch-master频道,当哨兵节点进行故障转移后会发布新主节点的信息,客户端重新初始化新主节点连接池
实现
连接阶段
1、每个哨兵节点获取配置文件中配置的监控主节点,与其建立网络连接
2、订阅主节点的频道__sentinel__:hello
3、哨兵节点定时每10秒向主节点发送命令 info ,获取主节点和从节点信息
4、哨兵节点将获取到的从节点信息存储到 slaves 字典中
5、哨兵节点跟发现的从节点建立连接
6、哨兵节点订阅从节点的频道 __sentinel__:hello
7、哨兵节点定时每10秒向从节点发送命令 info ,获取主从复制信息
8、哨兵节点定时每2秒向监控的主、从节点的channel发布消息,将哨兵节点信息和监控的节点信息发布出去
9、哨兵节点订阅了频道,通过频道获取到其他哨兵节点信息(过滤掉自己发布的消息),将信息记录到sentinels字典中
10、每个哨兵节点都创建连向其他已知哨兵节点的命令连接,保持通信
监控阶段
11、哨兵节点定时每秒向与他创建了命令连接的实例(主、从、其他哨兵节点)发送PING命令,检测是否在线
12、通过ping命令,如果指定时间内(down-after-milliseconds)一直没有有效回复,则认定对方主观下线
主节点被认定主观下线
从节点被认定主观下线
哨兵节点被认定主观下线
13、主节点客观下线认定
1、主节点被认定主观下线
2、哨兵节点询问其他哨兵节点是否也认可该主节点下线
3、向其他哨兵发送命令 sentinel is-master-down-by-addr <ip> <port> <current_epoch> <runid>
4、收到命令的哨兵节点通过ping命令判断该主节点是否客观下线
5、基于流言协议,如某个哨兵节点在给定的时间范围内,从其他哨兵节点那接收到了足够数量的主节点下线报告,那么该哨兵节点就会将主服务器的状态从主观下线改变为客观下线
6、主节点被 Sentinel 标记为客观下线后,Sentinel向下线主节点的所有从节点发送 INFO 命令的频率,会从 10 秒一次改为 每秒一次
故障转移阶段
14、当认定主节点客观下线之后,执行故障转移操作
1、哨兵节点选leader,Raft算法
每个在线的Sentinel节点都有资格成为领导者,当它确认主节点主观下线时候,会向其他Sentinel节点发送sentinel is-master-down-by-addr命令,要求将自己设置为领导者
收到命令的Sentinel节点,如果没有同意过其他Sentinel节点的sentinel is-master-down-by-addr命令,将同意该请求,否则拒绝
如果该Sentinel节点发现自己的票数已经大于等于max(quorum, num(sentinels)/2+1),那么它将成为领导者
如果此过程没有选举出领导者,将进入下一次选举。
2、leader挑选从节点,状态良好、数据完整的从节点
1、剔除断线的从节点
2、剔除5秒内没有回复哨兵info命令的从节点
3、优先选择优先级配置最高的从节点
4、优先级相同的情况下,选择复制偏移量最大的从节点
5、如果都一样,选取runid最小的从节点
3、将从节点升级为主节点,slaveof no one
4、其他从节点复制新的主节点
5、监控掉线的旧主节点,上线后复制信的主节点
6、Sentinel 都会向被重新配置的实例发送一个 CONFIG REWRITE 命令, 确保这些配置会持久化在硬盘里
通知阶段
故障转移成功后,向+switch-master频道发布新老主节点消息
客户端监听该频道获取新主节点信息,重新初始化连接池
或者可以通过client-reconfig-script配置的脚本修改vip
配置
down-after-milliseconds
parallel-syncs
failover-timeout
notification-script
client-reconfig-script
集群
原理
无中心化,基于流言协议达到一致性状态
槽概念
集群分了16384槽,每个节点负责一部分槽,直到所有槽都有负责的节点
每个节点有个位序列,存储是否负责某个槽
CRC16(key) mod 16384 获取key应该落到哪个槽
槽是数据管理和数据迁移的基本单位
重定向客户端
客户端随机连接集群中的某个节点
集群中每个节点都存储了槽到节点的映射关系
当访问的节点不负责该key对应的槽时,会返回重定向,客户端访问负责该槽的节点
重新分片
key到槽的映射关系不会变化
槽到集群节点的映射关系会变化,变化时重新分片
重新分片就是将一个节点上部分槽中所有数据迁移到另一个节点上,并修改节点负责的槽信息
MIGRATING状态
IMPORTING状态
过程
1、以集群模式启动所有集群节点
配置cluster-enabled yes
2、各节点直接通过meet建立连接
随机中集群中某个节点,执行 cluster meet {ip} {port},将该节点加入集群
3、分配槽
将16384个槽分配给集群节点
必须要保证所有的槽都分配完毕,集群才能处于上线状态
4、指定主从关系,集群中每个主节点有n个从节点
命令
cluster info
子主题
常见问题
架构选择
单点
优缺点
架构简单、部署方便
节省资源
无法保证高可用
不保证数据可靠性
单节点写瓶颈
结构
主从
优缺点
保证了数据的可靠性
可以支持读写分离,提高了读操作的并发量
无法保证高可用,主节点挂了之后,需要人工介入
单节点写瓶颈
结构
哨兵
优缺点
实现了高可用,哨兵实现自动故障转移
相对于主从部署复杂,哨兵集群需要额外占用机器
没有解决单点写瓶颈问题
sentinel+keepalived(vip)
集群
Twemproxy
Codis
Redis Cluster
阻塞
分布式锁
子主题
redlock
缓存一致性问题
缓存穿透
缓存 null值
布隆过滤器,将所有可能存在的key存到bitmap中,不存在的key会被过滤掉
缓存雪崩
加锁或者队列的方式保证单线程读取数据库进行缓存重建
缓存reload机制,预先去更新缓存,在即将发生大并发访问前手动触发加载缓存
不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀
做多份缓存,一份不存在的时候,访问另外一份
热点key问题
构建本地缓存,避免打到redis
构建Proxy代理层,路由实现读写分离
如果可以将key值拆分成多个key,分散一下
bigkey问题
监控bigkey
在proxy层,对每一个 redis 请求进行收集上报;
拆分bigkey
字符串拆分多个key或者使用hash
集合拆分为多个集合
0 条评论
下一页