1、cp系统必然是分布式的,提供高可用性 – 分区容错性
2、cp系统必然得大半数达成共识(也就是说能够统一意见,最简单的实现方式就是选出一个leader,只听leader的指挥),如果小半数达成共识就可以的话,那就可以产生两个达成共识的子系统,就会脑裂,就不是c系统了 – 可以保证一致性
3、cp系统活着的节点必然得包含最新的数据 —— 保证数据完整性。
4、cp系统必然得写过半,不然挂掉小半数的时候,最新的数据就能丢失掉 —— 保证数据完整性。
那有上述几个特点,就必然是一个cp系统了吗?以上几个条件是充分条件吗?只要保证任何时候都有多半数节点活着(如果不能保证这一点的时候,我就让服务不可用)。并且写数据的时候,只有一个leader,并且只有一个leader处理所有读写请求,并且处理任何请求都写入半数以上的节点log里。如果不能写入多半数,我就让这个请求失败。这样就是一个cp系统了吗?
答:在leader从来不挂,且大半数节点始终活着的时候,这肯定是一个cp系统。重点是在leader挂掉以后,怎样才能让系统恢复到以前的状态。
让cp系统时时刻刻处在一个可恢复状态才是最根本问题!然而什么状态才是可恢复状态呢?
就是在任何时候挂掉,都不会丢失数据,而且还能恢复到原状态。
我们该怎样定义什么是“有效数据”,怎样设计选举恢复过程,才能让leader挂掉(但有多半数节点存活)以后,系统能恢复到以前的状态(数据完整一致、系统也可用)?
答:正常运行情况下:
1、我们设计在处理任何请求(不管这个请求最终是否会产生有效数据)时,必须写入半数以上的节点log里才能响应客户端。
2、我们认定只有响应了客户端的请求才是真正的有效请求,才会产生有效数据。
3、我们规定一个请求只有写入大半数的节点log以后,才能响应给客户端。
3、我们规定节点一旦挂掉大半数,就停止服务(因为选不出leader,从candidate里读的数据不一致)。
4、我们设计只有leader能处理所有读写请求。
leader挂掉重新选举恢复有两个步骤:
1、我们首先去找一个包含最新有效数据的节点。
2、找到这个节点以后,我们让它去取得其它大半数节点的共识。
假如一个节点能找到半数多个节点的log数据比自己旧,那么肯定不存在比自己新的有效数据。也就是说自己是可以作为候选leader的。所有恢复过程就是找到这么一个节点以后,然后去拉选票,最终达成共识就好了。
推论:
节点无论是挂掉的,还是正常运行的,提交过的日志必然是完整、连续不间断的。挂掉重启以后,leader会给补齐。