互联网一致性架构设计 -- DB和Cache一致性
需求分析
下面两种情况会出现脏数据:
单库情况下
服务层的并发读写,缓存与数据库的操作交叉进行,这种情况虽然少见,但理论上是存在的,后发起的请求B在先发起的请求A中间完成了。
1. 请求A发起一个写操作,第一步淘汰了cache,然后这个请求因为各种原因在服务层卡住了(进行大量的业务逻辑计算,例如计算了1秒钟),如上图步骤1
2. 请求B发起一个读操作,读cache,cache miss,如上图步骤2
3. 请求B继续读DB,读出来一个脏数据,然后脏数据入cache,如上图步骤3
4. 请求A卡了很久后终于写数据库了,写入了最新的数据,如上图步骤4
主从同步
读写分离的情况下,读从库读到旧数据,这种情况请求A和请求B的时序是完全没有问题的,是主动同步的时延(假设延时1秒钟)中间有读请求读从库读到脏数据导致的不一致。
1. 请求A发起一个写操作,第一步淘汰了cache,如上图步骤1
2. 请求A写数据库了,写入了最新的数据,如上图步骤2
3. 请求B发起一个读操作,读cache,cache miss,如上图步骤3
4. 请求B继续读DB,读的是从库,此时主从同步还没有完成,读出来一个脏数据,然后脏数据入cache,如上图步4
5. 最后数据库的主从同步完成了,如上图步骤5
不一致的原因
1. 单库情况下,服务层在进行1s的逻辑计算过程中,可能读到旧数据入缓存
2. 主从库+读写分离情况下,在1s钟主从同步延时过程中,可能读到旧数据入缓存
建议:先淘汰缓存,再更新数据库
单库情况的优化
自己重写数据库连接池,例如根据userId取模,得到唯一的数据库连接,如何做到“让同一个数据的访问串行化”,只需要“让同一个数据的访问通过同一条DB连接执行”就行。
如何做到“让同一个数据的访问通过同一条DB连接执行”,只需要“在DB连接池层面稍微修改,按数据取连接即可”?
获取DB连接的
CPool.GetDBConnection()【返回任何一个可用DB连接】
改为
CPool.GetDBConnection(longid)【返回id取模相关联的DB连接】
1. service的上游是多个业务应用,上游发起请求对同一个数据并发的进行读写操作,上例中并发进行了一个uid=1的余额修改(写)操作与uid=1的余额查询(读)操作。
2. service的下游是数据库DB,假设只读写一个DB。
3. 中间是服务层service,它又分为了这么几个部分
(1) 最上层是任务队列
(2) 中间是工作线程,每个工作线程完成实际的工作任务,典型的工作任务是通过数据库连接池读写数据库
(3) 最下层是数据库连接池,所有的SQL语句都是通过数据库连接池发往数据库去执行的
4. 当用uid=1写数据库时,正在使用数据库连接池中的连接1。
5. 此时用uid度数据库,同样要使用连接1,这样读操作就会进行等待,要前面写数据完毕,释放数据库连接后才能读数据。
拓展
能否做到同一个数据的访问落在同一个服务上?
重新修改结构如下:
获取Service连接的
CPool.GetServiceConnection()【返回任何一个可用Service连接】
改为
CPool.GetServiceConnection(longid)【返回id取模相关联的Service连接】
1. 业务应用的上游不确定是啥,可能是直接是http请求,可能也是一个服务的上游调用
2. 业务应用的下游是多个服务service
3. 中间是业务应用,它又分为了这么几个部分
(1)最上层是任务队列【或许web-server例如tomcat帮你干了这个事情了】
(2)中间是工作线程【或许web-server的工作线程或者cgi工作线程帮你干了线程分派这个事情了】,每个工作线程完成实际的业务任务,典型的工作任务是通过服务连接池进行RPC调用
(3)最下层是服务连接池,所有的RPC调用都是通过服务连接池往下游服务去发包执行的
4. 当请求Service层时,根据uid来取模,决定使用哪个Service的连接
主从同步情况下的优化
既然旧数据就是在那1s的间隙中入缓存的,是不是可以在写请求完成后,再休眠1s,再次淘汰缓存,就能将这1s内写入的脏数据再次淘汰掉呢?
方法一
1. 先淘汰缓存
2. 再写数据库(这两步和原来一样)
3. 休眠1秒,再次淘汰缓存
缺点:所有的写请求都阻塞了1秒,大大降低了写请求的吞吐量,增长了处理时间,业务上是接受不了的。
方法二
1. 先淘汰缓存
2. 再写数据库(这两步和原来一样)
3. 不再休眠1s,而是往消息总线esb发送一个消息,发送完成之后马上就能返回
缺点:需要业务线的写操作增加一个步骤,这就是我们所谓的代码入侵
方法三
业务线的代码就不需要动了,新增一个线下的读binlog的异步淘汰模块,读取到binlog中的数据,异步的淘汰缓存。
总结
单库
由于数据库层面的读写并发,引发的数据库与缓存数据不一致的问题(本质是后发生的读请求先返回了),可能通过两个小的改动解决:
1. 修改服务Service连接池,id取模选取服务连接,能够保证同一个数据的读写都落在同一个后端服务上
2. 修改数据库DB连接池,id取模选取DB连接,能够保证同一个数据的读写在数据库层面是串行的
主从数据库
在“异常时序”或者“读从库”导致脏数据入缓存时,可以用二次异步淘汰的“缓存双淘汰”法来解决缓存与数据库中数据不一致的问题,具体实施至少有三种方案:
1. timer异步淘汰(本文没有细讲,本质就是起个线程专门异步二次淘汰缓存)
2. 总线异步淘汰
3. 读binlog异步淘汰
相关推荐
### 主从DB与Cache一致性详解 #### 一、引言 在现代软件系统中,为了提高性能和可扩展性,通常采用主从数据库复制技术以及缓存机制。然而,在这种架构下,由于主从数据库之间的数据同步延迟以及并发读写操作的存在...
总的来说,云原生数据库通过创新的架构设计,如日志优化、链式复制、Quorum机制、计算与存储分离等,解决了传统数据库在云环境中的性能问题,提高了数据一致性和可用性,降低了运维成本。这些技术的出现,不仅推动了...
English |简体中文RocksCache第一个保证最终一致性和与DB强一致性的Redis缓存库。特征最终一致性即使在极端情况下也能确保缓存的最终一致性强一致性为应用程序提供强一致的访问防崩溃缓存崩溃的更好解决方案防渗透防...
但是,这种做法存在一些问题,例如更新 database 成功,但更新 redis 失败的可能性很高,且错误日志可能会在别人的日志系统里面,使得难以保证 db 和 cache 的缓存一致性。 为解决这个问题,可以使用 canal 来订阅 ...
正确地利用它,可以避免不必要的数据库访问,同时保持数据的一致性。理解并熟练运用这些概念和方法,将有助于提升Laravel项目的整体效率和用户体验。在实际开发中,要根据业务需求和数据更新频率,灵活选择和管理...
此外,为了确保缓存和数据库的一致性,我们需要考虑缓存的更新策略。常见的策略有:先写数据库再删除缓存(Write-Behind)、先删除缓存再写数据库(Write-Ahead)以及使用分布式锁实现的双写模式。在Go-redis-cache...
- 事务的一致性、隔离性、持久性和原子性的解释。 - 锁机制与死锁预防措施。 - 事务日志的作用与管理。 ##### 16. DB2 CLP Plus - **命令行处理器**:讲解了DB2 Command Line Processor (CLP) 的高级用法。 - ...
abase基于Rocksdb的分布式存储系统,用于在线存储,具有基于文件的全量复制和基于rocksdb自身WAL的增量复制,内建和back storage强一致的key级别LRU cache,基于bucket的sharding和migration,基于compaction filter...
- **DB与Cache一致性**:通过缓存和数据库之间的协调机制来维护数据的一致性。 - **数据冗余一致性**:通过增加数据副本的数量来提高数据一致性。 - **消息时序一致性**:确保消息按照发送顺序处理,从而保持数据...
RAC通过私有网络连接各节点,共享存储设备,并使用Global Cache Service (GCS)和Grid Event Service (GES)来协调数据一致性。 然后,K-DB、DB2、Sybase和MySQL虽然各有特色,但都遵循类似的数据库体系架构原则。K-...
后台服务代码架构:项目实际应用中 redis 缓存与数据库一致性问题解决 一、需求起因 在项目中,出现了 redis 缓存与数据库一致性问题。假设先写数据库,再淘汰缓存:如果第一步写数据库操作成功,第二步淘汰缓存...
同时,采用延迟写入策略,认证数据等非实时数据更新可以稍后同步到数据库,以保证写操作的稳定性和一致性。 四、头像文件服务器 对于大量图片、文件的存储和访问,需要专门的文件服务器来处理。构建一个系统,提供...
- **Oracle9i RAC 的共享缓存架构**:Oracle9i RAC 采用了共享缓存机制,所有节点可以访问同一份数据,通过 Cache Fusion 技术实现了缓存的一致性,从而显著减少了磁盘 I/O 操作。 #### 系统软件需求 Oracle9i ...
网易的多副本数据一致高可用架构设计利用了多种技术手段,包括数据处理模块、事务分发模块以及Paxos算法等,确保数据在多个副本间的一致性与高可用性。 综上所述,数据库高可用架构的最新进展显示了技术界在保证...
8. **缓存一致性**:在多用户环境中,确保缓存和数据库之间的数据一致性是挑战之一。这可能涉及事务处理和锁机制,以防止脏读或丢失更新。 9. **性能优化**:通过合理设置缓存大小、过期策略以及使用合适的缓存系统...
DB2和Oracle是两种广泛应用的关系型数据库管理系统,它们在应用开发方面存在诸多差异。下面将对这些差异进行详细...理解这些差异对于开发者来说至关重要,特别是在跨平台项目中,确保数据的一致性和应用程序的兼容性。
- **一致性保障**:GaussDB T 通过一致性算法保证跨节点数据的一致性,确保事务的正确执行。 - **故障恢复机制**:具备快速故障恢复能力,确保系统的高可用性。 通过以上对 Oracle、MySQL、PostgreSQL 和 GaussDB T...
3. **LSM-Tree**:RocksDB采用了Log-Structured Merge Tree(LSM-Tree)的数据结构,这是一种针对SSD优化的存储模型,将数据分为内存中的MemTable和磁盘上的SSTable,通过周期性的合并操作保持数据的一致性。...
- 在分布式系统中,CAP三者不可兼得,通常需要在一致性和可用性之间做出权衡。 **2.2 最终一致性** - **最终一致性**指的是数据可能不会立即同步到所有节点,但最终会达到一致状态。 - 这种模型在分布式系统中非常...
在本篇文章中,我们将深入探讨如何在IBM DB2数据库中设计和创建表格,并重点讲解创建表语句...此外,合理地定义主键对于保证数据的一致性和查询性能至关重要。希望本文能帮助读者更好地理解DB2中的表设计与创建过程。