Redis
2021-11-12 11:27:58 0 举报
AI智能生成
针对于Java体系中,Redis的常见使用方式
作者其他创作
大纲/内容
问题
redis性能为什么可以这么高?
网络IO和键值对的读写是单线程
利用Epoll机制实现IO多路复用,将连接信息和事件放到队列中,再依次放到文件事件分派器,事件分配器发送给事件处理器
脑裂问题?
因Master和Slave失去联系导致重新选举,会出现多个Master;此时会将其中一个Master变成Slave,该Master在这段时间所持有的数据则会进行丢失
解决方案
利用配置,至少保证有一个节点同步完成数据后才算成功
数据一致性如何保障(db和内存)?
先更新数据库,再更新缓存(双写不一致)-不推荐
问题
1.某个线程更新db与缓存间存在延迟,导致另外一个线程已经将数据同步完成,则导致缓存脏数据
场景
适合于读多写少,以免频繁更新缓存
先删缓存,再更新数据库
问题
1.某个线程删除和更新数据库之间存在延迟,导致另外一个线程将脏数据写入缓存中
优化
延迟双删策略
也就是更新数据库后,延迟一段时间,再删除缓存一次
说明
其实这种情况也百分百做不到,和延迟时间有关系,并且延迟时间不好把握
场景
适合读写适中的场景
先更新数据库,再删除缓存(读写不一致)
问题
某个线程更新数据库,再删除缓存;但是另外线程先读取旧数据,然后重新写入缓存,问题依旧存在
场景
适合写多读少的场景
引入同步中间件Canal
不在业务层面人为解决同步问题,只在中间件解决,db和缓存最终一致的问题
说明
强一致性下,不考虑缓存,使用缓存,就是为了应对读多写少的场景
数据
自身
如果是自身的数据,没必要保证db和数据库一致性即可,采用哪种策略都可以,只要设置好缓存失效时间即可
全局
数据库和db保持一致性,前提是多线程修改全局数据,也就是有的线程修改,有得查询;
个人思考
其实或多或少都存在问题,关键看你们的业务适合哪一个,大致就是以上的场景设置,挨个套用下看看
缓存问题?
击穿
单个key击穿
方案
多级缓存
不同失效时间
穿透
大量不存在的key
方案
布隆过滤器
缓存空对象
雪崩
大量的key失效
方案
由于缓存失效,导致Db失效的问题
热点缓存Key重建
数据结构
字符串
分布式锁
SetNx
计数器
Incr自增
分布式系统全局序列号
IncrBy
Hash
对象缓存
value=对象属性信息
购物车
存储用户购买商品
存储商品数量
增加商品数量
不适用场景
Redis集群
比String更节省内存
List
微博和微信公众号消息
当做一个队列来使用,进行消息的读取
Set
微信公众号抽奖
选中后删除
选中后不删除
点赞
点赞、取消点赞
获取点赞人数
检查是否点赞过
微博微信关注模型
利用集合操作的特性
搜索商品
Sorted Set
排行榜->利用分值特性
持久化
RDB
触发条件
N 秒内数据集至少有 M 个改动
指令
Save
BgSave
写时复制机制
fork子线程,将内存数据库中的数据同步到dump.rdb的文件中
dump.rdb
AOF
appendonly.aof
触发条件
修改的每一条指令记录进文件appendonly.aof中(先写入os cache,每隔一段时间
fsync到磁盘)
fsync到磁盘)
策略
appendfsync always:每次有新命令追加到 AOF 文件时就执行一次 fsync ,非常慢,也非常安全。
appendfsync everysec:每秒 fsync 一次,足够快,并且在故障时只会丢失 1 秒钟的数据。-推荐
appendfsync no:从不 fsync ,将数据交给操作系统来处理。更快,也更不安全的选择。
问题
导致文件中记录太多无效的指令
优化
AOF重写
策略
auto‐aof‐rewrite‐min‐size 64mb //aof文件至少要达到64M才会自动重写,文件太小恢复速度本来就
很快,重写的意义不大
很快,重写的意义不大
auto‐aof‐rewrite‐percentage 100 //aof文件自上一次重写后文件大小增长了100%则再次触发重写
手动的方式
执行命令bgrewriteaof重写AOF;类似于RDB中的bgSave指令
混合持久化
1.重写这一刻之前的内存做RDB快照处理
2.将RDB快照内容和增量的AOF修改内存数据的命令存在一起
注意
以上操作过程产生的文件并不直接叫做apponly.aof,完成重写后,会直接覆盖原有的文件
延伸
管道操作
客户端可以一次性发送多个请求而不用等待服务器的响应,待所有命令都发送完后再一次性读取服务的响应
特点
管道中前面命令失败,后面命令不会有影响,继续执行
Lua脚本操作
原先5次请求的逻辑放在redis服务器上完成。使用脚本,减少了网络往返时延
特点
原子性的
策略
过期键策略
被动
读写的时候发现过期了才触发删除策略
主动
定时主动删除过期的键
主动和被动哪种方式好呢
内存超出预设值-MaxMemory,触发淘汰策略
redis4.0之前有六种
带过期时间
LRU
最近最少使用
时间为单位
LFU
最不经常使用
次数单位
随机
按照过期时间先后顺序
不带过期时间
LRU
LFU
随机
Redis4.0之后增加两种
拒绝策略,可读不可写
Redis6.0新特性
1.原来读、解析、写都是由单个线程按顺序依次执行
1.现在可以配置多线程模型,此模型读、解析还是由主线程完成,但是写入操作可以由其它线程完成
2.也可以配置IO线程执行读写任务
多线程可以读、解析,但是统一经过command excute来执行,再多线程写入
2.client side caching(客户端缓存)
redis 6 提供了服务端追踪key的变化,客户端缓存数据的特性
架构
主从架构
全量同步
首次发送rdb文件,进行同步
如果在同步过程中,有写的数据,则后续主节点将该指令直接发送到从节点的缓冲中
增量同步
master会在其内存中创建一个复制数据用的缓存队列,缓存最近一段时间的数据,master和它所有的
slave都维护了复制的数据下标offset和master的进程id
slave都维护了复制的数据下标offset和master的进程id
问题
主节点挂掉后,人为修改从节点为主节点,并且修改IP等一系列操作
无法保证主写,从读的操作,需要人为指定
哨兵架构
优点
主节点挂掉后,哨兵帮助切换
保证主写,读从
问题
只有一个主节点对外提供服务,没法支持很高的并发
且单个主节点内存也不宜设置得过大,否则会导致持久化文件过大,影响数据恢复或主从同步的效率
Cluster架构
优点
读和写走主节点,从节点用来备份
槽位定位算法
HASH_SLOT = CRC16(key) mod 16384
通信机制
存储元数据
也就是每个节点的内部信息
分类
集中式
gossip
ping
pong
meet
fail
选举机制
假如某个Node的Master节点挂了后,经过一定时间的延迟后,该Master对应的Slave节点发起投票机制,告知所有的其它节点
其它Node对应的Master节点进行回应,该Slave节点获得的投票树最多的成为新的主节点
特殊情况
假如挂掉Master中的Slave节点获得的票数持平,则会重新发起选举,几率及比较小,原因如下
因为Slave经过一定时间延迟后才会发起投票,该时间会根据当前持有的最新数据来进行计算
0 条评论
下一页