虚拟计算集群 ------------------- OushuDB 支持若干个节点组织为互斥的虚拟集群(VC)。虚拟集群可以使用户的资源使用限定在若干节点上,从而达到合理分配资源并隔绝错误。虚拟计算集群由 oushudb-topology.yaml 定义,用户可以通过视图 oushu_vcluster 查看。 虚拟集群实例(VCI)会根据虚拟集群的定义构造,是实际拥有资源和执行的实体。当 SQL 向某 VC 申请资源时,RM 内部会选择适当的 VCI 处理。VCI 之间不要求同构,即每个 VCI 可以拥有不同数量的节点。VCI 的信息会体现在 oushu_vcluster 中,名字形如 vcname@vciname。 1. 虚拟集群拓扑文件配置 ^^^^^^^^^^^^^^^^^^^^^^^^^ 虚拟集群配置允许用户使用拓扑文件描述,其拓扑定义在 OushuDB 配置文件 oushudb-topology.yaml 文件中, 下面是一个虚拟集群拓扑描述: .. code-block:: html :linenos: nodes: - id: m[1] addr: 192.168.1.11 label: { region: "regionA", zone: "zoneA"} - id: m[2] addr: 192.168.1.12 label: { region: "regionA", zone: "zoneA"} - id: m[3] addr: 192.168.1.13 label: { region: "regionA", zone: "zoneA"} vc: - name: mains vci: - nodes: m[1], m[2] - name: vc_default vci: - name: vci1 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) 5. 资源管理器选择优先级最高的 VCI,如果多个 VCI 的优先级相等,则使用 Round-robin 轮询选择一个。 6. 将资源管理器选择的 VCI 绑定给当前会话。 7. 结束。 根据以上算法: 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。 * 查看用户绑定的资源队列 .. code-block:: html :linenos: select * from pg_resqueue where rsqname = (select rsqname from pg_resqueue where oid=(select rolresqueue from pg_authid where rolname=(select current_user))); * 查看用户绑定的虚拟集群 .. code-block:: html :linenos: select * from oushu_vcluster where vc = (select split_part(rsqname, '.', 1) from pg_resqueue where oid=(select rolresqueue from pg_authid where rolname=(select current_user))); 资源队列和虚拟集群 """""""""""""""""""""""""""""" OushuDB 只有在初始化时会自动创建 vc_default.pg_default 队列,并且在初始化时为 oushudb-topology.yaml 中的虚拟集群自动创建 pg_default 队列。用户需要自行调整这些队列的 ACTIVE_STATMENTS 和 MEMORY_LIMIT 以适应实际环境。此后通过修改 oushudb-topology.yaml 新创建或删除的虚拟集群,用户需要手工创建或删除对应的资源队列。