简介
一个分布式系统,不可能同时做到三点:
- 一致性:对于客户端的每次读操作,要么读到的是最新数据,要么读取失败。
- 可用性:任何客户端的请求都能得到响应数据(非错误的响应)。
- 分区容忍性:节点间任意数量的消息丢失或者延时到达,系统能继续运行。
权衡
对于一个分布式系统而言,网络交互一定会存在延时或数据丢失,所以P必须要保证。需要注意的是没有发生网络分区时,CA时可以同时保证的,只有出现了网络问题才需要在CA中进行选择。
当选择了C(一致性)时,如果出现网络分区而无法保证特定的信息时最新的,则系统返回错误(或超时)。
当选择了A(可用性)时,则始终返回该信息可用的最新版本,不一定是最新的。
常用中间件的权衡结果:
- Zookeeper: Leader节点故障后,导致集群进行选主,无法处理请求;发生网络分区后,处于少数节点的分区也无法处理写请求,丧失了可用性;属于CP。
- Eureka: 去中心化的设计,节点之间平等,某个节点故障后,客户端会切换其他节点重试,不保证数据最新,属于AP。
- Nacos: 默认是AP,client阶段注册时ephemeral=true,使用distro协议实现;client节点注册时ephemeral=false,使用raft协议实现,属于CP。
- Redis: Sentinel模式下,master节点故障后,会自动选择另一个为master,客户端也能自动切换,但是不能保证数据不丢失,属于AP。
- MongoDB: 默认属于AP,可以通过配置应答机制来修改,例如写入操作的时候,设置w(write concern)为majority或者集群总节点数,则为CP模式。
- RocketMQ: Broker使用NameServer去注册服务,Producer和Consumer使用NameServer去发现发现服务来发送和消费消息。NameServer保证的是最终一致性,不关心某个节点数据是否最新,属于AP。
- RabbitMQ: 客户端会配置所有的服务节点,故障后自动切换可用节点,属于AP。
- etcd: 分布式key-value存储功能,使用raft协议,属于CP。