Redis09——一致性

31 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一致性

主从不一致的问题

redis默认是弱一致性,进行异步的同步。会存在时延的不一致,且突发情况(如宕机)也会产生不一致

解决

1,设置同步因子,在配置中规定要有多少个连接同步(比如一主二从,至少两个连接同步),来趋向于强一致性

2,wait命令,设置一定时间内同步到多少个结点,增强数据一致性,但会阻塞主线程性能损耗较大,wait 2 5000 (表示数据5秒内同步到2个结点)

数据库与缓存的双写一致性

同步策略:

(1)先更新缓存,再更新数据库;

(2)先更新数据库,再更新缓存;

(3)先删除缓存,再更新数据库;(通常直接删除缓存,更简单有效)

(4)先更新数据库,再删除缓存;(先删除缓存,下次查缓存未命中,查数据库时更新缓存)

(5)使用第三方技术,基于binlog文件的canal。

问题:更新缓存删除缓存哪个更好?先操作数据库还是先操作缓存?

通常直接删除缓存,更简单有效

推荐先更新数据库,再删除缓存;第二步失败则重试; 为什么?

(1)先删缓存更新数据库

删了缓存后,更新数据库无论是立刻成功还是延迟成功,查询都可能使旧数据更新到缓存,造成不一致,且不纠正的话缓存数据会一直保存旧数据。(影响大)

image.png

(2)更新数据库,再删除缓存

更新数据库后,删缓存无论是立刻成功还是延迟成功,后续查询都会将新数据更新到缓存中,只是有一些线程会得到旧数据。(影响小)

image-20220407155114495

数据实时同步:(如canal)实现解放C端,只需要将数据更新到数据库即可,canal 会自动更新缓存。canal使用了mysql的主从同步技术伪装为从服务器从mysql的binlog日志中读取操作写入redis,以主从同步的方式实现数据库缓存的同步

推荐的方案:订阅 MySQL binlog,再操作缓存

通过订阅binlog是最靠谱的一种方式,因为数据库更新成功后就会产生一条变更日志,记录在 binlog 中。通过订阅 binlog 日志,拿到具体要操作的数据,然后再执行缓存更新,删除和新增,可以保证数据的有序性。阿里巴巴的 Canal 中间件就是基于这个实现。

Canal 模拟 MySQL 主从复制的交互协议,把自己伪装成一个 MySQL 从节点,向 MySQL 主节点发送 dump 请求,MySQL 收到请求后就会开始推送 binlog 给 Canal,Canal 解析 binlog 字节流后,转换为便于读取的结构化数据,供下游订阅使用。