本篇博客主要翻译整理自vertica官方博客,以对资源管理,特别是资源池的配置做一个总结。
资源管理
原文可参考:https://www.vertica.com/blog/resource-management/
对数据库运行的所有加载和查询都会占用系统资源,例如CPU,内存,磁盘I / O,带宽,文件句柄等,而查询性能取决于分配给它的资源数量。在单用户环境中,系统可以将所有资源专用于单个查询,从而最有效地执行查询。然而在系统上运行多个查询时,查询将共享资源,因此,每个查询运行所需的时间比运行自身时要长。资源管理器可帮助您确定资源使用的优先级。
资源管理器
资源管理器在资源池上运行。资源池是系统资源的预分配子集,具有关联的队列。
内置资源池
有如下内置资源池:
Resource Pool | Description |
---|---|
GENERAL | Answers requests that have no specific resource pool associated with them. |
BLOBDATA | Controls resource usage for in-memory blobs. |
DBD | Controls resource usage for Database Designer processing. |
JVM | Controls Java Virtual Machine resources used by Java UDXs. |
METADATA | Tracks memory that is allocated for catalog data. |
RECOVERY | Used when recovering another node of the database. |
REFRESH | Used when refreshing newly added projections. |
SYSDATA | Reserved for temporary storage of intermediate results of queries against system monitoring and catalog tables. |
SYSQUERY | Reserved for temporary storage of intermediate results of queries against system monitoring and catalog tables. |
TM (Tuple Mover) | Controls resources for queries associated with the Tuple Mover. |
WOS (Write Optimized Store) | Controls WOS usage. |
用户自定义资源池
您可以使用自己的资源池补充内置资源池,以处理特定于数据库的需求。如果跨不同类别的工作负载具有竞争资源要求,则用户定义的资源池非常有用。
使用用户定义的资源池,可以:
- 处理工作负载类
- 限制内存使用,并发和优先级
- 将用户限制为特定资源池
示例:管理高优先级查询
想象一下,您的企业CEO经常通过第三方BI工具运行以下查询:
=> SELECT DISTINCT s.product_key, p.product_description
FROM store.store_sales_fact s, public.product_dimension p
WHERE s.product_key = p.product_key AND s.product_version = p.product_version
AND s.store_key IN (SELECT store_key FROM store.store_dimension WHERE store_state = 'MA')
ORDER BY s.product_key;
您希望确保查询始终具有要运行的资源。运行此查询时,Management Console会显示它使用与其他查询共享的常规资源池。排队使用常规池的查询偶尔会超时。对于CEO需要运行的查询,这是不可接受的。要确保CEO查询始终完成,请创建专用于它们的资源池:
1.确定要为CEO查询分配的内存量。在前面显示的查询上运行PROFILE命令:
=> PROFILE SELECT DISTINCT s.product_key, p.product_description
FROM store.store_sales_fact s, public.product_dimension p
WHERE s.product_key = p.product_key AND s.product_version = p.product_version
AND s.store_key IN (SELECT store_key FROM store.store_dimension WHERE store_state = 'MA')
ORDER BY s.product_key;
NOTICE 4788: Statement is being profiled
HINT: Select * from v_monitor.execution_engine_profiles where transaction_id=45035996274783380 and statement_id=1;
NOTICE 3557: Initiator memory for query: [on pool general: 693504 KB, minimum: 640011 KB]
product_key | product_description
-------------+----------------------------------------
1 | Brand #1 butter
1 | Brand #2 bagels
2.查询返回一个提示并估计查询所需的内存量。从提示中复制事务和语句ID,并在以下查询中使用它们来确认查询实际使用了多少内存:
=> SELECT MAX (memory_kb) memory_kb FROM dc_resource_acquisitions WHERE transaction_id = 45035996274783380 AND statement_id = 1;
memory_kb
-----------
696213
(1 row)
3.以超级用户身份 创建至少具有该内存量的资源池:
=> CREATE RESOURCE POOL ceo_pool MEMORYSIZE '700000K';
注意:Vertica支持许多选项用于自定义资源池。其中包括:修改内存大小,优先级和并发性。创建资源池后,可以稍后使用ALTER RESOURCE POOL
对其进行修改。
4.在ceo_pool上授予用户ceo使用权限:
=> GRANT USAGE ON RESOURCE POOL ceo_pool TO ceo;
5.将此用户与池关联:
=> ALTER USER ceo RESOURCE POOL ceo_pool;
将用户ceo与资源池ceo_pool关联后,为该池分配的资源仅为该用户的查询保留。如果需要,您可以将此资源池的使用扩展到其他用户或角色。现在,切换到ceo用户并再次运行查询:
=> \c - ceo
You are now connected as user "ceo".
=> SELECT DISTINCT s.product_key, p.product_description
FROM store.store_sales_fact s, public.product_dimension p
WHERE s.product_key = p.product_key AND s.product_version = p.product_version
AND s.store_key IN (SELECT store_key FROM store.store_dimension WHERE store_state = 'MA')
ORDER BY s.product_key;
检查管理控制台时,它确认查询使用资源池ceo_pool中的资源。
示例:为批量加载分配资源
批量加载通常比常规查询需要更多的时间和内存,如前面所示。通过将资源池用于批量加载,通用池可以自由处理查询。批处理负载被分配给它们自己的资源池,该资源池被分配了有效处理负载操作所需的资源。
1.首先,我们将为资源池创建一个用户:
=> CREATE USER etluser;
2.为批量加载创建资源池:
=> CREATE RESOURCE POOL batch_pool MEMORYSIZE '2G' MAXMEMORYSIZE'6G' MAXCONCURRENCY 3;
3.接下来,为新资源池上的etluser授予使用权限,并将此用户与资源池关联:
=> GRANT USAGE ON RESOURCE POOL batch_pool TO etluser;
=> ALTER USER etluser RESOURCE POOL batch_pool;
当etluser时运行批处理加载,您可以使用管理控制台确认加载操作使用batch_pool中的资源。
Vertica查询预算
原文可参考:https://www.vertica.com/blog/do-you-need-to-put-your-query-on-a-budgetba-p236830/
在Vertica中执行查询时,启动器节点确定Vertica存储数据的位置,可用的投影,可用CPU带宽和其他因素。根据此信息,启动器节点创建查询计划并将其发送到将帮助执行查询的每个节点。
然后,每个节点估计执行其部分查询所需的内存量和并发性。这是查询预算。
通常,计算的查询预算可为查询提供最佳性能。但是,与忽略资产负债表非常相似,忽略资源池参数会对查询性能产生负面影响。
查询预算因素
Vertica根据与执行查询的资源池关联的以下参数估计查询预算:
- MEMORYSIZE
- MAXMEMORYSIZE
- PLANNEDCONCURRENCY
此外,每个资源池都有一个排队阈值。对于每个资源池:
排队阈值=池的MAXMEMORYSIZE的95%
当针对资源池的所有请求使用的内存量超过排队阈值时,针对池的新请求将排队,直到内存可用。
如果您没有为资源池指定MAXMEMORYSIZE,则MAXMEMORYSIZE将等于池的MEMORYSIZE加上GENERAL池的MAXMEMORYSIZE。因此,如果未设置池的MEMORYSIZE(默认值为0),则MAXMEMORYSIZE只是GENERAL池的MAXMEMORYSIZE。
您可以在RESOURCE_POOL_STATUS系统表中查看所有这些值。
查询预算计算
使用上面列出的资源池参数,Vertica以下列方式计算每个资源池的查询预算:
-
GENERAL资源池:
查询预算= GENERAL池的排队阈值/ GENERAL池的PLANNEDCONCURRENCY。 -
如果MEMORYSIZE设置为0且未设置MAXMEMORYSIZE
查询预算=GENERAL池的排队阈值/ PLANNEDCONCURRENCY -
如果MEMORYSIZE设置为0并且MAXMEMORYSIZE设置为默认值以外的值:
查询预算=资源池的排队阈值/资源池的PLANNEDCONCURRENCY。 -
如果MEMORYSIZE设置为默认值以外的值:
查询预算=资源池的排队阈值/资源池的PLANNEDCONCURRENCY
下图显示了上述计算的示例:
调整查询预算
通过调整MEMORYSIZE和PLANNEDCONCURRENCY参数,可以限制查询使用的内存量。换句话说,您可以设置查询预算。
如果因为出于其他目的需要而减少MAXMEMORYSIZE,请注意这将减少查询预算。减少查询预算会对查询性能产生负面影响,尤其是在查询很复杂的情况下。
要维护资源池的原始查询预算,在减少MAXMEMORYSIZE时,请务必还要减少PLANNEDCONCURRENCY的值。
补充:
1.参看用户绑定的资源池。使用系统表users。
SELECT * FROM users WHERE user_name ='ceo_user';
-[ RECORD 1 ]-----+--------------------------------------------------
user_id | 45035996273733402
user_name | ceo_user
is_super_user | f
profile_name | default
is_locked | f
lock_time |
resource_pool | ceo_pool
memory_cap_kb | unlimited
temp_space_cap_kb | unlimited
run_time_cap | unlimited
all_roles |
default_roles |
search_path | "$user", public, v_catalog, v_monitor, v_internal
2.显示内置和用户定义资源池的设置。查看系统表RESOURCE_POOLS
。
3.更多资源管理的配置查看,可参考:
https://www.vertica.com/docs/9.1.x/HTML/index.htm#Authoring/AdministratorsGuide/ResourceManager/ManagingWorkloads.htm