虚拟计算集群#

OushuDB 支持若干个节点组织为互斥的虚拟集群(VC)。虚拟集群可以使用户的资源使用限定在若干节点上,从而达到合理分配资源并隔绝错误。虚拟计算集群由 oushudb-topology.yaml 定义,用户可以通过视图 oushu_vcluster 查看。

虚拟集群实例(VCI)会根据虚拟集群的定义构造,是实际拥有资源和执行的实体。当 SQL 向某 VC 申请资源时,RM 内部会选择适当的 VCI 处理。VCI 之间不要求同构,即每个 VCI 可以拥有不同数量的节点。VCI 的信息会体现在 oushu_vcluster 中,名字形如 vcname@vciname

1. 虚拟集群拓扑文件配置#

虚拟集群配置允许用户使用拓扑文件描述,其拓扑定义在 OushuDB 配置文件 oushudb-topology.yaml 文件中, 下面是一个虚拟集群拓扑描述:

 1nodes:
 2 - id: m[1]
 3   addr: 192.168.1.11
 4   label: { region: "regionA", zone: "zoneA"}
 5 - id: m[2]
 6   addr: 192.168.1.12
 7   label: { region: "regionA", zone: "zoneA"}
 8 - id: m[3]
 9   addr: 192.168.1.13
10   label: { region: "regionA", zone: "zoneA"}
11
12
13vc:
14 - name: mains
15   vci:
16     - nodes: m[1], m[2]
17 - name: vc_default
18   vci:
19     - name: vci1
20       nodes: m[1], m[2]

nodes 标识集群内的节点,由节点id,节点地址addr, 节点标签label 构成。 vc 标识一个具体的虚拟集群拓扑描述,由集群名称name,以及具体的vci组成,在vci子项下,定义了对应的vci名称以及包含的节点。

虚拟集群的增删改查都通过修改 oushudb-topology.yaml 后通过 reload 命令完成对虚拟集群的更改。

2. 虚拟集群查询#

用户可以通过视图 oushu_vcluster 来查看虚拟集群定义以及状态。

用户可以通过视图 gp_segment_configuration 来查看单个节点的状态。

3. 节点状态感知#

OushuDB 的所有节点(包括 main 和 segment)都会通过自身资源管理器的 Gossip 协议来感知状态。由于 Gossip 是最终一致性算法,各个节点看到的状态可能稍有时延,但是最终都将统一。当用户执行查询时,会根据 gp_segment_configuration 中的节点状态以及使用的虚拟集群实例来最终确定执行的节点。如果虚拟集群实例的所有节点都宕机,则查询语句会报错中止。用户可以通过查询 gp_segment_configuration 来查看所有节点的状态,确认虚拟集群实例是否可以运行查询语句。

4. 虚拟集群实例的选择#

会话使用的虚拟集群实例(VCI)是动态选择的,它由当前用户、集群状态和负载共同决定。当 VCI 中有任意节点存活,则我们称此 VCI 健康;当 VCI 中没有节点存活,则我们称此 VCI 不健康。

OushuDB 中的用户都会绑定资源队列,当会话开始事务时,会根据绑定的资源队列确定虚拟集群(VC),进而在 VC 中根据以下规则选择虚拟集群实例(VCI):

  1. 当前会话未选择任何 VCI,则跳转至 3

  2. 当前会话已选择 VCI,如果此 VCI 健康,则跳转至 7,否则跳转至 3

  3. 如果当前用户绑定的 VC 的所有 VCI 都不健康,则跳转至 7

  4. 资源管理器根据以下公式计算每个健康 VCI 的优先级

p1 = 正在执行的语句数量 / ACTIVE_STATEMENTS
p2 = 已使用的内存量 / MEMORY_LIMIT
p = 1 - (p1 > p2 ? p1 : p2)
  1. 资源管理器选择优先级最高的 VCI,如果多个 VCI 的优先级相等,则使用 Round-robin 轮询选择一个。

  2. 将资源管理器选择的 VCI 绑定给当前会话。

  3. 结束。

根据以上算法:

  1. 资源管理器并不区分异构的 VCI,用户应当尽量避免节点数量差异过大的 VCI。

  2. 当所有 VCI 都没有节点存活时,则资源管理器无法为当前会话选择 VCI,进而无法执行查询。此时用户可以通过观察 gp_segment_configuration 来确认节点状态变化,当发现有节点存活后,可以再次尝试执行。

  3. 当会话已经选择了 VCI 后,即使此 VCI 有部分节点宕机,OushuDB 仍然会尽可能复用此 VCI 来提高缓存命中率,只有当此 VCI 中的全部节点都宕机后,资源管理器才会为其选择新的 VCI。

  4. 当会话切换用户、指定会话级别资源队列、修改用户绑定的资源队列时都会使已选择的 VCI 失效,待新查询发起时会重新选择 VCI。

5. FAQ#

资源队列和ROLE#

  • 使用 vcname.rsqname 来表示资源队列,即虚拟集群 vcname 下的 rsqname 资源队列。

  • 创建用户不指定资源队列会自动使用 vc_default.pg_default。

  • 查看用户绑定的资源队列

    1select * from pg_resqueue
    2  where rsqname = (select rsqname from pg_resqueue
    3    where oid=(select rolresqueue from pg_authid
    4      where rolname=(select current_user)));
    
  • 查看用户绑定的虚拟集群

    1select * from oushu_vcluster
    2  where vc = (select split_part(rsqname, '.', 1) from pg_resqueue
    3    where oid=(select rolresqueue from pg_authid
    4      where rolname=(select current_user)));
    

资源队列和虚拟集群#

OushuDB 只有在初始化时会自动创建 vc_default.pg_default 队列,并且在初始化时为 oushudb-topology.yaml 中的虚拟集群自动创建 pg_default 队列。用户需要自行调整这些队列的 ACTIVE_STATMENTS 和 MEMORY_LIMIT 以适应实际环境。此后通过修改 oushudb-topology.yaml 新创建或删除的虚拟集群,用户需要手工创建或删除对应的资源队列。