kudu master design(kudu主节点设计)

时间:2021-09-02 16:24:39

转载:http://blog.csdn.net/lookqlp/article/details/51355195

The Catalog Manager and System Tables

Catalog Manager 监听用户创建的kudu表和tablet。

所有table和tablet的元数据信息以写入时复制(copy-on-write)的objects形式存储在内存和磁盘里,kudu系统的sys.catalog信息只存储在master节点上,它在master启动时被加载进内存。在写这篇设计文档时,为了保证元数据的强一致性,sys.catalog仅仅存在一个tablet中(catalog也是tablet结构,为了便于采用Raft协议进行复制)。

增加或者修改table/tablet时,master先写入磁盘,完成后才会提交到内存。这保证了client访问内存table/tablet状态的一致性。我的理解是,创建或者修改表时,内存先提交,如果底层磁盘还有没有flush,client访问时却能拿到table/tablet的信息,就会出现不一致问题,因为此时table/tablet还未能提供正确的服务。所以必须保证磁盘先正常提交,完成后再刷新到内存中。

这种设计避免了tablet寻址服务更耗性能的全局扫描的问题,并且保证了每个table/tablet具备平稳的状态。

Catalog Manager在sys table中为查询元数据信息维护了三个hash-map:

[Table Id] -> TableInfo
[Table Name] -> TableInfo
[Tablet Id] -> TableInfo
TableInfo里也维护了一个map,存储了[table-start-key] -> TableInfo信息,为用户提供了根据key-range查找tablets地址服务。

Table Creation

如下步骤与CatalogManager::CreateTable()方法是一致的:

  1. Client向Master提交请求,请求信息有:创建表table x,N个tablets,表结构
  2. Master的CatalogManager::CreateTable()方法:

    2.1 验证请求准确性,例如验证表结构是否准确
    2.2 确定表名是否已经被占用
    2.3 在内存中创建TableInfo,并标注preparing状态
    2.4 在内存中,根据用户提供的表结构信息,创建TableInfo的pre-split-keys域信息,此时TableInfo同样也是preparing状态
    2.5 写入tablets信息进入sys.catalog(如果写入失败,这个Master线程会被killed)
    2.5.1 master开始写入disk
    2.5.2 如果此时正好master crashes或者restarts,当master再次恢复时,表不会存在
    2.5.3 表信息写入sys.catalog,并标注running状态
    2.5.4 master写入disk完成
    2.5.5 此后,master即使crashes或者重启,表依然存在。接着会提交running状态到内存,然后client才能访问到这个表。

  3. Master返回给client信息:已经创建,或者创建失败信息

经过如上步骤后,表就创建好了,集群shutdown,重启后表会依然存在。不过表的tablets还没有创建,见下边的Table Assignment章节。

Table Deletion

当用户提交一个DetleTable T的请求,表T在sys.catalog信息表中会被标注为deleted,从master的内存 table names列表中移除,同时,master内存的TableInfo/TableInfo该表的状态也被标注为deleted。

此时,外部通过master rpc对这个表不可见,但表T的tablet configs依然运行着。新的client open 表T,会报找不到表的异常,然而之前缓存了tablet地址信息的client,依然可以读写table configs,只要tablet servers运行正常,且tablets没被delete。在某种情况下,类似于文件系统的软连接。

Master将会异步的发送一个DeleteTablet RPC请求给每个tablet(config的中每个tablet server中的tablet一个RPC请求,config的概念参见下文)。然后tablets会被detele掉,互不干涉的且没有先后顺序的。如果master或者tablet server在一个成功执行的DeleteTablet操作之前下线了,master下次接收到这个需要被delete的tablet的心跳后,master会发送一个新的DeleteTablet的请求。

A config in Kudu is a fault-tolerant, consistent unit that serves
requests for a single tablet. As long as there are 2f+1 participants
available in a config, where f is the number of possibly faulty
participants, the config will keep serving requests for its tablet and
it is guaranteed that clients perceive a fully consistent,
linearizable view of both data and operations on that data. The f
parameter, defined table wide through configuration implicitly defines
the size of the config, f=0 indicates a single node config, f=1
indicates a 3 node config, f=2 indicates a 5 node config, etc..
Quorums may overlap in the sense that each physical machine may be
participating in multiple configs, usually one per each tablet that it
serves.

以后(TODO),一个独立的cleaner线程会负责删除table/tablet的on-disk和in-memory数据。

Table Assignment(Tablet Creation)

当表创建后,需要在一组副本上创建tablets。为了实现它,master需要选择副本,并与tablet结合,即将副本指定给某一个tablet。

我们发送创建tablet请求,选择了一组副本,且选择了leader,并不代表着这个tablet已经创建好了。接下来,tablet server如果接收到leader的tablet created心跳,我们就可认为这个tablet是running状态。如果超出了timeout时间(ASSIGNMENT-TIMEOUT-MSEC)没有接收到tablet created报告,master会替换掉这个tablet,步骤与上诉的一样。

这个分配任务是被CatalogManagerBgTasks线程执行的。这个线程主要负责两个事:

创建表(分配新的tablet)
超时时再次分配(部分tablet超时了,需要替换)
具体的步骤如下:
CatalogManagerBgTasks thread:

处理Pending Assignments:
循环每个即将要分配tablet任务:
  如果已经提交了创建tablet的请求:
    如果没有接收到响应,且配置的超时时间已经超过了,就标记这个tablet为replaced:
      a.删除这个tablet
      b.创建一个新的tablet替代如上tablet,把创建tablet加入到create tablet的list中
  如果tablet是新的,即刚刚被CreateTable创建且是preparing状态
    将这个tablet加入到create tablet的list中
循环create tablet list里的每个tablet:
  选择一组tablet server,在tablet config里
  选择一个tablet server成为初始化config的leader,此时[BEGIN-WRITE-TO-DISK]
  sys.cagalog中标注creating,如果这里失败了,Pending Assignments会重新创建这个tablet。[END-WRITE-TO-DISK]
  循环第一步中选择的那一组tablet server:
    发送一个异步的CreateTablet RPC请求,给tablet server。由于tablertserver的心跳,master会接收到tablet createion的通知
提交tablet的状态变化到内存,此时client可以看到tablet是”running”状态

清理删除掉的table和tablet(应该还没实现)
从sys.catalog中移除已经标注为deleted的tables/tablets
从内存的map中移除已经标注为deleted的tables/tablets

如上都是Catalog Manger的工作,而当TS(tablet server简称TS,下文雷同)接收到一个CreateTablet RPC请求时,TS会本地创建一个tablet副本。一旦成功创建了,会被加入到下一个tablet的report中。接着,调用master端的ProcessTabletReport方法。

如果此时master找到tablet状态是creating,并且TS report此tablet在分配过程中被选举为leader(CatalogManagerBgTasks过程后),这个tablet会被标记为running,并且提交到disk,结束这个tablet分配任务。

Heatbeats and TSManager

TS会发送Heartbeats给master,心跳包含如下信息:

节点实例信息:TS永久的uuid,节点顺序number
(可选的)注册。TS启动或者先前master响应TS需要needs register
(可选的)tablet report。当tablet的信息被改变了,或者先前master要求TS返回一个完整的tablet信息。

Hadling heartbeats

master接收到一个TS的heartbeat后:

判断是否是registration的心跳。如果是,TSManager登记这个TS实例
从TSManager中获取TSDescriptor,如果TSDescriptor找不到,则告知这个TS需要重新注册
更新心跳时间,在registration对象里
如果心跳含有tablet report信息,catalog manger会处理这个report并且更新mem cache,以及系统表(sys.catalog)。如果没有tablet report信息,master会向TS索取一个tablet report
发送一个成功响应给TS

TSManager

TSManagert在内存中存储着TS发送给master的信息(所有的TS信息,心跳信息和tablet reports等等),信息存储在map中,key是TS的永久UUID,而value指向的是这个TS的TSDescriptor。