内部编码:根据当前值的类型和长度决定使用哪一种编码node
set key field
内部编码:redis
hash-max-ziplist-entries
和全部值小于hash-max-ziplist-value
内部编码:算法
hash-max-ziplist-entries
和全部值小于hash-max-ziplist-value
内部编码:数据库
set-max-intset-entries
配置内部编码:后端
set-max-ziplist-entries
配置slowlog show get [n]
;采用队列存储,先进先出形式max-len > 1000
& slower-than 1ms
Redis的批量命令与Pipeline区别:数组
Lua脚本:Redis脚本语言缓存
setbit key offset value
bitop [and(交集) | or(并集) | not(非) | xor(异或)] destkey [keys...]
发布者客户端向指定的频道(channel)发布消 息,订阅该频道的每一个客户端均可以收到该消息安全
publish
发布,subscrible
订阅地理信息定位功能:支持存储地理位置信息来实现诸如附近位置、摇一摇这类依赖于地理位置信息的功能;底层实现是:zset服务器
客户端通讯协议:基于TCP协议定制RESP实现交互的
RESP协议优势:a)实现容易;b)解析快;c)人类可读网络
1.没法从链接池中获取到链接
对象个数默认是8个:
blockWhenExhausted=false
表明链接池没有资源可能的缘由:
- 链接池设置太小
- 没有释放链接
- 存在慢查询操做
- 服务端命令执行过程被堵塞
2.客户端读写超时
1.读写超时时间设置太短
2.命令自己比较慢
3.客户端与服务端网络不正常
4.Redis自身发生堵塞
3.客户端链接超时
1.链接超时设置太短
2.Redis发生堵塞,形成tcp-backlog已满
3.客户端缓冲区异常
4.输出缓冲区满
5.长时间闲置链接被服务端主动断开
6.不正常并发读写
4.Lua脚本正在执行,并超过lua-time-limit
5.Redis正在加载持久化文件
6.Redis使用的内存超过maxmemory配置
7.客户端链接数过大
RDB持久化:把当前进程数据生成快照保存到硬盘的过程,触发RDB持久化分为手动触发和自动触发
bgsave
命令Redis进程执行fork操做建立子进程,由子进程负责完成自动触发:
sava m n
(表示m秒内数据集存在n次修改即自动触发bgsave)bgsave
生成RDB文件并发送给从节点debug reload
命令从新加载Redis时,也会自动触发save操做shutdown
命令时,若是没有开启AOF持久化功能则自动执行bgsaveRDB优势:
RDB缺点:
AOF持久化:以独立日志的方式记录每次写命令,重启时再从新执行AOF文件中的命令达到恢复数据的目的,解决数据持久化的实时性
1.命令写入以追加方式到AOF_buf
2.AOF缓冲区根据策略同步到AOF文件
3.随着AOF文件变大,须要按期对AOF文件进行重写,达到压缩目的
4.当Redis重启时,能够加载AOF文件进行数据恢复
命令写入追加到缓冲区的目的:
同步策略:Redis提供多种AOF缓冲区同步文件策略,由appendfsync控制
- write操做:会触发延迟写机制,由于Linux在内核提供页缓冲区来提供磁盘IO性能;write操做在写入系统缓冲区后直接返回,同步硬盘依赖于系统调度机制
- fsync操做:针对单个文件操做作强制硬盘同步,fsync将阻塞直到写入硬盘完成后返回,保证了数据持久化
重写机制:把Redis进程内的数据转化为命令同步到新AOF文件的过程,这个过程会让AOF文件体积变小,从而提升恢复时的效率
1.进程已经超时的数据再也不写入新文件
2.经过进程内数据直接生成,避免旧文件中的无效命令
3.多条命令能够合并为一个
AOF重写触发方式:
手动触发:执行bgrewriteaof命令
自动触发:同时知足如下2个条件
1.auto-aof-rewrite-min-size
:表示运行AOF重写时文件最小体积,默认为64MB
2.auto-aof-rewrite-percentage
:表示当前AOF文件空间和上一次重写后AOF文件空间的比值
Redis持久化加载流程
关于AOF文件异常
redis-check-aof-fix
命令修复后,进行对比并进行手工修改补全)AOF追加阻塞:当开启AOF持久化时,经常使用的同步磁盘策略是everysec,对于这种方式,Redis会使用同步条线程每秒执行fsync同步硬盘,当系统硬盘资源繁忙时,会形成Redis主线程阻塞
everysec刷盘策略过程:
1.同步线程负责每秒调用fsync操做进行同步磁盘
2.主进程会去对比上次fsync同步时间,若是在2s内则经过,不然会堵塞(磁盘资源紧张)
3.everysec策略最多可能丢失2s数据;若是系统fsync缓慢,会致使主进程堵塞
AOF优势:
AOF缺点:
创建复制的3种方式:
slaveof [masterHost] [masterPort]
redis-server --slaveof [masterHost] [masterPort]
slaveof [masterHost] [masterPort]
断开复制:命令1操做后从节点晋升为主节点;命令2操做后能够完成切主操做
slaveof no none
slaveof [newmasterHost] [newmasterPort]
安全性:主节点经过requirepass参数
进行密码验证来保证数据安全性
slave-read-only=yes
配置为只读模式;由于从节点的数据没法同步给主节点传输延迟:主从节点通常部署在不一样机器上,复制时的网络延迟成为须要考虑的问题
repl-disable-tcp-nodelay=yes
时:表明关闭,主节点产生的命令不管大小都会及时发送给从节点,这样作延迟会变小,可是增长了网络带宽消耗repl-disable-tcp-nodelay=no
时:表明开启,主节点会合并比较小的TCP数据包从而节省网络带宽消耗,可是这样增长了主从之间的延迟复制过程:
1.保存主节点信息:IP+Port
2.创建socket链接
3.发送ping命令:a)检测socket是否可用;b)判断主节点是否能处理命令
4.权限验证
5.同步数据集:首次创建复制,主节点会把数据集所有发往从节点
6.命令持续复制:主节点把持续写命令复制给从节点,保持数据一致性
全量复制过程
部门复制过程
心跳判断:主从节点创建链接后保持长链接
repl-ping-slave-period
控制发送频率)repl-timeout
配置的值(默认60秒),则断定从节点下线并断开复制客户端链接补充知识点:
Redis是单线程架构:全部读写操做都是串行的而会致使阻塞问题
内在缘由:不合理使用API或数据结构、CPU饱和、持久化阻塞
外在缘由:CPU竞争,内存交换,网络问题等
info
,查看blocked_clientsredis-cli --latency -h -p
查看延时状况不合理使用API或数据结构:好比执行hgetall
获取的数据量会很是大
redis-cli <ip+port> bigkeys
(大于10K)重点指标:mem_fragmentation_ratio
mem_fragmentation_ratio = used_memory_rss / used_memory
used_memory_rss: 系统认为Redis使用的物理内存
used_memory: 内部存储的全部数据占用量
当mem_fragmentation_ratio > 1
表示存在内存碎片
当mem_fragmentation_ratio < 1
表示存在交换内存
Redis内存消耗划分
Redis使用maxmemroy
参数限制最大可用内存,限制内存的主要目的:
1.缓存场景:当超过内存上限时根据淘汰策略删除键释放内存
2.防止所用内存超过物理内存(限制的是used_memory;因此考虑内存溢出)
内存回收策略
删除过时键带有
内存溢出控制策略:当达到maxmemory
自动触发
1.关于volatile-lru和volatile-ttl控制策略:若是没有,会回退到noeviction控制策略
2.在Redis的LRU算法中:能够经过设置样本的数量来调优算法精度(参数:maxmemory-samples 5->10
)
内存优化总结
1.精简键值对大小,键值字面量精简,使用高效二进制序列化工具。
2.使用对象共享池优化小整数对象。
3.数据优先使用整数,比字符串类型更节省空间。
4.优化字符串使用,避免预分配形成的内存浪费。
5.使用ziplist压缩编码优化hash、list等结构,注重效率和空间的平衡。
6.使用intset编码优化整数集合。
7.使用ziplist编码的hash结构下降小对象链规
主从架构问题:
Sentinel架构问题:
Cluster架构问题
Sentinel节点集合会按期对全部节点进行监控,从而实现主从的故障自动转移
监控任务
主观下线和客观下线
领导Sentinel节点选举:故障转移工做的执行者
故障转移过程:
slave no one
命令让其成为主节点slot=CRC16(key)&16383
。每个节点负责维护一部分槽以及槽所映射的键值数据Gossip消息分类:ping/pong/meet/fail
请求路由:使用客户端去操做集群
故障转移
故障发现:经过ping/pong消息实现节点通讯
恢复流程:
开发和运维常见问题::超大规模集群带宽消耗, pub/sub广播问题,集群节点倾斜问题,手动故障转移,在线迁移数据等
缓存收益:a)加速速度;b)减小后端负载
缓存成本:a)数据不一致性;b)代码维护;c)运维
缓存场景:a)开销大的复杂计算;b)加速请求响应
LRU/LFU/FIFO算法剔除:缓存使用量超过设定的最大值(maxmemory-policy
配置剔除策略)
超时剔除:缓存数据设置过时时间
主动更新:数据一致性要求高,须要真实数据更新后立马更新缓存数据
最佳实践
缓存穿透:查询一个根本不存在的数据,致使不存在的数据每次请求都要到存储层去查询,会使后端存储负载加大
基本缘由:
1.自身业务代码或者数据出现问题
2.恶意攻击、爬虫等形成大量空命中
解决办法:
1.缓存空对象
2.布隆过滤器
缓存雪崩:缓存层宕掉后,流量会忽然所有打到后端存储
预防和解决缓存雪崩问题:
1.保证缓存层服务高可用性
2.依赖隔离组件为后端限流并降级
问题缘由:当前key是一个热点key,并发量很是大而重建缓存又不能在短期内完成
解决办法:互斥锁、“永远不过时”可以在必定程度上解决热点key问题
内存分配控制优化:
1.Redis设置合理的maxmemory
,保证机器有20%~30%的限制内存
2.设置vm.overcommit_memory=1
,防止极端状况下形成fork失败
Swap交换内存优化:当物理内存不足时,系统会使用swap致使磁盘IO会成为性能瓶颈
权值越大,使用swap几率越高:0-100 默认60:
echo "vm.swappiness={bestvalue}" >> /etc/sysctl.conf
OMM killer: 当内存不足时选择性杀死进程
下降redis优先级:
echo {value} > /proc/{pid}/oom_adj
Transparent Huge Pages:虽然能够加快fork操做,可是写时内存copy消耗从4KB-2MB
关闭大页:
echo never > /sys/kernel/mm/transparent_hugepage/enabled
打开文件描述符:
由于openfile
优先级大于redis maxclients
/etc/rc.local配置文件中:ulimit -Sn {max-open-files}
Tcp backlog: Tcp链接队列长度
调高全链接队列值:默认是511
echo 10000 > /proc/sys/net/core/somaxconn
快速恢复数据:
1.防止AOF重写
2.去掉AOF文件中的flush相关内容
3.重启Redis服务器,恢复数据
危害:
1.网络拥塞
2.超时堵塞
3.内存空间不均匀
定位:找到键的serializedlength信息,而后判断指定键值的大小
1.debug object key
2.strlen key
3.主动检测:scan+debug object
;而后检测每一个键值的长度
补充:使用redis-cli -h[ip] -p[port] bigkeys
命令(内部进行scan操做,把历史扫描过的最大对象统计出来)
优雅删除:直接删除全部bigkey可能会致使堵塞
能够结合Python的RedisAPI编写脚本去实现:
1. hash key:经过hscan
命令,每次获取500个字段,再用hdel
命令
2. set key:使用sscan
命令,每次扫描集合中500个元素,再用srem
命令每次删除一个元素;
3. list key:删除大的List键,经过ltrim
命令每次删除少许元素。
4. sorted set key:删除大的有序集合键,和List相似,使用sortedset自带的zremrangebyrank
命令,每次删除top 100个元素。
后台删除: lazyfree机制