HAWQ技术解析(十三) —— 资源管理

2018-01-03 14:49:20 浏览数 (1)

一、HAWQ如何管理资源

        HAWQ使用多种机制管理CPU、内存、I/O、文件句柄等系统资源,包括全局资源管理、资源队列、强制资源使用限额等。

1. 全局资源管理

        Hadoop通常使用YARN全局管理资源。YARN是一个通用的资源管理框架,为MapReduce作业或其它配置了YARN的应用提供资源。在YARN环境中,资源分配的单位被称为容器(container),YARN还能强制限制每个集群节点上的可用资源。图1展示了Hadoop YARN环境下的HAWQ集群布局。

图1

        可以将HAWQ配置为一个在YARN中注册的应用,执行查询时,HAWQ的资源管理器与YARN通信以获取所需的资源。之后HAWQ master主机上的资源管理器管理分配这些从YARN获得的资源。当资源使用完成时返还给YARN。

2. HAWQ资源队列

        资源队列是HAWQ系统中并发管理的主要工具,它是一种数据库对象,可以使用CREATE RESOURCE QUEUE语句创建。资源队列控制可以并发执行的活跃查询数量,以及为每种查询类型分配的最大内存、CUP数量。资源队列还可以限制一个查询消耗的资源总量,避免个别查询使用过多的资源而影响系统整体的性能。

        HAWQ内部基于资源队列层次系统动态管理资源。资源队列的数据结构为一棵n叉树,如图2所示。

图2

        HAWQ初始化后有一个根队列pg_root和一个缺省的队列pg_default。如果使用YARN模式,HAWQ资源管理器自动从全局资源管理器获得根队列资源。当创建了一个新的资源队列时,必须指定其父队列,以这种方式将所有资源队列组织到一棵树中。

        执行查询时,进行编译和语义分析后,优化器与HAWQ资源管理器协调查询的资源使用情况,得到基于可用资源的优化的查询计划。查询分发器将每个查询的资源分配与查询计划一同发送给segment。这样,segment上的查询执行器(QE)就知道当前查询的资源配额,并在整个执行过程中使用这些资源。查询结束或终止后,资源返还给HAWQ资源管理器。

        资源队列树中,只有叶子队列可以被授予角色和接受查询。资源分配策略如下:

  • 只为正在运行或排队的查询分配资源队列。
  • 多个查询竞争时,HAWQ资源管理器自动依据可用资源情况平衡队列间的资源。
  • 在一个资源队列中,如果有多个查询等待资源,最终资源以Best-Effort方式分配给每个查询。

二、资源管理器配置最佳实践

        配置资源管理时可以使用下面HAWQ给出的的实践原则,保证高效的资源管理和最佳系统性能:

  • segment节点没有相同的IP地址。某些软件使用自动配置IP地址的虚拟网卡,这可能造成某些HAWQ segment得到相同的IP地址。这种情况下,资源管理器的容错服务组件只能认到相同IP中的一个segment。
  • 所有segment配置相同的资源容量配额。
  • 为了避免资源碎片化,配置segment资源配额为所有虚拟段资源限额的整数倍。
  • 确保有足够已注册的segment响应资源请求。如果失效的segment超过了限制,资源请求被拒绝。
  • master和segment使用多个独立的大磁盘(2T或以上)的临时目录,例如/disk1/tmp /disk2/tmp,保证写临时文件的负载均衡。对于给定查询,HAWQ为每个虚拟段使用一个单独的临时目录存储溢出文件。多个HAWQ会话也是用自己的临时目录避免磁盘竞争。如果临时目录过少,或者多个临时目录存储在同一个磁盘上,会增加磁盘竞争或磁盘空间用尽的风险。
  • 最小化每个segment的YARN容器数,并设置空闲资源返还YARN的超时时间。
  • yarn.scheduler.minimum-allocation-mb参数设置成可以被1G整除,如1024、512等。

三、独立资源管理器

        HAWQ中的资源管理器配置主要涉及以下几个方面:

  • 确定使用哪种资源管理模式。HAWQ支持两种管理模式:独立模式与外部全局资源管理器模式。独立模式也叫无全局资源管理模式。在该模式下,HAWQ使用集群节点资源时,不考虑其它共存的应用,HAWQ假设它能使用所有segment的资源。对于专用HAWQ集群,独立模式是可选的方案。当前HAWQ支持YARN作为外部全局资源管理器。该模式下,HAWQ作为一个YARN的应用,使用YARN管理的集群资源。
  • 如果选择独立资源管理模式,需要决定是否限制分配给每个HAWQ segment使用的内存与CPU。
  • 如果使用YARN模式,需要在YARN中为HAWQ配置资源队列,还要在HAWQ进行与YARN相关的配置。HAWQ自动注册为YARN应用,使用YARN中配置的资源队列。
  • 在HAWQ中,创建资源队列。

1. 使用独立模式

        为了配置HAWQ运行独立资源管理模式,在master上的hawq-site.xml文件中设置以下属性:

代码语言:javascript复制
<property>
      <name>hawq_global_rm_type</name>
      <value>none</value>
</property>

        该属性为全局设置,需要重启HAWQ以生效。当然也可以使用ambari,在HAWQ->Configs->Resource Manager进行设置,然后重启HAWQ服务。

        hawq_global_rm_type参数代表HAWQ全局资源管理类型,有效值为yarn和none。设置为none表示由HAWQ的资源管理器自己管理资源。设置为yarn意味着与YARN协调使用资源。缺省安装时使用的是独立模式。

代码语言:javascript复制
[gpadmin@hdp3 ~]$ hawq config -s hawq_global_rm_type
GUC		: hawq_global_rm_type
Value		: none
[gpadmin@hdp3 ~]$ 

2. 配置segment资源限制

        使用独立模式(hawq_global_rm_type=none)时,可以限制每个HAWQ segment所能使用的资源。配置方法是在hawq-site.xml文件中增加以下参数:

代码语言:javascript复制
<property>
   <name>hawq_rm_memory_limit_perseg</name>
   <value>8GB</value>
</property>
<property>
   <name>hawq_rm_nvcore_limit_perseg</name>
   <value>4</value>
</property>

        hawq_rm_memory_limit_perseg参数设置独立资源管理模式下,每个HAWQ segment使用的最大内存数。hawq_rm_nvcore_limit_perseg参数设置每个HAWQ segment使用的最大CPU虚拟核数。

        因为XML的配置验证,在YARN模式下也需要设置这些属性,即使该模式下不会使用这些参数。所有segment都配置成相同的值,内存应该设置成1G的倍数。并且为了降低形成资源碎片的可能性,hawq_rm_memory_limit_perseg应该配置成所有虚拟段资源限额(通过资源队列的VSEG_RESOURCE_QUOTA配置)的倍数。例如,hawq_rm_memory_limit_perseg设置成15G,但是虚拟段资源限额设置成2G,那么一个segment可以使用的最大内存只有14G。

3. 配置查询语句的资源限额

        某些场景下,可能需要在查询语句级增加资源限额。以下配置属性允许用户通过修改相应的资源队列控制限额:

  • hawq_rm_stmt_vseg_memory
  • hawq_rm_stmt_nvseg

        hawq_rm_stmt_vseg_memory定义每个虚拟段的内存限额,hawq_rm_stmt_nvseg定义下个执行的查询所使用的虚拟段个数,缺省值为0,表示不能在语句级设置资源限额。下面的例子中,执行下个查询语句时,HAWQ的资源管理器将分配10个虚拟段,每个虚拟段有256M的内存限额。

代码语言:javascript复制
db1=# set hawq_rm_stmt_vseg_memory='256mb';
SET
db1=# set hawq_rm_stmt_nvseg=10;
SET
db1=# create table t(i integer);
CREATE TABLE
db1=# insert into t values(1);
INSERT 0 1
db1=# 

        HAWQ是动态为给定查询语句分配资源的,资源管理器只是分配segment的资源,而不会为查询保留资源。并且,语句级设置的虚拟段数不要超过全局配置参数hawq_rm_nvseg_perquery_limit的值。

4.配置最大虚拟段数

        可以在服务器级限制语句执行时使用的虚拟段数,这能防止数据装载期间的资源瓶颈或过渡消耗资源带来的性能问题。在Hadoop集群中,NameNode和DataNode可以并发打开的写文件数是有限制的,考虑下面的场景:

  • 需要向有P个分区的表导入数据。
  • 集群中有N个节点,为了导入数据,每个节点上启动了V个虚拟段。

        则每个DataNode要打开P * V个文件,至少启动P * V个线程。如果P和V的数量很大,DataNode将成为瓶颈。而在NameNode上将有V * N个连接,如果节点很多,那么NameNode可能成为瓶颈。

        为了缓解NameNode的负载,使用下面的服务器配置参数限制V的大小,即每个节点启动的最大虚拟段数。

  • hawq_rm_nvseg_perquery_limit:在服务器级别上限制执行一条语句可以使用的最大虚拟段数量,缺省值为512。default_hash_table_bucket_number定义的哈希桶数不能超过hawq_rm_nvseg_perquery_limit。
  • default_hash_table_bucket_number:定义哈希表使用的缺省桶数。查询哈希表时,分配给查询的虚拟段数是固定的,等于表的桶数。一般集群扩容后应当调整此参数。

        还可以在资源队列配置中限制查询使用的虚拟段数量。全局配置参数是“硬限制”,资源队列或语句级别的限额不能超过服务器级别的限额。

四、整合YARN

        HAWQ支持YARN作为全局资源管理器。在YARN管理的环境中,HAWQ动态向YARN请求资源容器,资源使用完成后返还YARN。此特性让HAWQ有效利用Hadoop的资源管理能力,并使HAWQ成为Hadoop生态圈的一员。总的来说,可以使用以下步骤整合YARN与HAWQ:

  1. 安装YARN。如果使用HDP 2.3版本,必须设置yarn.resourcemanager.system-metrics-publisher.enabled=false。
  2. 配置YARN使用CapacityScheduler调度器,并为HAWQ保留一个单独的应用队列。
  3. 启用YARN的高可用特性(可选)。
  4. 配置HAWQ的YARN模式。
  5. 根据需要调整HAWQ的资源使用:为HAWQ修改相应的YARN资源队列配额(刷新YARN资源队列不需要重启HAWQ);通过修改HAWQ资源队列进行资源消耗的细粒度控制;其它配置,如设置每个HAWQ segment的最小YARN容器数,或修改HAWQ的空闲资源超时时间等。

1. 配置YARN

        查询请求资源执行时,HAWQ的资源管理器与YARN的资源调度器协商资源分配。查询执行完毕后,HAWQ资源管理器向YARN调度器返回占用的资源。为了使用YARN,最好为HAWQ配置独立的应用资源队列。YARN为特定的资源调度器配置资源队列,调度器根据资源队列的配置为应用分配资源。目前HAWQ仅支持YARN的Capacity调度器。

下面的例子说明如何使用ambari配置CapacityScheduler作为YARN的调度器。

(1)登录ambari

(2)选择YARN -> Configs -> Advanced -> Scheduler,如图3所示

图3

(3)在yarn.resourcemanager.scheduler.class输入框中输入以下值:

代码语言:javascript复制
org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler

        该属性值设置YARN的调度器为Capacity。

(4)在Capacity Scheduler输入框中输入以下内容:

代码语言:javascript复制
yarn.scheduler.capacity.maximum-am-resource-percent=0.2
yarn.scheduler.capacity.maximum-applications=10000
yarn.scheduler.capacity.node-locality-delay=40
yarn.scheduler.capacity.root.acl_administer_queue=*
yarn.scheduler.capacity.root.capacity=100
yarn.scheduler.capacity.root.queues=mrque1,mrque2,hawqque
yarn.scheduler.capacity.root.hawqque.capacity=20
yarn.scheduler.capacity.root.hawqque.maximum-capacity=80
yarn.scheduler.capacity.root.hawqque.state=RUNNING
yarn.scheduler.capacity.root.hawqque.user-limit-factor=1
yarn.scheduler.capacity.root.mrque1.capacity=30
yarn.scheduler.capacity.root.mrque1.maximum-capacity=50
yarn.scheduler.capacity.root.mrque1.state=RUNNING
yarn.scheduler.capacity.root.mrque1.user-limit-factor=1
yarn.scheduler.capacity.root.mrque2.capacity=50
yarn.scheduler.capacity.root.mrque2.maximum-capacity=50
yarn.scheduler.capacity.root.mrque2.state=RUNNING
yarn.scheduler.capacity.root.mrque2.user-limit-factor=1

        缺省的Capacity调度策略只有一个名为default的资源队列。以上属性在根队列下设置两个MapReduce队列和一个名为hawqque的HAWQ专用队列,三个队列并存,共享整个集群资源。hawqque队列可以使用整个集群20%到80%的资源。表1说明了队列配置的主要属性及其含义。

属性名称

描述

yarn.scheduler.capacity.maximum-am-resource-percent

集群中可用于运行application master的资源比例上限,通常用于限制并发运行的应用程序数目。示例中设置为0.2,即20%。

yarn.scheduler.capacity.maximum-applications

集群中所有队列同时处于等待和运行状态的应用程序数目上限,这是一个强限制,一旦集群中应用程序数目超过该上限,后续提交的应用程序将被拒绝,默认值为10000。

yarn.scheduler.capacity.node-locality-delay

调度器尝试调度一个rack-local container之前,最多跳过的调度机会。通常该值被设置成集群中机架数目,缺省值为40,接近一个机架中的节点数目。

yarn.scheduler.capacity.<queue_name>.queues

定义本队列下的资源队列。即资源队列树中某节点的直接下级节点。

yarn.scheduler.capacity.<queue_name>.capacity

一个百分比的值,表示队列占用整个集群的百分之多少比例的资源。

yarn.scheduler.capacity.<queue_name>.maximum-capacity

弹性设置,队列最多占用多少比例的资源。

yarn.scheduler.capacity.<queue_name>.state

队列状态,可以是RUNNING或STOPPED。

yarn.scheduler.capacity.<queue_name>.user-limit-factor

每个用户的低保百分比,比如设置为1,则表示无论有多少用户在跑任务,每个用户占用最低不会少于1%的资源。

表1

(5)保存配置并重启YARN服务,之后可以在YARN资源管理器的用户界面看到配置的三个队列,如图4所示。

图4

2. 在YARN中设置segment资源限制

        与独立资源管理模式类似,也可以通过YARN管理HAWQ segment的配额。HAWQ推荐将所有segment设置成相同的资源配额。在yarn-site.xml文件中设置如下属性:

代码语言:javascript复制
<property>
  <name>yarn.nodemanager.resource.memory-mb</name>
  <value>4GB</value>
</property>
<property>
  <name>yarn.nodemanager.resource.cpu-vcores</name>
  <value>1</value>
</property>

        或者使用ambari的YARN -> Configs -> Settings进行配置,yarn.nodemanager.resource.memory-mb和yarn.nodemanager.resource.cpu-vcores的设置分别如图5、图6所示。

图5

图6

  • yarn.nodemanager.resource.memory-mb:表示该节点上YARN可使用的物理内存总量,默认是8192MB。如果节点的内存资源不够8GB,则需要调减小这个值,YARN不会智能的探测节点的物理内存总量。
  • yarn.nodemanager.resource.cpu-vcores:表示该节点上YARN可使用的虚拟CPU个数,默认是8。目前推荐将该值设值为与物理CPU核数相同。如果节点的CPU核数不够8个,则需要调减小这个值,YARN不会智能的探测节点的物理CPU总数。

        与独立模式一样,HAWQ推荐每核内存数是1GB的倍数,如每核1G、2G、4G等。为了减少YARN模式下产生资源碎片的可能,应该遵从以下配置原则:

  • yarn.nodemanager.resource.memory-mb应该设置为虚拟段资源限额(在HAWQ资源队列中配置)的倍数。
  • 每核内存应该设置为yarn.scheduler.minimum-allocation-mb的倍数。

        比如YARN中的配置如下:

  • yarn.scheduler.minimum-allocation-mb=1024
  • yarn.nodemanager.resource.memory-mb=49152
  • yarn.nodemanager.resource.cpu-vcores=16

        HAWQ计算的每核内存为3GB(48GB/16)。由于yarn.scheduler.minimum-allocation-mb设置是1G,每个YARN容器内存为1GB。这样每核内存正好是YARN容器的3倍,不会形成资源碎片。但如果yarn.scheduler.minimum-allocation-mb设置为4GB,则每个YARN容器形成1GB的内存碎片空间(4GB - 3GB)。为了避免这种情况,可以修改yarn.nodemanager.resource.memory-mb为64GB,或者将yarn.scheduler.minimum-allocation-mb改为1GB。注意,如果将yarn.scheduler.minimum-allocation-mb设置为1GB或更小的值,该值应该能被1GB整除,如1024、512等。

3. 启用YARN模式

        配置完YARN,就可以在hawq-site.xml文件中添加如下属性,将YARN启用为HAWQ的全局资源管理器。

代码语言:javascript复制
<property>
   <name>hawq_global_rm_type</name>
   <value>yarn</value>
</property>

        或者使用ambari的HAWQ -> Configs -> Settings -> Resource Management 进行配置,如图7所示。

图7

        这样HAWQ资源管理器只会使用YARN分配的资源。

        YARN模式的HAWQ需要在hawq-site.xml文件中配置以下属性:

代码语言:javascript复制
<property>
   <name>hawq_rm_yarn_address</name>
   <value>hdp2:8050</value>
</property>
<property>
   <name>hawq_rm_yarn_scheduler_address</name>
   <value>hdp2:8030</value>
</property>
<property>
   <name>hawq_rm_yarn_queue_name</name>
   <value>hawqque</value></property>
<property>
   <name>hawq_rm_yarn_app_name</name>
   <value>hawq</value>
</property>

        或者使用ambari的HAWQ -> Configs -> Advanced -> Advanced hawq-site 进行配置,如图8所示。

图8

        表2包含了相关属性的描述。

属性名称

描述

hawq_rm_yarn_address

YARN服务器的主机和端口号,与yarn-site.xml中的yarn.resourcemanager.address属性相同。

hawq_rm_yarn_scheduler_address

YARN调度器的主机和端口号,与yarn-site.xml中的yarn.resourcemanager.scheduler.address属性相同。

hawq_rm_yarn_queue_name

YARN中HAWQ使用的资源队列名称。

hawq_rm_yarn_app_name

YARN中HAWQ使用的应用名称。

表2

4. 用YARN协调HAWQ资源

        为了保证资源管理的效率与查询性能,应该做适当的配置,协调YARN为HAWQ资源管理器分配资源。

(1)调整每个segment的最小YARN容器数

        当HAWQ刚注册到YARN,还没有工作负载时,HAWQ不需要立即获得任何资源。只有在HAWQ接收到第一个查询请求时,HAWQ资源管理器才开始向YARN请求资源。为保证为后续查询优化资源分配,同时避免与YARN协调过于频繁,可以调整hawq_rm_min_resource_perseg参数。无论初始查询的大小,每个HAWQ segment都至少会被分配指定的YARN容器数。该参数的缺省值为2,这意味着即便查询所需的资源很少,HAWQ资源管理器为每个segment至少获得两个YARN容器。

        此属性配置不能超过YARN中HAWQ资源队列的配额。例如,如果YARN中HAWQ队列的配额不大于整个集群的50%,并且每个YARN节点的最大内存与虚拟CPU核数分别为64GB和16,那么hawq_rm_min_resource_perseg的设置不能大于8。这是因为HAWQ资源管理器通过虚拟CPU核数获得YARN资源容器。

(2)设置YARN资源超时

        如果HAWQ的工作负载很低,HAWQ资源管理器已经获得的YARN资源有可能出现空闲的情况。可以调整hawq_rm_resource_idle_timeout参数,让HAWQ资源管理器更快或更慢地向YARN返还空闲资源。例如,HAWQ资源管理器获取资源的过程会造成查询延时。为了让HAWQ资源管理器更长时间持有已获资源,以备后面的查询工作使用,可增加hawq_rm_resource_idle_timeout的值。该参数的缺省值为300秒。

五、资源队列层次

        通过定义层次化的资源队列,系统管理员能够根据需要均衡分配系统资源。

        资源队列是使用CREATE RESOURCE QUEUE语句创建的数据库对象,是HAWQ系统中管理并发度的主要工具。可以使用资源队列控制并发执行的活跃查询的数量,以及分配给每种查询类型使用的最大内存与CPU数量。资源队列还可以防止某些查询因消耗太多系统资源,影响系统整体性能的情况。HAWQ内部将资源队列组织为一棵如图2所示的n叉树。HAWQ初始化后,有一个名为pg_root的根队列,根下有一个名为pg_default的缺省队列,图2中用灰色节点表示。

1. 设置资源队列最大数

        可以配置HAWQ集群中允许的资源队列最大数量,缺省值为128,值域范围是3 - 1024。

代码语言:javascript复制
[gpadmin@hdp3 ~]$ hawq config -s hawq_rm_nresqueue_limit
GUC		: hawq_rm_nresqueue_limit
Value		: 128
[gpadmin@hdp3 ~]$

        手工编辑hawq-site.xml文件或使用ambari界面配置该参数,新值在HAWQ重启后生效。下面例子将最大资源队列数设置成50。

代码语言:javascript复制
<property>
   <name>hawq_rm_nresqueue_limit</name>
   <value>50</value>
</property>

        执行以下命令检查运行时的参数设置:

代码语言:javascript复制
db1=# show hawq_rm_nresqueue_limit;
 hawq_rm_nresqueue_limit 
-------------------------
 128
(1 row)

        该参数不能在服务器启动后动态改变:

代码语言:javascript复制
db1=# set hawq_rm_nresqueue_limit=50;
ERROR:  attempted change of parameter "hawq_rm_nresqueue_limit" ignored
DETAIL:  This parameter cannot be changed after server start.
db1=# 

2. 资源队列维护

(1)创建资源队列

        使用CREATE RESOURCE QUEUE语句创建资源队列。只有管理员用户才能运行该DDL语句。创建资源队列时需要指定队列的名称、父队列名称、CPU和内存限制等,还能可选限制队列中的活跃语句数量。

        下面的语句在pg_root下创建一个名为myqueue的资源队列,限制活跃查询数为20,内存和CPU核数最多为集群总量的10%:

代码语言:javascript复制
db1=# create resource queue myqueue with (parent='pg_root', active_statements=20,
db1(# memory_limit_cluster=10%, core_limit_cluster=10%);
CREATE QUEUE
db1=# 

        一个父队列下的所有直接子队列的资源限制总和不能超过100%。例如,缺省的pg_default队列的memory_limit_cluster和core_limit_cluster为50%,刚刚建立的myqueue两者限制为10%,两个队列的限制总和是60%,此时无法再在pg_root下创建限制超过40%的资源队列。

代码语言:javascript复制
db1=# create resource queue myqueue1 with (parent='pg_root', active_statements=20,
db1(# memory_limit_cluster=50%, core_limit_cluster=50%);
ERROR:  the value of core_limit_cluster and memory_limit_cluster exceeds parent queue's limit, wrong value = 50%
db1=# 

        下面的语句在pg_root下创建一个名为test_queue_1的资源队列,内存和CPU核数最多为集群总量的40%,并指定资源过度使用因子为2:

代码语言:javascript复制
db1=# create resource queue test_queue_1 with (parent='pg_root',
db1(# memory_limit_cluster=30%, core_limit_cluster=30%, resource_overcommit_factor=2);
CREATE QUEUE
db1=# 

        RESOURCE_OVERCOMMIT_FACTOR是一个可选属性,定义有多少资源能够被过度使用,缺省值为2.0,最小值为1.0。如果设置RESOURCE_OVERCOMMIT_FACTOR为3.0,同时将MEMORY_LIMIT_CLUSTER设置为30%,那么最大可能的资源分配为90%(30% * 3)。如果资源限制与RESOURCE_OVERCOMMIT_FACTOR相乘的结果值大于100%,采用100%。

(2)修改资源队列

        使用ALTER RESOURCE QUEUE语句修改资源队列。只有管理员用户才能运行该DDL语句。该语句可以修改队列的资源限制和活跃语句数,但不能改变一个队列的父队列,创建资源队列时的约束同样适用于修改语句。

        可以在队列正在被使用时进行修改,所有队列中排队的资源请求都调整为基于修改后的队列。在修改队列时,排队的资源请求可能遇到某些冲突,如可能发生资源死锁,或者修改后的资源限额不能满足排队的请求等。为防止冲突,缺省情况下HAWQ会取消与新资源队列定义冲突的所有请求,该行为受服务器配置参数hawq_rm_force_alterqueue_cancel_queued_request控制,缺省设置是on。

代码语言:javascript复制
[gpadmin@hdp3 ~]$ hawq config -s hawq_rm_force_alterqueue_cancel_queued_request
GUC		: hawq_rm_force_alterqueue_cancel_queued_request
Value		: on
[gpadmin@hdp3 ~]$

        如果该参数设置为off,如果资源管理器发现新的队列定义与排队请求发生冲突,则取消ALTER RESOURCE QUEUE中指定的限制。

        以下语句修改资源队列的内存和CPU核数限制:

代码语言:javascript复制
db1=# alter resource queue test_queue_1 with (memory_limit_cluster=40%,core_limit_cluster=40%);
ALTER QUEUE
db1=#

        以下语句将资源队列的最大活跃语句数由缺省的20改为50:

代码语言:javascript复制
db1=# alter resource queue test_queue_1 with (active_statements=50);
ALTER QUEUE
db1=# 

(3)删除资源队列

        使用DROP RESOURCE QUEUE语句删除一个资源队列。只有管理员用户才能运行该DDL语句。满足以下条件的资源队列才能被删除:

  • 没有查询正在使用该队列。
  • 没有子队列。
  • 没有被赋予角色。

        不能删除系统资源队列pg_root和pg_default。

        以下语句从资源队列中删除角色(角色会被移到缺省的pg_default资源队列中):

代码语言:javascript复制
db1=# alter role wxy resource queue none;
ALTER ROLE
db1=# 

        以下语句删除myqueue资源队列。

代码语言:javascript复制
db1=# drop resource queue myqueue;
DROP QUEUE
db1=# 

(4)检查现有资源队列

        HAWQ的系统表pg_resqueue保存资源队列数据。下面的查询语句显示test_queue_1的相关信息:

代码语言:javascript复制
db1=# x
Expanded display is on.
db1=# select rsqname,
db1-#        parentoid,
db1-#        activestats,
db1-#        memorylimit,
db1-#        corelimit,
db1-#        resovercommit,
db1-#        allocpolicy,
db1-#        vsegresourcequota,
db1-#        nvsegupperlimit,
db1-#        nvseglowerlimit,
db1-#        nvsegupperlimitperseg,
db1-#        nvseglowerlimitperseg
db1-#   from pg_resqueue 
db1-#  where rsqname='test_queue_1';
-[ RECORD 1 ]--------- -------------
rsqname               | test_queue_1
parentoid             | 9800
activestats           | 50
memorylimit           | 40%
corelimit             | 40%
resovercommit         | 2
allocpolicy           | even
vsegresourcequota     | mem:256mb
nvsegupperlimit       | 0
nvseglowerlimit       | 0
nvsegupperlimitperseg | 0
nvseglowerlimitperseg | 0

db1=# 

        也可以从pg_resqueue_status系统视图检查资源队列的运行时状态:

代码语言:javascript复制
db1=# select * from pg_resqueue_status;
   rsqname    | segmem | segcore  | segsize | segsizemax | inusemem | inusecore | rsqholders | rsqwaiters | paused 
-------------- -------- ---------- --------- ------------ ---------- ----------- ------------ ------------ --------
 pg_root      | 256    | 0.125000 | 72      | 72         | 0        | 0.000000  | 0          | 0          | F
 pg_default   | 256    | 0.125000 | 36      | 72         | 0        | 0.000000  | 0          | 0          | F
 test_queue_1 | 256    | 0.125000 | 28      | 57         | 0        | 0.000000  | 0          | 0          | F
(3 rows)

        表3描述了pg_resqueue_status视图中各字段的含义。

字段名称

描述

rsqname

HAWQ资源队列名称。

segmem

每个虚拟段内存限额(MB)。

segcore

每个虚拟段的CPU虚拟核数限额。

segsize

资源队列能够为执行查询分配的虚拟段数。

segsizemax

过度使用其它队列的资源时,资源队列可为执行查询分配的最大虚拟段数。

inusemem

当前运行的语句使用的总内存(MB)。

inusecore

当前运行的语句使用的总CPU虚拟核数。

rsqholders

并发运行的语句数量。

rsqwaiters

排队语句的数量。

paused

指示在没有资源状态改变时,资源队列是否临时性暂停。‘F’表示否,‘T’表示是,‘R’表示资源队列发生了资源碎片问题。

表3

        下面的语句查询所有资源队列的当前活动SQL: 

代码语言:javascript复制
select usename, rsqname, locktype, objid, transaction, pid, mode, granted, waiting
  from pg_stat_activity, pg_resqueue, pg_locks
 where pg_stat_activity.procpid=pg_locks.pid
   and pg_locks.objid=pg_resqueue.oid;

        下面的语句查询所有资源队列的当前等待SQL:

代码语言:javascript复制
select rolname, rsqname, pid, granted, current_query, datname
  from pg_roles, pg_resqueue, pg_locks, pg_stat_activity
 where pg_roles.rolresqueue=pg_locks.objid
   and pg_locks.objid=pg_resqueue.oid
   and pg_stat_activity.procpid=pg_locks.pid;

3. 给角色赋予资源队列

        资源队列对资源的管理是通过角色(用户)发挥作用的。角色被赋予某个资源队列,用该角色执行的查询受相应资源队列的限制。只允许为角色赋予叶子队列。

        下面的语句在创建或修改角色时赋予角色一个资源队列:

代码语言:javascript复制
db1=# create role rmtest1 with login resource queue pg_default;
CREATE ROLE
db1=# alter role rmtest1 resource queue test_queue_1;
ALTER ROLE
db1=# 

        下面的语句查看为角色分配的资源队列:

代码语言:javascript复制
db1=# select rolname, rsqname from pg_roles, pg_resqueue
db1-#  where pg_roles.rolresqueue=pg_resqueue.oid;
 rolname |   rsqname    
--------- --------------
 gpadmin | pg_default
 wxy     | pg_default
 rmtest1 | test_queue_1
(3 rows)

六、查询资源管理器状态

        通过一些查询能够导出资源管理器的细节信息,如活跃资源上下文状态、当前资源队列状态、HAWQ segment状态等。

1. 连接状态跟踪

        查询执行时从资源管理器请求分配资源,此时会有一个连接跟踪实例,记录查询资源使用的整个生命周期,从中可以找到所有的资源请求与分配情况。下面的查询获取保存连接跟踪状态信息的文件路径:

代码语言:javascript复制
db1=# select * from dump_resource_manager_status(1);
                              dump_resource_manager_status                               
-----------------------------------------------------------------------------------------
 Dump resource manager connection track status to /tmp/resource_manager_conntrack_status
(1 row)

        表4总结了该文件中的输出字段及其描述。

字段名称

描述

Number of free connection ids

空闲的连接跟踪实例数量。HAWQ资源管理器支持最多65536个活动连接跟踪实例。

Number of connection tracks having requests to handle

资源管理器已经接受但还没有处理的请求数量。

Number of connection tracks having responses to send

资源管理器已经生成但还没有发送出去的响应数量。

SOCK

请求的socket连接信息。

CONN

请求的角色名称、目标队列和当前状态等信息。 prog=1表示连接建立 prog=2连接由用户注册 prog=3表示连接等待目标队列中的资源。 prog=4表示资源已经分配给连接。 prog>5表示失败或异常状态。

ALLOC

会话相关信息,如请求的资源、会话级资源限制、语句级资源设置、按查询计划分片数估计的工作量等等。

LOC

查询扫描HDFS的数据本地化信息。

RESOURCE

已经分配的资源信息。

MSG

最后收到的消息。

COMMSTAT

当前socket通信缓冲区状态。

表4

2. 资源队列状态

        下面的查询获取保存资源队列状态信息的文件路径:

代码语言:javascript复制
db1=# select * from dump_resource_manager_status(2);
                             dump_resource_manager_status                             
--------------------------------------------------------------------------------------
 Dump resource manager resource queue status to /tmp/resource_manager_resqueue_status
(1 row)

        表5总结了该文件中的输出字段及其描述。

字段名称

描述

Maximum capacity of queue in global resource manager cluster

YARN资源队列最大配额。

Number of resource queues

HAWQ资源队列总数量。

QUEUE

资源队列的基本结构信息,以及是否忙于为查询调度资源。

REQ

等待队列的计数和状态。

SEGCAP

虚拟段资源限额和可派发的虚拟段数量。

QUECAP

原始资源队列配额,以及一个队列可以使用的集群资源的实际百分比。

QUEUSE

资源队列使用信息。

表5

3. HAWQ segment状态

        下面的查询获取保存HAWQ segment状态信息的文件路径:

代码语言:javascript复制
db1=# select * from dump_resource_manager_status(3);
                            dump_resource_manager_status                            
------------------------------------------------------------------------------------
 Dump resource manager resource pool status to /tmp/resource_manager_respool_status
(1 row)

        表6总结了该文件中的输出字段及其描述。

字段名称

描述

HOST_ID

识别的segment名称和内部ID。

HOST_INFO

segment配置的资源配额。GRMTotalMemoryMB和GRMTotalCore显示YARN报告的限额,FTSTotalMemoryMB和FTSTotalCore显示HAWQ中配置的限额。

HOST_AVAILABILITY

segment对于HAWQ容错服务(fault tolerance service,FTS)和YARN是否可用。

HOST_RESOURCE

当前分配的和可用的资源,以及估算的负载计数器。

HOST_RESOURCE_CONTAINERSET

Segment持有的资源容器。

表6

0 人点赞