虚拟集群

OushuDB从4.4.0.0版本开始支持虚拟集群来管理节点及其队列。虚拟集群可以使用户的资源使用限定在若干节点上,从而达到合理分配资源并隔绝错误。目前所有关于虚拟集群的元数据信息记录在系统表pg_vcluster中。

1. 特殊虚拟集群

OushuDB在初始化时会自动创建名为vc_default的虚拟集群,此虚拟集群不可删除,并自动配有vc_default.pg_root和vc_default.pg_default资源队列。OID为10的role(通常为gpadmin)会自动绑定vc_default.pg_default。

2. 虚拟集群初始化

vc_default可以在初始化时获得节点。默认情况下,所有slaves文件下的节点都会自动加入vc_default。用户同样可以在hawq init的时候指定vcluster_config,来自定义节点。更具体的,vcluster_config为一个指向虚拟集群配置文件的文件路径,而虚拟集群配置文件的格式如下:每个条目一行且每个条目由两列构成,第一列为节点域名,第二列为虚拟集群名,若第二列为空则视为vc_default,例如:

1
2
3
4
seg1
seg2 vc1
seg3 vc2
seg4 vc2

则vc_default含有seg1节点,同时创建vc1包含seg2,创建vc2包含seg3和seg4

此外初始化时还会将hash_table_bucket_number按照节点个数平均分配给各个虚拟集群。

3. 创建虚拟集群

1
2
3
4
5
6
7
8
9
CREATE VCLUSTER <name> [
  WITH (SEGMENTS='<hostnames>' | SEGMENTFILE='<hostfile>'
        [, <VCPROPERTY>=<value> [, ...] ])
]
where <VCPROPERTY>=<value> is:
   <hash_table_bucket_number> = <integer>
|  <max_nvseg_perquery> = <integer>
|  <max_nvseg_perquery_perseg> = <integer>
|  <magma_hash_table_nvseg_perseg> = <integer>

其中SEGMENTS=’<hostnames>’是一组节点的域名,可由’,’分割,例如:SEGMENTS=’seg1,seg2,seg3’。 每个被分割的域名可以支持如下的扩展匹配:匹配区域由’[]’定义,模式内由’,’分割,利用’..’来进行循环。 具体来讲模式内每个条目有如下三种形式:

  • X 即为 X
  • X..Y 表示从X到Y(闭区间)
  • X..Y..S 表示从X到Y(闭区间),步长为S

其中X,Y,S均为整数,举例:

1
192.168.1.[1,2,3..4,5..10..2], hawq[1..2]

被解析为:

1
2
3
4
5
6
7
8
9
192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.4
192.168.1.5
192.168.1.7
192.168.1.9
hawq1
hawq2

SEGMENTFILE=’<hostfile>’是一个包含segment域名的文件位置,文件内容的语法和SEGMENT语法一致,且支持’n’分隔,支持空行

每一个新创建的虚拟集群会自动创建两个资源队列,加入新虚拟集群的名字为newvc,则资源队列名为newvc.pg_root,newvc.pg_default。

需要注意的是DDL中SEGMENTS和SEGMENTFILE里面的内容全是域名。即使写成IP也会被当成域名,值得庆幸的是IP作为域名会被解析成自身,但不幸的是会让我们产生歧义。更具体地,假设域名localhost对应IP为127.0.0.1,我们不能同时加入localhost和127.0.0.1,因为他们IP冲突。

另外,我们不会验证segments和segmentfile中的域名是否真实有效,也就是说即使你随便胡编乱造节点的域名,vc也会把它加入其中,只是这个节点永远不可用。通常情况下这不会发生问题,但有时他会触发以下三种错误:

  • 申请资源:VCluster %d has %d of %d segments %s unavailable, exceeds %.1f%% defined in GUC hawq_rm_rejectrequest_nseg_limit.
  • 申请资源配额:VCluster %d has %d of %d segments %s unavailable, exceeds %.1f%% defined in GUC hawq_rm_rejectrequest_nseg_limit.
  • 日志中出现:RM: Failed to fix MemCoreRatio: Expects at least %d segments available before first time fixing cluster memory to core ratio, currently %d available segments are ready.

这是因为虚拟集群中又太多的虚假节点,导致超过阈值从而失败。

此外一种容易出现问题的情况是:你试图加入127.0.0.1,但是手误写成了127.00.1,这不会失败,但远不是你所期望的。当然如果你明确知道加入的节点已经发送过心跳,可以通过pg_segment_configuration来确认其信息是否正确。

4. 删除虚拟集群

1
DROP VCLUSTER [IF EXISTS] <name>

一个繁忙的(简易理解:有资源请求)虚拟集群无法被删除。

5. 虚拟集群缩容扩容

1
2
3
ALTER VCLUSTER <name> WITH (SEGMENTS='<hostnames>' | SEGMENTFILE='<hostfile>')

ALTER VCLUSTER <name> WITHOUT (SEGMENTS='<hostnames>' | SEGMENTFILE='<hostfile>')

WITH用来扩容,WITHOUT用来缩容,此DDL同样支持扩展匹配。

同一时刻一个节点(域名或IP)只能归属一个虚拟集群。

若缩容节点有资源被使用,则缩容会提示失败。

6. 虚拟集群属性

随着虚拟集群的引入,有些GUC不再是全局范围的定义而是从属于虚拟集群的属性,我们将这些GUC移入pg_vcluster中,将其作为虚拟集群的属性。

GUC与虚拟集群属性对照表

GUC VCPROPERTY Default
default_hash_table_bucket_number hash_table_bucket_number 8
hawq_rm_nvseg_perquery_limit max_nvseg_perquery 512
hawq_rm_nvseg_perquery_perseg_limit max_nvseg_perquery_perseg 8
default_magma_hash_table_nvseg_per_seg magma_hash_table_nvseg_perseg 8

设置虚拟集群属性

1
2
3
ALTER VCLUSTER <name> WITH (<VCPROPERTY>=<value> [, <VCPROPERTY>=<value>]) [IN SESSION]

ALTER VCLUSTER <name> WITHOUT (<VCPROPERTY> [, <VCPROPERTY>]) [IN SESSION]

设置使用WITH,取消使用WITHOUT(不要设值)。 持久话不要加IN SESSION,临时设置请使用IN SESSION。

显示虚拟集群属性

1
SHOW VCPROPERTY <name>

虚拟集群属性的使用/显示按照以下优先级:SESSION>CATALOG>DEFAULT。

7. FAQ

7.1. 资源队列和ROLE

  • 使用vcname.rsqname来表示资源队列,以前的pg_root/pg_default可以对应成vc_default.pg_root/pg_default。

  • 修改用户的资源队列同样请使用vcname.rsqname来表示。

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

  • 没有了none资源队列,如果需要请用vc_default.pg_default。

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

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

    1
    2
    3
    4
    select * from pg_vcluster
      where oid = (select vcid from pg_resqueue
        where oid=(select rolresqueue from pg_authid
          where rolname=(select current_user)));
    

7.2. RM拒绝资源申请请求

Deferred the resource request because the resource queues have no valid resource capacities yet.

出现这种情况意味着当前用户绑定的资源队列没有可用资源,可以进行以下步骤进行检查:

  1. 检查用户绑定的资源队列,理论上报了此错误,则segcore为-1,segsize为0
  2. 检查对应虚拟集群,vcseg列是否有节点:
    • 若没有节点,需要向vc加入节点后使用。
    • 若有节点,则进一步排查。
  3. 检查节点健康状况,观察vcseg中的节点在gp_segment_configuration是否健康:
    • 若节点显示`d`则需要排查节点状况,令其可用。
    • 若vcseg中的节点没在gp_segment_configuration中出现,或一个是IP一个是域名,则意味着域名解析错误,需要检查/etc/hosts,确认域名与IP对应一致。

7.3. 如何正确扩容

4.4.0.0版本以前,在对应节点上开启OushuDB的segment进程即可。4.4.0.0版本以后,开启segment进程只会将其识别为isolated节点,可以在gp_segment_configuration中看到此信息,此时需要按需手动将其加入到某个虚拟集群中使用。