mysql写入数据库1s中_redis-缓存和数据库写入不一致问题

bc3f9276acf88283a0569b9b9ef9ee92.png

在线QQ客服:1922638

专业的SQL Server、MySQL数据库同步软件

CAP理论(除缓存模式):缓存 + 数据库读写模式

读取序列化请求和写入请求并将它们放入内存队列

原因很简单。在许多情况下,在复杂的缓存方案中,缓存不仅是直接从数据库中获取的值。

例如,可以更新某个表的字段,然后相应的缓存需要查询其他两个表的数据并执行操作以计算缓存的最新值。

另外,更新高速缓存的成本有时非常高。这是否意味着每次修改数据库时,都必须更新相应的缓存?在某些情况下可能是这种情况,但在更复杂的缓存数据计算情况下则不是这种情况。如果您经常修改缓存中涉及的多个表,则缓存也会经常更新。但是问题是,是否会经常访问此缓存?

对于板栗,将与缓存相关的表的字段在1分钟内修改20次或100次,然后将缓存更新20次和100次;但是此缓存仅在1分钟内被读取一次,有很多冷数据。实际上,如果仅删除缓存,缓存将仅在1分钟内重新计算,并且开销大大减少。缓存用于计算缓存。

实际上,删除缓存而不是更新缓存是一个懒惰的计算思路。不论是否要使用,都不要每次都进行复杂的计算,而要在需要使用时重新计算。像mybatis,hibernate一样,都具有延迟加载的想法。查询一个部门,该部门会带来一个雇员列表,不必说每次查询该部门时,也会同时找到其中的1000名雇员的数据。在80%的情况下,仅检查该部门即可访问该部门的信息。首先检查部门,并拜访部门中的员工。然后,仅当您这次要访问员工时,您才可以进入数据库查询1000名员工。

数据已更改,请先删除缓存,然后再修改数据库(当前尚未修改)。发出请求,读取缓存,发现缓存为空,去查询数据库,在修改前找到了旧数据并将其放入缓存中。随后的数据修改过程完成了数据库修改。完成后,数据库中的数据与缓存不同

解决方案如下:

更新数据时,根据数据的唯一标识符,将操作路由并发送到jvm内部队列。读取数据时,如果发现数据不在缓存中,则根据唯一标识符路由后,重新读取数据+更新缓存的操作将发送到同一jvm内部队列。

队列对应一个工作线程,每个工作线程serial获得相应的操作,然后一个接一个地执行。在这种情况下,数据更改操作将首先删除缓存,然后更新数据库,但是更新尚未完成。这时,如果出现读取请求并且未读取缓存,则可以先将缓存更新请求发送到队列,然后将队列积压,然后等待缓存更新完成。

有一个优化点,实际上,队列中有多个更新缓存请求连接在一起,这是没有意义的,因此,如果发现已经有更新,则可以进行过滤在队列中缓存请求然后,无需进行更新请求操作,只需等待先前的更新操作请求完成即可。

与该队列相对应的工作线程完成对上一个操作的数据库的修改后,它将执行下一个操作,即更新缓存的操作。此时,将从数据库中读取最新值,然后将其写入缓存。

如果请求仍在等待时间范围内,并且连续轮询发现可以获取该值,则直接返回;否则,直接返回。如果请求等待的时间超过一定的时间长度,则这次直接从数据库中读取当前的旧值。

在高并发情况下,解决方案应注意:

长期阻止读取请求

由于读取请求非常不同步,因此我们必须注意读取超时的问题。每个读取请求必须在超时时间内返回。

此解决方案的最大风险点是,可能会频繁更新数据,从而导致队列中进行大量更新操作,然后读取请求将发生大量超时,最后是大量的请求将直接进入数据库。确保通过一些模拟的真实测试,以查看数据更新的频率。

还有一点,因为在队列中,可能会积压多个数据项的更新操作,因此您需要根据您的业务状况进行测试,您可能需要部署多个服务,每个服务共享一些数据更新操作。如果一个内存队列实际压缩了100项库存修改操作,则完成每个库存修改操作需要10毫秒,那么最后一个产品读取请求可能在获取数据之前等待10 * 100 = 1000ms = 1s,这导致长期的阻止读取请求。

确保根据实际的业务系统操作进行一些压力测试,并模拟在线环境,以查看在最繁忙的时间内内存队列可能挤压了多少更新操作,这可能导致最后一次更新读取多少时间。对应于该操作的请求挂起,如果读取请求在200ms处返回,则如果计算出该请求,即使是最繁忙的时间,积压10次更新操作,最多等待200ms,也可以。

如果内存队列中可能有太多更新操作,那么您必须添加计算机以允许部署在每台计算机上的服务实例处理更少的数据,然后每个内存队列中的更新操作积压将更少。

根据以前的项目经验,通常来说,数据写入频率很低,因此实际上,通常来说,队列中更新的积压应该很少。像此类用于读取高并发性和读取缓存体系结构的项目一样,一般来说,写入请求很少,并且每秒几百个QPS很好。

并发读取请求太高

还必须进行压力测试,以确保当碰巧发生上述情况时,还存在突然大量的读取请求挂起在服务上的风险,这会延迟数十毫秒,具体取决于是否可以进行服务。多少台机器可以容纳最大限制情况的峰值。

但由于并非所有数据都在同一时间更新,因此高速缓存不会同时失效,因此每次少量数据的高速缓存都可能失效,然后与这些数据相对应的读取请求过来,并发量也应该不会太大。

用于多服务实例部署的请求路由

可能会部署该服务的多个实例,因此必须确保将执行数据更新操作和缓存更新操作的请求通过Nginx服务器路由到同一服务实例。

例如,对同一商品的读写请求都被路由到同一台机器。您可以根据服务之间的特定请求参数进行哈希路由,也可以使用Nginx的哈希路由功能,等等。

热产品的路由问题导致请求偏斜

如果对某个产品的读取和写入请求特别高,则它们全部都到达同一台计算机的同一队列,这可能会对某台计算机造成过大的压力。也就是说,由于仅在更新产品数据时才清除高速缓存,然后这会导致并发读写,因此实际上必须根据业务系统对其进行查看。如果更新频率不太高,则此问题的影响不会特别大。但是某些机器的负载可能会更高。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值