首页 > 代码库 > Tair源码分析_对照表创建流程
Tair源码分析_对照表创建流程
Tair 中存放在主节点中的表的创建共分为五步:
1)根据当前m_hash_table表,统计出每一个alive节点上存储的bucket数量(包括master bucket和slave bucket)。假设有节点A,B,C和D,则形成数据如下的map,同时在扫描主节点的过程当中判断主节点是否down,如果不可用,则需要执行第五步快速建表:
注意:
在检查可用节点列表的过程中如果为负载均衡优先策略,group会统计当前可用节点列表,将该列表与m_hash_table一起作为算法的输入。这里对可用节点列表的唯一约束就是,列表中的节点都是alive的。而在位置优先策略中,对可用节点列表的约束加强了,即除了要求列表中的每个节点是alive的外,还需要统计2个机房中dataserver的数量差异不超过一个阈值。(若不满足这个2个约束,在该策略下,对照表是无法正常构建的)
例如:有两个集群一个集群70台机器一个有30台,阈值为0.5,那么该例子中的数量差异为(70-30)/7>0.5故不满足策略建表失败。
其中Xa表示节点A上存储的bucket数量,Xb,Xc,Xd亦然。显然,在启动时Xa = Xb = Xc = Xd = 0;
2) 根据1)中生成的map构建一个index map,即对于hold相同数量bucket的节点存放在同一列表里,举例如下:
3) 给每一个节点分配存储bucket的数量。这一步只是确定每一个节点上可以储存多少个bucket,而不确定到底存储哪一些bucket。对于不同的构建对照表策略,这一步骤是不同的。
在具体给每个节点分配bucket的过程中,假设某个节点上已经分配了b个bucket,现在N个节点已经负责了X个bucket,若b < X/N,则让该节点负责B/N个bucket,否则该节点负责B/N+1个节点。这样做的目的是,在负载均衡的前提下,减少数据迁移。由于允许数据存放多备份,对于某个bucket而言,可能会存储copyCount次,也就是说存在copyCount个bucket的内容是完全一样的,这些一样的backet,我们将其中的一个称作为master bucket,其余的称为slave bucket。那对于master bucket显然不能存放在过于集中,也需平均分配在每一个节点上。也类似地构造一个map,如下:
其中,第二列中的30和31表示节点A最终要存储的bucket总数。
计算bucket的流程如下图所示:
注意: 在位置安全优先策略中,根据配置掩码pos_mask来将节点分成2个机房,并且统计出每个机房中可用的存储节点数量。当确定出2个机房后,依次确定每个机房中的存储节点的平均负载bucket的数量(记为B), 拥有B个bucket的节点数量,拥有B+1个bucket的节点数量。接下来,为存储节点分配bucket数量,会根据其所在节点的平均bucket数量(每个机房的这3个数据可能是不同的)等数据,确定该节点的负载的bucket数量。
4) 计算每一个节点预期可存储bucket的数量;有了1) ~ 3)步的数据,现在可以计算每一个节点还可以存储的bucket的数量。
5) 快速创建对照表,确定每一个bucket的存储位置。
在初始化的过程中首先为master bucket 安排存储节点,依次按列扫描对照表中主节点所在列,备份节点1所在列,备份节点2所在列。
扫描主节点:当主节点无法使用的时候,将备份桶所在节点提升成为主节点,如果备份桶所在节点都不可用,建表失败。
扫描备份节点:备份节点不可用时,设置为0。
如果快速建表流程执行完成后不必执行第六步。
6)判断这个bucket是否适合存储在该节点
该功能由get_suitable_node函数实现,并且该函数通过调用is_this_node_ok函数。将在这里展开叙述get_suitable_node函数。该函数正如其名,其功能是选择一个合适的节点。虽然,configserver提供两种不同的建表策略,但是选择合适节点的框架是相同的。主要不同点在于,判断某一个节点是否适合存储某个特定bucket的约束是不同的,显然在不同的创建策略下,约束是不同的。这里我们分别来详述:根据第四步我们算出每一个节点还可以存储的bucket的数量:
按照key值从小到大选取节点进行判断。
1. 考察在负载均衡策略下,判断一个节点是否为适合存储某个bucket的约束归纳如下:
1)该节点上存储master bucket的数量约束;
2)该节点上存储总的bucket数量约束;
3)拥有最多bucket的节点总数量约束;
4)欲存储的bucket与其备份bucket不能在同一个节点上。
而选择合适节点采用的约束级别分为4类,根据其约束强弱,依次定义为ALL,POS,BASE和FORCE。如下图所示:
如果不满足节点约束,我们顺序查找其他节点,在上个例子中选择E节点进行验证,如果E不符合标准则顺次寻找下一个,同时修改列表中关于E的数据。
2. 在位置优先策略下,也是通过通过各种约束条件来实现这一功能的。位置安全优先策略将所有节点按位置分为2类。与负载均衡策略所不同的是:首先,判断某个节点是否可以存储某个bucket的时候,需要考虑其所属位置类别的信息,而非负载均衡那种全局信息(例如,A机房中的节点n, 其存储bucket的数量是以该机房中所有节点的平均负载 bucket数量为基准的,而不是以所有机房中的为基准);其次,每种约束级别需满足的约束条件不同;然后,没有添加随机扰动因子。现将这些约束归类如下:
1)在所在机房里,该节点上存储master bucket的数量约束;
2)在所在机房里,该节点上存储总的bucket数量约束;
3)在所在机房了,拥有最多bucket的节点总数量约束;
4)欲存储的bucket与其备份bucket不能在同一个节点上;
5)欲存储的bucket与其备份bucket不能在同一个机房中。
而选择合适节点采用的约束级别分为4类,根据其约束强弱,依次定义为ALL,POS,BASE和FORCE,如下图所示:
通过表中数据,我们可以看出负载均衡策略与位置安全策略在判断某bucket是否适合存储在某个节点上的判断策略还是很不同的。
有了上述介绍,我们就开始介绍描述get_suitable_node函数的工作方式吧。实际上,该函数异常降低约束级别来选择合适的节点。例如,在ALL级别下,无法选择合适的节点,那么就将约束级别降低到POS,直到降低到FORCE级别。在每一级别的约束下,依次遍历一个节点存储bucket容量的map(该map在对照表构建过程的第2步创建),选择一个节点。
通过以上六步我们初步建立了Tair的对照表。
Tair源码分析_对照表创建流程