当前位置: 首页 > wzjs >正文

淄博网站开发网泰好网络架构种类

淄博网站开发网泰好,网络架构种类,网站在政务新媒体建设,做网站高校视频一、引言 今天我们来聊聊一个在分布式系统中非常常见但又十分棘手的问题——Redis与MySQL之间的双写一致性。我们在项目中多多少少都遇到过类似的困扰,缓存是用Redis,数据库是用MySQL,但如何确保两者之间的数据一致性呢?接下来我…

一、引言

今天我们来聊聊一个在分布式系统中非常常见但又十分棘手的问题——Redis与MySQL之间的双写一致性。我们在项目中多多少少都遇到过类似的困扰,缓存是用Redis,数据库是用MySQL,但如何确保两者之间的数据一致性呢?接下来我会尽量简洁地为大家解析这个问题,并提供几个实战方案。

二、双写一致性挑战

我们先来看看什么是双写一致性。

简单来说,就是当数据同时存在于缓存(Redis)和数据库(MySQL)时,如何确保这两者之间的数据是一致的。

典型场景

  1. 写数据库后忘记更新缓存:这种情况最常见,当我们更新数据库后,缓存没有同步更新,导致读取到旧的数据。
  2. 删除缓存后数据库更新失败:在某些操作中,我们可能会先删除缓存,再更新数据库,但如果数据库更新失败,就会导致缓存和数据库的数据不一致。

在了解完双写一致性带来的挑战之后我们接下来看看几种经典的缓存模式。

三、缓存模式

3.1 Cache Aside Pattern (旁路模式)

Cache Aside Pattern是最常见的一种缓存使用模式,它的核心思想是以数据库为主,缓存为辅。

工作流程

读取操作:先从缓存中读取数据,如果缓存命中则返回结果;如果缓存未命中,则从数据库中读取数据,并将数据写入缓存。

更新操作:先更新数据库,再删除缓存中的旧数据。

示例代码:

public class CacheAsidePattern {private RedisService redis;private DatabaseService database;// 读取操作public String getData(String key) {// 从缓存中获取数据String value = redis.get(key);if (value == null) {// 缓存未命中,从数据库获取数据value = database.get(key);if (value != null) {// 将数据写入缓存redis.set(key, value);}}return value;}// 更新操作public void updateData(String key, String value) {// 更新数据库database.update(key, value);// 删除缓存中的旧数据redis.delete(key);}
}

优缺点分析:

优点:

  • 简单易懂,易于实现。
  • 读性能高,因为大部分读操作都会命中缓存。

缺点:

  • 存在短暂的不一致情况,更新数据库后缓存可能还没删除。
  • 删除缓存后,如果数据库更新失败,会导致数据不一致。

3.2 读写穿透模式

3.2.1 写穿透

当缓存未命中时,自动从数据库加载数据,并写入缓存。

3.2.2 读穿透

当缓存更新时,同步将数据写入数据库。

3.2.3 代码示例
public class ReadWriteThroughPattern {private RedisService redis;private DatabaseService database;// Read-Throughpublic String readThrough(String key) {// 从缓存中获取数据String value = redis.get(key);if (value == null) {// 缓存未命中,从数据库获取数据value = database.get(key);if (value != null) {// 将数据写入缓存redis.set(key, value);}}return value;}// Write-Throughpublic void writeThrough(String key, String value) {// 将数据写入缓存redis.set(key, value);// 同步将数据写入数据库database.update(key, value);}
}
3.2.4 优缺点分析

优点:

  • 保证了数据的强一致性,缓存和数据库的数据始终同步。
  • 读写操作都由缓存处理,数据库压力较小。

缺点:

  • 写操作的延迟较高,因为每次写入缓存时都需要同步写入数据库。
  • 实现复杂度较高,需要额外的缓存同步机制。

3.3 异步缓存写入(Write Behind)

缓存更新后,异步批量写入数据库。这种策略适用于可以容忍一定数据不一致的高性能场景。

3.3.1 示例代码
public class WriteBehindPattern {private RedisService redis;private DatabaseService database;private UpdateQueue updateQueue;// 异步缓存写入public void writeBehind(String key, String value) {// 将数据写入缓存redis.set(key, value);// 异步将数据写入数据库asyncDatabaseUpdate(key, value);}private void asyncDatabaseUpdate(String key, String value) {// 异步操作,将更新请求放入队列updateQueue.add(new UpdateTask(key, value));}
}
3.3.2 优缺点分析

优点:

  • 写操作的性能非常高,因为只需更新缓存,数据库更新是异步进行的。
  • 适用于对写操作性能要求较高的场景。

缺点:

  • 存在数据不一致的风险,缓存更新后数据库可能还未更新。
  • 实现复杂度较高,需要处理异步操作中的异常和重试。

四、实战解析

4.1 延时双删策略

延时双删策略的核心思想是:在更新数据库后,先删除一次缓存,然后延迟一段时间再删除一次缓存,减少数据不一致的风险。

关键是如何确定延迟时间,这个时间需要根据系统的具体情况来调整,以平衡一致性和性能。

public class DelayedDoubleDeletePattern {private RedisService redis;private DatabaseService database;private ScheduledExecutorService scheduledExecutorService;private long delay = 500; // 延迟时间,单位:毫秒// 更新操作public void updateDataWithDelay(String key, String value) {// 更新数据库database.update(key, value);// 删除缓存中的旧数据redis.delete(key);// 延迟一段时间再删除缓存scheduledExecutorService.schedule(() -> redis.delete(key), delay, TimeUnit.MILLISECONDS);}
}

优缺点分析:

优点:

  • 简化了缓存和数据库的一致性问题。
  • 避免了缓存和数据库的同步更新,提高了系统性能。

缺点:

  • 需要精确控制延迟时间,否则可能导致缓存和数据库不一致。
  • 实现相对复杂,需要额外的定时任务管理。

4.2 删除缓存重试机制

删除缓存时,如果失败,可以设置重试机制,以确保缓存最终被删除。

通过使用Spring的@Retryable注解,可以简化重试逻辑。

代码示例:

public class CacheService {private RedisService redis;@Retryable(value = Exception.class, maxAttempts = 5, backoff = @Backoff(delay = 2000))public void deleteCache(String key) {// 删除缓存中的数据redis.delete(key);}
}

优缺点分析:

优点:

  • 确保缓存最终被删除,降低数据不一致的风险。
  • 使用Spring的重试机制,简化实现逻辑。

缺点:

  • 需要处理重试的多次失败情况,可能导致系统负载增加。
  • 适用于缓存删除失败率较低的场景。

4.3 监听binlog异步删除缓存

利用数据库的binlog变更来异步更新缓存,通过消息队列和异步服务解耦缓存更新操作。

通过订阅binlog,将变更记录放入消息队列,然后由异步服务处理缓存更新。

代码示例:

public class BinlogListenerPattern {private RedisService redis;private MessageQueue messageQueue;// 订阅binlogpublic void onBinlogChange(BinlogEntry entry) {// 将变更记录放入消息队列messageQueue.send(new CacheUpdateMessage(entry.getKey()));}// 异步服务处理缓存更新public void processCacheUpdate(CacheUpdateMessage message) {// 删除缓存中的数据redis.delete(message.getKey());}
}

优缺点分析:

优点:

  • 利用数据库的变更日志,保证缓存和数据库的一致性。
  • 异步处理提高了系统性能,降低了实时更新的压力。

缺点:

  • 实现复杂度较高,需要处理消息队列和异步服务。
  • 存在延迟更新的情况,可能导致短时间内的数据不一致。

五、小结

在实际项目中,我们需要根据具体的业务场景来选择最合适的一致性策略。同时,在高并发场景下,可以结合分布式锁和消息队列来确保数据一致性。异步处理中的异常处理和重试策略也非常重要,能够有效提高系统的稳定性和可靠性。

此外,在实际开发应用时,不需要自己再去实现一套缓存管理代码,有很多框架已经提供了基于声明式注解的缓存管理器抽象,只需要添加几个注解,就可以实现数据库缓存,例如:

  • Spring Cache
  • Alibaba Jetcache

文章转载自:

http://S8LUzj4Q.snzgg.cn
http://58UiYXKq.snzgg.cn
http://MUdWzQ3s.snzgg.cn
http://GDVt2w55.snzgg.cn
http://BowcGVUp.snzgg.cn
http://Jm0UxxDZ.snzgg.cn
http://cgPQ6LVu.snzgg.cn
http://uU21GhuN.snzgg.cn
http://YUmxoer8.snzgg.cn
http://7pk88Vg4.snzgg.cn
http://TZ1fOxPP.snzgg.cn
http://wekHZYPC.snzgg.cn
http://I1xt6FTJ.snzgg.cn
http://72wnMzU5.snzgg.cn
http://DH2E0U0r.snzgg.cn
http://s4q7VNQS.snzgg.cn
http://3z9mn4Rn.snzgg.cn
http://fZy15dK0.snzgg.cn
http://C3MNLpoy.snzgg.cn
http://9lm87h2Z.snzgg.cn
http://vCtODowz.snzgg.cn
http://ZQ8JGUcf.snzgg.cn
http://Knftv5OV.snzgg.cn
http://EYnGUtMa.snzgg.cn
http://i5s4YUld.snzgg.cn
http://5w7g7V9a.snzgg.cn
http://1FYWR6Xt.snzgg.cn
http://BMVSwYLM.snzgg.cn
http://XOdBG0t8.snzgg.cn
http://vEgfm6Tc.snzgg.cn
http://www.dtcms.com/wzjs/691102.html

相关文章:

  • 用vs2013做网站登录wordpress 更改 虚拟目录
  • 可以做翻译的网站小程序商城怎么开通
  • 二手车网站开发背景提交百度收录
  • 权威发布e站长春行业网站
  • 移动端企业网站模板wordpress 获取category id
  • 阜蒙县建设镇官方网站wordpress地址应该填什么意思
  • .net网站开发实站合肥比较好的设计公司
  • 网站服务器租用和自己搭建的区别wordpress mu插件
  • 花生壳怎么建设购物网站潍坊 区网站建设
  • 做动态图网站公司制作网站需要
  • 怎么在百度上做单位网站网站全面推广方案
  • 武进建设银行网站首页郑州专业网站制作的公司
  • 网站建设课程简介图片黄页广告公司
  • 多个域名绑定一个网站自己做商业网站
  • 有没有专门做数据分析的网站郑州网站分析
  • 中卫网站推广优化公司网站建设定制开发推广
  • 公司网站没做301怎么做301谁做彩票网站代理
  • 网站建设对企业影响有多大在猪八戒做网站有保障吗
  • 专业制作网站有哪些怎样在微信上开发小程序
  • 广州微信网站制作网站建设费的摊销
  • 电器企业网站建设做网站广告词找王思奇
  • 房产网站怎么推广支付宝 网站接口
  • 上街区网站建设兰州新区小程序建站
  • 湛江个人网站制作在哪里做西安房产网58
  • 句容住房和城乡建设局网站四川建站
  • seo同行网站wordpress企业建站模版
  • 网站论坛怎样建设大气黑色机械企业网站源码
  • 网站加视频播放设计怎么做的深圳做购物网站
  • 当当网网站建设需求分析网站不备案会怎么样
  • wap网站cms微信微网站开发策划