被 leeder 摆了一道,哭笑不得!

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 大家好,我是小林。上一周我写一了篇,数据库和缓存双写一致性的文章「老板真爱画大饼!」,故事的主人公是程序员阿旺。当时只写了上半篇,看到很多小伙伴催更下篇,说来就来!

大家好,我是小林。

上一周我写一了篇,数据库和缓存双写一致性的文章「老板真爱画大饼!」,故事的主人公是程序员阿旺。

当时只写了上半篇,看到很多小伙伴催更下篇,说来就来!


前情回顾


上回程序员阿旺为了提升数据访问的性能,引入 Redis 作为 MySQL 缓存层,但是这件事情并不是那么简单,因为还要考虑 Redis 和 MySQL 双写一致性的问题。


阿旺经过一番周折,最终选用了「先更新数据库,再删缓存」的策略,原因是这个策略即使在并发读写时,也能最大程度保证数据一致性。


聪明的阿旺还搞了个兜底的方案,就是给缓存加上了过期时间。


本以为就这样不会在出现数据一致性的问题,结果将功能上线后,老板还是收到用户的投诉「说自己明明更新了数据,但是数据要过一段时间才生效」,客户接受不了。


老板转告给了阿旺,阿旺得知又有 Bug 就更慌了,立马就登录服务器去排查问题,查看日志后得知了原因。


「先更新数据库, 再删除缓存」其实是两个操作,这次客户投诉的问题就在于,在删除缓存(第二个操作)的时候失败了,导致缓存中的数据是旧值,而数据库是最新值


好在之前给缓存加上了过期时间,所以才会出现客户说的过一段时间才更新生效的现象,假设如果没有这个过期时间的兜底,那后续的请求读到的就会一直是缓存中的旧数据,这样问题就更大了。


所以新的问题来了,如何保证「先更新数据库 ,再删除缓存」这两个操作能执行成功?


阿旺分析出问题后,慌慌张张的向老板汇报了问题。老板知道事情后,又给了阿旺几天来解决这个问题,画饼的事情这次没有再提了。


  • 阿旺会用什么方式来解决这个问题呢?
  • 老板画的饼事情,能否兑现给阿旺呢?


如何保证两个操作都能执行成功?


这次用户的投诉是因为在删除缓存(第二个操作)的时候失败了,导致缓存还是旧值,而数据库是最新值,造成数据库和缓存数据不一致的问题,会对敏感业务造成影响。


举个例子,来说明下。应用要把数据 X 的值从 1 更新为 2,先成功更新了数据库,然后在 Redis 缓存中删除 X 的缓存,但是这个操作却失败了,这个时候数据库中 X 的新值为 2,Redis 中的 X 的缓存值为 1,出现了数据库和缓存数据不一致的问题。

4.png

那么,后续有访问数据 X 的请求,会先在 Redis 中查询,因为缓存并没有 诶删除,所以会缓存命中,但是读到的却是旧值 1。


其实不管是先操作数据库,还是先操作缓存,只要第二个操作失败都会出现数据一致的问题。


问题原因知道了,该怎么解决呢?有两种方法:

  • 重试机制。
  • 订阅 MySQL binlog,再操作缓存。


先来说第一种。


重试机制


我们可以引入消息队列,将第二个操作(删除缓存)要操作的数据加入到消息队列,由消费者来操作数据。

  • 如果应用删除缓存失败,可以从消息队列中重新读取数据,然后再次删除缓存,这个就是重试机制。当然,如果重试超过的一定次数,还是没有成功,我们就需要向业务层发送报错信息了。
  • 如果删除缓存成功,就要把数据从消息队列中移除,避免重复操作,否则就继续重试。

举个例子,来说明重试机制的过程。

3.png


订阅 MySQL binlog,再操作缓存


先更新数据库,再删缓存」的策略的第一步是更新数据库,那么更新数据库成功,就会产生一条变更日志,记录在 binlog 里。


于是我们就可以通过订阅 binlog 日志,拿到具体要操作的数据,然后再执行缓存删除,阿里巴巴开源的 Canal 中间件就是基于这个实现的。


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


下图是 Canal 的工作原理:

2.png

所以,如果要想保证「先更新数据库,再删缓存」策略第二个操作能执行成功,我们可以使用「消息队列来重试缓存的删除」,或者「订阅 MySQL binlog 再操作缓存」,这两种方法有一个共同的特点,都是采用异步操作缓存。


老板发饼啦


阿旺由于对消息队列比较熟悉,所以他决定采用「消息队列来重试缓存的删除」的方案,来解决这次的用户问题。


经过几天几夜的操作,服务器搞定啦,立马向老板汇报工作。


老板让阿旺再观察些时间,如果没问题,到中秋节就商量“饼”的事情。


时间过的很快,中秋佳节到了,这期间一直都没有用户反馈数据不一致的问题。


老板见这次阿旺表现很好,没有再出现任何差错,服务器的访问性能也上来了,于是给阿旺发了这个超级大的月饼,你看这个饼又大又圆,就像你的代码又长又多.

0.png

阿旺看到这个月饼,哭笑不得,没想到这就是老板画的饼,是真的很大饼。。。。以上故事纯属虚拟,如有巧合,以你为准。



相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
传感器 算法 机器人
倒立摆
倒立摆
58 0
|
8月前
|
机器学习/深度学习 开发框架 算法
【深度强化学习】蒙特卡洛策略梯度法求解倒立摆问题实战(附源码)
【深度强化学习】蒙特卡洛策略梯度法求解倒立摆问题实战(附源码)
194 0
|
5月前
|
算法
基于模糊控制算法的倒立摆控制系统matlab仿真
本项目构建了一个基于模糊控制算法的倒立摆控制系统,利用MATLAB 2022a实现了从不稳定到稳定状态的转变,并输出了相应的动画和收敛过程。模糊控制器通过对小车位置与摆的角度误差及其变化量进行模糊化处理,依据预设的模糊规则库进行模糊推理并最终去模糊化为精确的控制量,成功地使倒立摆维持在直立位置。该方法无需精确数学模型,适用于处理系统的非线性和不确定性。
基于模糊控制算法的倒立摆控制系统matlab仿真
|
4月前
|
资源调度 算法
基于迭代扩展卡尔曼滤波算法的倒立摆控制系统matlab仿真
本课题研究基于迭代扩展卡尔曼滤波算法的倒立摆控制系统,并对比UKF、EKF、迭代UKF和迭代EKF的控制效果。倒立摆作为典型的非线性系统,适用于评估不同滤波方法的性能。UKF采用无迹变换逼近非线性函数,避免了EKF中的截断误差;EKF则通过泰勒级数展开近似非线性函数;迭代EKF和迭代UKF通过多次迭代提高状态估计精度。系统使用MATLAB 2022a进行仿真和分析,结果显示UKF和迭代UKF在非线性强的系统中表现更佳,但计算复杂度较高;EKF和迭代EKF则更适合维数较高或计算受限的场景。
|
5月前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于强化学习的倒立摆平衡车控制系统simulink建模与仿真
基于强化学习的倒立摆平衡控制系统利用MATLAB 2022a实现无水印仿真。此系统通过学习策略使摆维持垂直平衡。强化学习涉及状态(如角度和速度)、动作(施力)、奖励(反馈)及策略(选择动作)。采用Q-Learning算法更新动作价值函数Q(s,a),并通过DQN处理高维状态空间,利用经验回放和固定Q-targets提高学习效率和稳定性。
116 9
|
7月前
|
机器学习/深度学习 算法 索引
m基于Qlearning强化学习的小车倒立摆控制系统matlab仿真
在MATLAB 2022a中模拟的Q-learning倒立摆控制显示出稳定平衡效果。Q-learning算法通过智能体与环境交互学习最佳控制策略,以维持摆杆直立。算法基于状态s和动作a更新Q值表,目标是最大化未来奖励。系统状态包括小车位置、速度、杆角度及角速度。动作是小车加速度。当状态或动作空间大时,用神经网络近似Q函数,DQN通过经验回放和目标网络稳定学习。核心代码涉及状态更新、贪婪策略选择动作及环境反馈,实时更新摆杆和小车位置。
107 6
|
机器学习/深度学习 传感器 安全
【倒立摆】基于PID实现双回路倒立摆控制附Matlab代码
【倒立摆】基于PID实现双回路倒立摆控制附Matlab代码
|
机器学习/深度学习 传感器 算法
【倒立摆】基于PID模糊控制算法模拟倒立摆系统附Matlab代码
【倒立摆】基于PID模糊控制算法模拟倒立摆系统附Matlab代码
|
机器学习/深度学习 算法 决策智能
基于强化学习的倒立摆控制策略Matlab实现(附代码)
基于强化学习的倒立摆控制策略Matlab实现(附代码)
298 0
|
数据可视化 Python
非线性弹簧摆的仿真(Matlab代码实现)
非线性弹簧摆的仿真(Matlab代码实现)
208 0