浅谈一致性模型与实现
一致性模型
1.强一致性
数据在插入后,立即就能看到结果,一些 传统的关系数据库,基本都是强一致性,例如单实例下的mysql,oracle等等,但如果是分布式的情况,例如主从,那么从库会有一定的延迟,就不是强一致性
2.弱一致性
系统不保证立即看到写操作的结果。数据最终会变得一致,但系统不保证具体的时间。例如,DNS 缓存更新就是弱一致性的例子。
3.最终一致性
如果没有新的更新,则最终所有的访问都将返回最后(最新)更新的值。Amazon DynamoDB 是最终一致性模型的一个例子。
区别
弱一致性不提供任何关于何时达到一致的保证,读操作可能总是看到旧数据;而最终一致性保证数据最终会一致,读操作最终会看到最新的数据。
案例
- Kafka
Kafka 是一个分布式流处理平台,主要用于构建实时的数据流应用。它通过分区和副本的机制来保证数据的可靠性和一致性。
- 一致性保证:在 Kafka 中,如果配置了多个副本(replicas),那么它使用领导者(leader)和追随者(followers)的模型来保证数据一致性。所有写入操作都首先由领导者处理,然后同步到追随者。只有当指定数量的追随者已经成功写入数据后,操作才被认为是完成的。
- 一致性类型:Kafka 可以配置为“全部”模式(acks=all),这种配置下可以实现强一致性,因为生产者客户端在接收到所有同步副本的确认后才认为消息提交成功。如果配置不是全部副本,那么就可能存在数据不一致的情况,从而属于最终一致性。
- Elasticsearch
Elasticsearch 是一个分布式搜索和分析引擎,通常用于实现全文搜索、结构化搜索等功能。
- 一致性保证:Elasticsearch 在内部使用分片和副本来存储数据。数据首先写入主分片,然后异步复制到副本分片。默认情况下,当数据被写入主分片时,就认为写操作成功了,尽管这些数据可能还没有被完全复制到所有副本分片。
- 一致性类型:Elasticsearch 提供最终一致性。虽然主分片在处理写操作后可以立即对新写入的数据进行搜索,但副本分片的数据同步是异步进行的,这意味着在某个时间点,不同的用户可能会看到不同的搜索结果,特别是在高负载下。
- RabbitMQ
RabbitMQ 是一个开源的消息代理和队列服务器,用于在分布式系统中传输消息。
- 一致性保证:RabbitMQ 保证消息的可靠传递通过消息持久化和确认机制实现。生产者可以等待消息被服务器确认(通过消息确认机制),消费者也可以发送回执。
- 一致性类型:RabbitMQ 本身处理的是消息的传递,而不直接涉及到数据的一致性问题。它可以配置为确保消息不丢失(通过消息持久化和事务支持),但在处理分布式消息传递的过程中,如果不借助外部系统支持事务或确保处理逻辑的一致性,它本身更接近于提供最终一致性。
总结
Kafka、Elasticsearch和RabbitMQ每个系统都可以在特定的配置下提供较强的一致性保证,但在默认或通用配置下,这些系统更多地提供最终一致性,确保在没有进一步操作的情况下,系统最终会达到一个一致的状态。这使得它们非常适合于需要高可用性和可扩展性的现代应用场景。
实现一致性的方案
1.分布式锁
- 作用:在操作共享资源前获取锁,保证同一时间只有一个节点能操作该资源。
- 案例:Zookeeper 提供了一个分布式锁服务,用于管理跨多个节点的锁定。
2.二阶段提交(2PC)
- 作用:是一种保证分布式系统事务一致性的协议,分为准备阶段和提交阶段。
- 案例:大多数关系数据库管理系统,如 PostgreSQL 和 MySQL,支持基于二阶段提交的分布式事务。
3.读写分离和副本同步
- 作用:通过在多个节点上维护数据副本,并对读写操作进行适当的路由,实现负载均衡和数据一致性。
- 案例:MongoDB 提供了复制集功能,通过主从复制机制来保证数据一致性。
浅谈一致性模型与实现
https://www.xinyublog.com/theory/consistency/