三种方法-数据库和缓存数据一致性维护策略 (三种方法数据比较)
在现代web开发中,缓存已经成为提高应用程序读性能的标准做法。通过引入缓存,我们可以暂时存储经常访问的数据,避免频繁查询数据库,从而显著减少应用程序的响应时间。
引入缓存也带来了一些挑战,其中之一就是如何保证缓存和数据库中的数据保持一致。如果不解决这个问题,可能会导致业务逻辑出现异常行为,影响应用程序的可靠性和可信度。
缓存和数据库数据一致性问题
在缓存和数据库数据一致性方面,主要存在以下两个问题:- 先更新缓存,后更新数据库
- 先更新数据库,后更新缓存
在这种情况下,如果缓存更新成功但数据库更新失败,那么缓存中将包含最新值,而数据库中则仍然是旧值。后续的读请求可能会命中缓存,获取到正确的值,但在缓存失效后,系统将从数据库中读取到旧值并重新构建缓存,导致用户修改的数据“变回去”,造成业务影响。
如果数据库更新成功但缓存更新失败,那么数据库中将包含最新值,但缓存中仍然是旧值。随后的读请求将始终获取旧数据,只有在缓存失效后才能从数据库中获取正确的值。在这种情况下,用户在修改数据后可能看不到变更,直到一段时间后缓存失效,数据才会更新,同样会对业务造成影响。
解决缓存和数据库一致性问题的模式
为了解决缓存和数据库数据一致性的问题,业界提出了多种设计模式,以下介绍几种常见且有效的模式:-
Cache-Aside模式
-
读写穿透模式
-
写后模式
Cache-Aside模式是一种简单的模式,它将缓存视为数据库数据的补充。在使用Cache-Aside模式时,应用程序将直接操作数据库,而缓存仅用于加速读操作。当数据更新时,应用程序会先更新数据库,然后使缓存失效,这样后续的读请求将从数据库中获取最新数据。
Cache-Aside模式的主要优点是简单易于实现,并且不需要额外的基础设施。它也有一些缺点,例如,无法处理并发写入的情况,并且缓存和数据库之间可能存在不一致的窗口期。
读写穿透模式是一种将缓存与数据库紧密耦合的模式。在使用读写穿透模式时,所有数据库读写操作都必须通过缓存进行。当发生读操作时,缓存将首先检查是否有对应数据,如果有则直接返回,否则将从数据库中获取数据并将其放入缓存中。当发生写操作时,缓存将更新对应的数据,并同步将更新操作应用到数据库中。
读写穿透模式的主要优点是具有较高的数据一致性,并且可以处理并发写入的情况。它也存在一些缺点,例如,增加了数据库的负载,并且可能导致性能下降。
写后模式是一种折衷的模式,它结合了Cache-Aside模式和读写穿透模式的优点。在使用写后模式时,应用程序仍然直接操作数据库,但是缓存也会参与写操作。当发生写操作时,应用程序会先更新缓存,然后异步地将更新操作应用到数据库中。这种模式可以在一定程度上提高性能,同时保持数据的一致性。
写后模式的主要优点是既可以提高性能,又可以保证数据的一致性。它也有一些缺点,例如,需要额外的基础设施来处理异步更新,并且在异常情况下可能会导致数据丢失。
总结
缓存和数据库数据一致性是一个重要的概念,在设计和实现高性能、高可靠性的应用程序时必须考虑。通过理解不同的设计模式及其优缺点,我们可以选择最适合自己应用程序需求的模式,从而确保缓存和数据库中的数据保持同步,并避免不一致性造成的业务问题。浅谈缓存最终一致性的解决方案
在互联网业务的性能优化中,缓存层的重要性不言而喻。遵循CAP理论,缓存一致性问题备受关注,业界倾向于追求最终一致性,Cache-Aside策略作为常见策略,展现其独特价值。
Cache-Aside策略的核心是读先缓存,未命中时才查询数据库并更新,这种策略在读请求中可能遭遇缓存删除导致的未命中,但写请求则确保先更新数据库,再在并发场景中通过延迟删除策略来避免数据不一致,以维护性能和并发下的数据一致性。
然而,Cache-Aside并非完美无瑕,数据一致性风险在并发下难以完全避免。为解决这一问题,业界提出了延时双删策略,尽管存在预测读请求时间的难题,但通过补偿机制可以降低不一致风险。常见的补偿机制包括:
在实践中,如Canal通过解析binary log,支持消费和MQ推送,以确保数据准确性。DTS作为云服务的高效数据传输解决方案,适用于大规模一致性场景,简化部署和维护工作。
Read-Through模式在Cache-Aside的基础上加入了访问控制层,提高业务逻辑的封装,适用于读多写少的场景,Write-Through直写模式虽然实时更新缓存,但可能引发低效和数据不一致,需谨慎使用,通常在事务处理和分布式事务支持下得以缓解。
至于更新数据库与缓存的顺序,分布式锁是关键,确保单线程操作的有序性。Write-Behind模式异步更新缓存,减轻数据库压力,但牺牲一致性;而Write-Around模式则在非关键业务中选择缓存过期策略,尽管简单,但用户体验可能受到影响。
总结来说,缓存最终一致性解决方案需要根据业务特性和场景灵活选择,如读多写少优先考虑Cache-Aside+补偿日志,写多则可能倾向于Write-Through+锁,极端写多情况下,Write-Behind可能是明智之选。每种策略都需在性能和一致性之间找到最佳平衡点。
mysql 如何解决数据一致性
MySQL主从复制
现在常用的MySQL高可用方案,十有八九是基于 MySQL的主从复制(replication)来设计的,包括常规的一主一从、双主模式,或者半同步复制(semi-sync replication)。
我们常常把MySQL replication说成是MySQL同步(sync),但事实上这个过程是异步(async)的。大概过程是这样的:
在master上提交事务后,并且写入binlog,返回事务成功标记;
将binlog发送到slave,转储成relay log;
在slave上再将relay log读取出来应用。
步骤1和步骤3之间是异步进行的,无需等待确认各自的状态,所以说MySQL replication是异步的。
MySQL semi-sync replication在之前的基础上做了加强完善,整个流程变成了下面这样:
首先,master和至少一个slave都要启用semi-sync replication模式;
某个slave连接到master时,会主动告知当前自己是否处于semi-sync模式;
在master上提交事务后,写入binlog后,还需要通知至少一个slave收到该事务,等待写入relay log并成功刷新到磁盘后,向master发送“slave节点已完成该事务”确认通知;
master收到上述通知后,才可以真正完成该事务提交,返回事务成功标记;
在上述步骤中,当slave向master发送通知时间超过rpl_semi_sync_master_timeout设定值时,主从关系会从semi-sync模式自动调整成为传统的异步复制模式。
半同步复制看起来很美好有木有,但如果网络质量不高,是不是出现抖动,触发上述第5条的情况,会从半同步复制降级为普通复制;此外,采用半同步复制,会导致master上的tps性能下降非常严重,最严重的情况下可能会损失50%以上。
这样来看,除非需要非常严格保证数据一致性等迫不得已的场景,就不太建议使用半同步复制了。当然了,事实上我们也可以通过加强程序端的逻辑控制,来避免主从数据不一致时发生逻辑错误,比如说如果在从上读取到的数据和主不一致的话,那么就触发主从间的一次数据修复工作。或者,我们也可以用 pt-table-checksum & pt-table-sync 两个工具来校验并修复数据,只要运行频率适当,是可行的。
真想要提高多节点间的数据一致性,可以考虑采用PXC方案。现在已知用PXC规模较大的有qunar、sohu,如果团队里初期没有人能比较专注PXC的话,还是要谨慎些,毕竟和传统的主从复制差异很大,出现问题时需要花费更多精力去排查解决。
如何保证主从复制数据一致性
上面说完了异步复制、半同步复制、PXC,我们回到主题:在常规的主从复制场景里,如何能保证主从数据的一致性,不要出现数据丢失等问题呢?
在MySQL中,一次事务提交后,需要写undo、写redo、写binlog,写数据文件等等。在这个过程中,可能在某个步骤发生crash,就有可能导致主从数据的不一致。为了避免这种情况,我们需要调整主从上面相关选项配置,确保即便发生crash了,也不能发生主从复制的数据丢失。
1. 在master上修改配置
innodb_flush_log_at_trx_commit = 1sync_binlog = 1
上述两个选项的作用是:保证每次事务提交后,都能实时刷新到磁盘中,尤其是确保每次事务对应的binlog都能及时刷新到磁盘中,只要有了binlog,InnoDB就有办法做数据恢复,不至于导致主从复制的数据丢失。
2. 在slave上修改配置
master_info_repository = TABLErelay_log_info_repository = TABLErelay_log_recovery = 1
上述前两个选项的作用是:确保在slave上和复制相关的元数据表也采用InnoDB引擎,受到InnoDB事务安全的保护,而后一个选项的作用是开启relay log自动修复机制,发生crash时,会自动判断哪些relay log需要重新从master上抓取回来再次应用,以此避免部分数据丢失的可能性。
![数据库](https://tyye.cn/zb_users/theme/tpure/style/images/lazyload.png)
通过上面几个选项的调整,就可以确保主从复制数据不会发生丢失了。但是,这并不能保证主从数据的绝对一致性,因为,有可能设置了ignore\do\rewrite等replication规则,或者某些SQL本身存在不确定因素,或者人为在slave上修改数据,最终导致主从数据不一致。这种情况下,可以采用pt-table-checksum和pt-table-sync工具来进行数据的校验和修复。
免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。