HMaster的failover 流程(三)

继续HMASTER的failover 流程

上一篇说道master failover的一个漏洞,这几天好好的看了一下,终于找到问题的关键在
哪儿了。首先来看如何重现。

1. master 发送rpc请求去open region,此时zk上的节点时offline状态。
2. rs收到请求还没有开始处理,即zk节点仍然是offline。
3. master重启
4. master开始failover 流程,rs继续处理open region动作

关键就在第四步:
如果rs已经将region open了。

1). master先收到zk node changed时间。然后再处理failover流程

1.1  收到zk事件,查看rit队列该region为null,则不做任何处理。然后failover处理的时候会将该region 重新assign。如果assign的是同一个regionserver,那么会立刻返回,且rs此次open动作结束。即region只在该rs上分配了一次,但是master的内存中并没有更新master中regions存放的信息是不准确的,影响balance;另外region依旧在RIT中,超时以后依旧会继续分配到另外一个region中,造成二次分配。

1.2 assign到不同rs,则显然会二次分配。

2).master先处理failover流程,再处理zk事件。

2.1 failover中会assign 该region,RIT为PENDINGOPEN,zk节点时offline。此时rs也在openregion 并更新zk节点,如果在此过程中有冲突的话会导致rs 或是master abort掉。

2.2 master的assign如果到不同rs上的话也会导致二次分配。

2.3 如果是同一个rs的话assign 动作结束。

2.3.1 master处理zk事件,如果此时getdata是opened的话,那么在RIT中是pendingopen,符合预期,更新master内存这个逻辑是正确的。

2.3.2但是master getdata的数据可能已经是被修改的数据,即虽然触发的是opened事件,但是在master 的nodedatachanged函数中去getdata得到的数据并不一定是opened,如有可能是offline(assign 动作更新的)这就导致master的内存又不正确,RIT也没有清空,又会二次分配。

上面所说的先处理failover还是先处理zk事件,是因为对这两个操作都是需要对RIT队列上锁的,是串行的。可以看到如果zk上状态是offline时master failover会有很大可能导致集群状态不一致,或是二次分配。

90中修正这个比较难。因为涉及到rpc通信协议的修改。

94中如何修改呢?

将要region将要在何处open的rs数据写入到zk中,即在zk上记录该region将要在那个regionserver上打开。

zk上的servername是master。这种只有当failover时有deadserver时,master会创建该region节点才会出现,即rpc请求肯定没有发送

zk上的servername是regionserver。且该server online,那么将assign该region的动作重写,不需要创建或是更新zk上面的节点。
如果region已经在rs上面分配成功了,RPC会返回alreadyopen然后会更新master内存。
如果region还在分配,rpc返回不做处理。当master收到rs 成功open region以后会更新
内存。

针对上面的几个问题

1.1  收到zk事件,查看rit队列该region为null,则不做任何处理。然后failover处理的时候会将该region 重新assign如果assign的是同一个regionserver,那么会立刻返回,且rs此次open动作结束。即region只在该rs上分配了一次,但是master的内存中并没有更新master中regions存放的信息是不准确的,影响balance;另外region依旧在RIT中,超时以后依旧会继续分配到另外一个region中,造成二次分配。

答:收到zk时间发现RIT队列是null,此时94会有一个判断,如果是正在failover那么会更新master内存。并将region加入一个队列,当failover开始执行的时候,发现该region已经被处理了,则该region的failover就不会再处理了。

1.2 master的assign如果到不同rs上的话也会导致二次分配。

答:master assign现在只会分配到同一台rs上。

2.1 failover中会assign 该region,RIT为PENDINGOPEN,zk节点时offline。此时rs也在openregion 并更新zk节点,如果在此过程中有冲突的话会导致rs 或是master abort掉。

答:修改了region failover assign的逻辑,当分配到同一台region的话,是不会去更新或是创建zk节点的,因此也就不会有冲突。如果是zk上的servername是master的话,那么该region的rpc尚未发出,创建节点就不会冲突

2.2 master的assign如果到不同rs上的话也会导致二次分配。

答:只会分配到同一台rs。

2.3 如果是同一个rs的话assign 动作结束。master处理zk事件,如果此时getdata是opened的话,那么在RIT中是PENDINGopen,符合预期,更新master 内存这个逻辑是正确的。但是master getdata的数据可能已经是被修改的数据,即虽然触发的是opened事件,但是在master 的nodedatachanged函数中去getdata得到的数据并不一定是opened,如有可能是offline(assign 动作更新的)这就导致master的内存又不正确,RIT也没有清空,又会二次分配

答:更新zk节点只有一个线程在操作不会存在两个线程了,因此不存在getdata的数据与触发的事件不一致的结果。



猜你喜欢

转载自punishzhou.iteye.com/blog/1574971
今日推荐