CAP理论
Consistency【一致性】
- 通过某个节点的写操作结果对后面通过其它节点的读操作可见
- 如果更新数据后,并发访问情况下可立即感知该更新,称为强一致性
- 如果允许之后部分或者全部感知不到该更新,称为弱一致性
- 若在之后的一段时间(通常该时间不固定)后,一定可以感知该更新,称为最终一致性
- 造成数据不一致:并发读写,或者通过不同节点去读写的时候
Availability【可用性】
任何一个没有发生故障的节点必须在有限的时间内返回合理的结果
Partition tolerance【分区容忍性】
- 部分节点宕机或者无法与其它节点通信时,各分区间还可保持分布式系统的
CAP理论:分布式系统中,一致性、可用性、分区容忍性最多只可同时满足两个
一般分区容忍性都要求有保障,因此很多时候是在可用性与一致性之间做权衡
一致性方案
Master-slave
- RDBMS的读写分离即为典型的Master-slave方案
- 同步复制可保证强一致性但会影响可用性
- 异步复制可提供高可用性但会降低一致性
WNR
- 主要用于去中心化(P2P)的分布式系统中。DynamoDB与Cassandra即采用此方案
- N代表副本数,W代表每次写操作要保证的最少写成功的副本数,R代表每次读至少读取的副本
- 当W+R>N时,可保证每次读取的数据至少有一个副本具有最新的更新,取得最新的数据,一种是版本号,一种是时间戳,那个最大那个就是最新的数据
- 多个写操作的顺序难以保证,可能导致多副本间的写操作顺序不一致,Dynamo通过向量时钟保证最终一致性
Paxos及其变种
- Google的Chubby,Zookeeper的Zab,RAF
Replica【复制品】
Replica
当某个Topic的replication-factor为N且N大于1时,每个Partition都会有N个副本(Replica)
Replica的个数小于等于Broker数,即对每个Partition而言每个Broker上只会有一个Replica,因此可用Broker ID表示Replica
所有Partition的所有Replica默认情况会均匀分布到所有Broker上
上图中Broker1中Topic2的Partition0的复制是在Broker2中Topic2中的虚线部分表示
Data Rlication要解决的问题
如何Propagate【扩散】消息
- leader:表示中心节点
- follower:相当于Slave
- 流程简述:producer在往topic1写入数据时,只会下入leader也就是Broker1里面,然后数据再被复制到Broker2和Broker3上面,采用方式是:follower周期性的采用pull方式将数据从leader拉过来。如果有读操作的情况下,那么也是通过leader完成。follower实际是数据的复制,它保证leader挂掉的时候follower能够顶上,代替leader完成相应操作
何时Commit
- ISR
- Leader会维护一个与其基本保持同步的Replica列表,该列表称为ISR(in-sync Replica)
- 如果一个Follower比Leader落后太多,或者超过一定时间未发起数据复制请求,则Leader将其从ISR中移除
- 当ISR中所有Replica都向Leader发送ACK时,Leader即Commit
- Commit策略【leader告诉客户端,告诉producer你的这条数据写成攻了,发送这么一个确认】
- Server配置
- replica.lag.time.max.ms=10000【10秒内没有向leader发送请求,程序出现问题,或者资源紧张,调度不过来,不希望它拖慢进度,所以将它从ISR中移除】
- replica.lag.max.messages=4000【follower和leader的数据相差4000条,也会移除,保证高可用性】
- 当leader发现follower,已经赶上来了,在十秒内会经常发送请求,同时leader和follower的数据相差小于4000,这时leader会把这些follower重新加入ISR
- Topic配置【保证至少有几个复制】
- min.insync.replicas=1
- Producer配置
- 0:他虽然是异步的,但不需要等待想leader发送ACK,立马返回
- 1:必须等待leader发送ACK,才算发送成功
- -1:不需要这个角色,交给Broker自己的策略,交给上边的Topic配置的值
- request.required.acks=0
如何处理Replica恢复
-
- 我们默认这里有三个结点A、B、C【A为leader,B、C为follower】,commit只能读到m1
- 当A挂掉了,A就移除ISR,B就变成了leader,当C也收到了m2时,B和C都有m2,那么B就会将m2这条数据commit
- 再来两条数据m4和m5,当C也收到m4和m5时,那么B就会将这两条数据commit
- 当A重新回来后,因为A本身有m1,那么A之后的数据就会被删除,因为这里A、B、C之间的数据差只有三条,当B commit的数据回到A时,ISR就变成了A、B、C,认为A也在ISR中
- 数据的顺序是数据被commit的数据
如何处理Replica全部
- 等待ISR中任一Replica恢复,并选它为Leader
- 等待时间较长,降低可用性
- 或ISR中的所有Replica都无法恢复或者数据丢失,则该Partition将永不可用
- 选择第一个恢复的Replica为新的Leader,无论它是否在ISR中
- 并未包含所有已被之前Leader Commit过的消息,因此会造成数据丢失
- 可用性
- 默认配置是第二种方式:高可用