这是本节的多页打印视图。
点击此处打印.
返回本页常规视图.
管理工作负载
Vertica 的资源管理架构支持在数据库中高效地运行不同的并发工作负载。对于基本操作,Vertica 会根据 RAM 和计算机内核数预配置内置 GENERAL 池。可以自定义 GENERAL 池,以便处理特定的并发要求。
也可以定义新的资源池并对其进行配置,以限制内存使用量、并发和查询优先级。之后,您可以视情况指定每个数据库用户使用特定资源池,以便控制其请求所占用的内存资源。
如果不同类别的工作负载之间存在资源争用需求,则用户定义的池很有用。示例场景如下:
-
一个大型批处理作业占用了所有服务器资源,导致更新网页的小型作业资源不足。这会降低用户体验。
在此场景中,可创建一个资源池来处理网页请求并确保用户获得所需的资源。也可以为批处理作业创建一个受限的资源池,以使该作业不能用尽所有系统资源。
-
某个应用程序的优先级低于其他应用程序,且您要限制低优先级应用程序的内存使用量和并发用户数。
在此场景中,可创建一个设有查询内存上限的资源池并将该池与低优先级应用程序的用户关联起来。
还可以使用资源池管理分配给正在运行的查询的资源。可以为资源池分配运行时优先级以及一个阈值,为持续时间不同的查询分配不同的优先级。有关详细信息,请参阅在查询运行时管理资源。
Enterprise 模式和 Eon 模式
在企业模式下,整个数据库有一组全局资源池。在 Eon 模式下,您可以在全局或按子群集分配资源。有关详细信息,请参阅管理 Eon 模式数据库中的工作负载资源。
1 - 资源管理器
在单用户环境中,系统可以将所有资源用于单个查询,使该查询得到最有效率的执行。您的环境更有可能需要同时运行几个查询,因此难以做到为每个查询提供最大数量的资源(运行时间最快),同时又能以合理运行时间同时为多个查询提供服务。
Vertica 资源管理器可以解决此矛盾,同时确保每个查询最终得到服务,实际系统限制始终被顾及。
例如,在系统面临资源压力时,资源管理器可能会对查询进行排队,直到资源可用或达到超时值。另外,在配置各个资源管理器设置时,您可以根据针对系统运行的并发查询的预期数量来优化每个查询的目标内存。
资源管理器对执行查询的影响
资源管理器以各种方式影响单个查询的执行。将查询提交到数据库时,会发生以下一系列事件:
-
对查询进行解析、通过优化查询确定执行计划,然后将查询分发到参与节点。
-
在每个节点上调用资源管理器,以评估运行查询所需的资源并与当前使用的资源进行比较。将发生下列情况之一:
-
当所有参与节点都允许查询运行时,查询即会开始运行。
注意
查询运行后,资源管理器将使用
RUNTIMEPRIORITY
和
RUNTIMEPRIORITYTHRESHOLD
参数进一步管理资源池的资源分配。有关详细信息
.
,请参阅
在查询运行时管理资源。
特定查询的资源分配和允许运行的最大查询数量取决于资源池配置。请参阅资源池架构。
在每个节点上,不会为处于队列中的查询保留或保存任何资源。但是,在某些节点上排队的多节点查询将持有其他节点上的资源。在这种情况下,Vertica 会竭力避免发生死锁。
2 - 资源池架构
资源管理器将资源处理为一个或多个资源池,这些池是使用关联队列预先分配的系统资源子集。
在企业模式下,有一组全局资源池适用于整个数据库中的所有子群集。在 Eon 模式下,您可以在全局或按子群集分配资源。全局级资源池适用于所有子群集。子群集级别的资源池允许您针对子群集执行的工作负载类型微调资源。如果您同时具有全局和子群集级别的资源池设置,则可以覆盖该子群集的任何与内存相关的全局设置。全局设置适用于没有子群集级别资源池设置的子群集。有关微调每个子群集的资源池的详细信息,请参阅管理 Eon 模式数据库中的工作负载资源。
Vertica 预配置了一组内置池,这些池将资源分配给不同请求类型,其中的 GENERAL 池根据计算机中的 RAM 和内核允许某种并发级别。
修改和创建资源池
可以根据实际的并发要求和性能要求配置内置的 GENERAL 池,如内置池中所述。也可以创建自定义池以处理各种类别的工作负载并可选择将用户请求限制在自定义池范围内。
您可以使用
CREATE RESOURCE POOL
创建用户定义的资源池,使用
ALTER RESOURCE POOL
修改用户定义的资源池。您可以针对内存使用、并发性和队列优先级配置这些资源池。您还可以将数据库用户或用户会话限制为使用特定的资源池。这样做可以让您控制内存、CPU 和其他资源的分配方式。
下图说明了在哪个资源池中执行了哪些数据库操作。仅显示了三个内置池。
2.1 - 定义辅助资源池
您可以定义正在运行的查询在超出初始资源池的 RUNTIMECAP
时可以级联到的辅助资源池。
确定辅助池
通过定义辅助资源池,您可以指定一个位置,超出正在运行查询的资源池的 RUNTIMECAP
的查询可以在该位置执行。这样,如果某个查询超出池的 RUNTIMECAP
,该查询可级联至具有更大 RUNTIMECAP
的池,而不会导致错误。当查询级联到另一个池时,原始池将重新获得此查询使用的内存。
因为不考虑在辅助池上授予权限,所以您可以使用此功能为用户查询指定辅助资源池而无需为用户提供在该池上运行查询的明确权限。
您还可使用辅助池来存储长时间运行的查询,以便日后使用。使用 PRIORITY HOLD
选项,您可以指定一个对队列重新排队的辅助池,直至达到 QUEUETIMEOUT
或者池的优先级更改为非保留值。
在 Eon 模式下,为特定于子群集的资源池定义辅助资源池时,需遵循以下限制:
-
全局资源池只能级联到其他全局资源池。
-
特定于子群集的资源池可以级联到全局资源池,或级联到属于同一子群集的另一个特定于子群集的资源池。如果子群集特定资源池级联到全局和子群集级别中均具有的用户定义资源池,则优先子群集级别资源池。例如:
=> CREATE RESOURCE POOL billing1;
=> CREATE RESOURCE POOL billing1 FOR CURRENT SUBCLUSTER;
=> CREATE RESOURCE POOL billing2 FOR CURRENT SUBCLUSTER CASCADE TO billing1;
WARNING 9613: Resource pool billing1 both exists at both subcluster level and global level, assuming subcluster level
CREATE RESOURCE POOL
查询级联路径
当达到初始池上的 RUNTIMECAP
时,Vertica 会将查询路由到辅助池。然后,Vertica 检查辅助池的 RUNTIMECAP
值。如果辅助池的 RUNTIMECAP
大于初始池的值,查询将在辅助池上执行。如果辅助池的 RUNTIMECAP
小于或等于初始池的值,Vertica 将在链中的下一个池上重新尝试查询,直至找到一个 RUNTIMECAP
大于初始池值的池。如果此时辅助池没有足够的可用资源来执行查询,SELECT
查询可能会在该池上重新排队、重新计划和中止。其他类型的查询会因为资源不足而失败。如果查询不存在合适的辅助池,查询将出现错误。
下图演示了执行查询时采用的路径。
查询执行时间分配
在 Vertica 找到用于运行查询的相应池之后,它会继续不间断地执行该查询。现在,查询在用于完成查询的两个池的 RUNTIMECAP
限制方面存在一些差异:
query execution time allocation = rp2 RUNTIMECAP - rp1 RUNTIMECAP
使用 CASCADE TO 参数
作为
超级用户,您可以使用
CREATE RESOURCE POOL
或
ALTER RESOURCE POOL
语句中的 CASCADE TO
参数来识别辅助池。辅助池必须已作为用户定义的池或 GENERAL
池存在。使用 CASCADE TO
时,不能创建资源池循环。
此示例说明了一个场景,其中管理员希望 user1
的查询在 user_0
资源池上启动,但在查询过长时级联到 userOverflow
池。
=> CREATE RESOURCE POOL userOverflow RUNTIMECAP '5 minutes';
=> CREATE RESOURCE POOL user_0 RUNTIMECAP '1 minutes' CASCADE TO userOverflow;
=> CREATE USER "user1" RESOURCE POOL user_0;
在此场景中,user1
无法在 userOverflow
资源池上启动他或她的查询,但由于不考虑为辅助池授予权限,因此如果辅助池超出 user_0
池的 RUNTIMECAP
,user1
的查询可以级联到 userOverflow
池。使用辅助池会释放主要池中的空间,因此可以运行简短的查询。
此示例显示了一个场景,即管理员想要长时间运行的查询在辅助池上保持排队状态。
=> CREATE RESOURCE POOL rp2 PRIORITY HOLD;
=> CREATE RESOURCE POOL rp1 RUNTIMECAP '2 minutes' CASCADE TO rp2;
=> SET SESSION RESOURCE_POOL = rp1;
在此场景中,在 rp1
上运行超过 2 分钟的查询将在 rp2
上排队,直至达到 QUEUETIMEOUT
,此时查询将被拒绝。
如果您尝试删除的资源池是另一个资源池的辅助池,则 Vertica 会返回一个错误。该错误会列出与您尝试删除的辅助池有关的资源池。要删除辅助资源池,首先在主要资源池上将 CASCADE TO 参数设置为 DEFAULT
,然后再删除辅助池。
例如,可以删除资源池 rp2
,它是 rp1
的辅助池,如下:
=> ALTER RESOURCE POOL rp1 CASCADE TO DEFAULT;
=> DROP RESOURCE POOL rp2;
参数注意事项
当查询进入辅助池时,该池的 CPUAFFINITYSET
和 CPUAFFINITYMODE
会应用于该查询。
查询会根据以下情况在不同时间采用辅助池的 RUNTIMEPRIORITY
:
-
如果当查询在主要池中运行时未启动 RUNTIMEPRIORITYTHRESHOLD
计时器,查询会在级联时采用辅助池的 RUNTIMEPRIORITY
。当未设置主要池的 RUNTIMEPRIORITYTHRESHOLD
时或者将主要池的 RUNTIMEPRIORITY
设置为 HIGH 时,即会发生上述情况。
-
如果达到主要池的 RUNTIMEPRIORITYTHRESHOLD
,查询会在级联时采用辅助池的 RUNTIMEPRIORITY
。
-
如果未达到主要池的 RUNTIMEPRIORITYTHRESHOLD
并且辅助池没有阈值,查询会在级联时采用新池的 RUNTIMEPRIORITY
。
-
如果未达到主要池的 RUNTIMEPRIORITYTHRESHOLD
并且辅助池设置了一个阈值:
-
如果主要池的RUNTIMEPRIORITYTHRESHOLD
大于或等于辅助池的 RUNTIMEPRIORITYTHRESHOLD
,查询在达到主要池的 RUNTIMEPRIORITYTHRESHOLD
之后会采用辅助池的 RUNTIMEPRIORITY
。
例如:
RUNTIMECAP
(主要池)为 5 秒
RUNTIMEPRIORITYTHRESHOLD
(主要池)为 8 秒
RUNTIMTPRIORITYTHRESHOLD
(辅助池)为 7 秒
在这种情况下,查询会在主要池上运行 5 秒,然后级联到次要池。再过去 3 秒(总共 8 秒)后,查询会采用次要池的 RUNTIMEPRIORITY
。
-
如果主要池的 RUNTIMEPRIORITYTHRESHOLD
小于辅助池的 RUNTIMEPRIORITYTHRESHOLD
,查询在达到辅助池的 RUNTIMEPRIORITYTHRESHOLD
之后将采用辅助池的 RUNTIMEPRIORITY
。
例如,主要池的
RUNTIMECAP
= 5 秒
RUNTIMEPRIORITYTHRESHOLD
(主要池)为 8 秒
RUNTIMTPRIORITYTHRESHOLD
(辅助池)为 12 秒
在这种情况下,查询会在主要池上运行 5 秒,然后级联到次要池。再过去 7 秒(总共 12 秒)后,查询会采用次要池的 RUNTIMEPRIORITY
。
2.2 - 查询资源池设置
您可以使用以下内容来获取有关资源池的信息:
有关资源池的运行时信息,请参阅监控资源池。
查询资源池设置
以下示例查询两个内部资源池 GENERAL 和 TM 的各种设置:
=> SELECT name, subcluster_oid, subcluster_name, maxmemorysize, memorysize, runtimepriority, runtimeprioritythreshold, queuetimeout
FROM RESOURCE_POOLS WHERE name IN('general', 'tm');
name | subcluster_oid | subcluster_name | maxmemorysize | memorysize | runtimepriority | runtimeprioritythreshold | queuetimeout
---------+----------------+-----------------+---------------+------------+-----------------+--------------------------+--------------
general | 0 | | Special: 95% | | MEDIUM | 2 | 00:05
tm | 0 | | | 3G | MEDIUM | 60 | 00:05
(2 rows)
查看对全局资源池的覆盖
在 Eon 模式下,您可以在系统表中查询 SUBCLUSTER_RESOURCE_POOL_OVERRIDES 以查看对各个子群集的全局资源池的任何覆盖。以下查询显示了一个覆盖在 analytics_1 子群集中将内置资源池 TM 的 MEMORYSIZE 和 MAXMEMORYSIZE 设置为 0% 的覆盖。这些设置阻止子群集执行 Tuple Mover 合并任务。
=> SELECT * FROM SUBCLUSTER_RESOURCE_POOL_OVERRIDES;
pool_oid | name | subcluster_oid | subcluster_name | memorysize | maxmemorysize | maxquerymemorysize
-------------------+------+-------------------+-----------------+------------+---------------+--------------------
45035996273705058 | tm | 45035996273843504 | analytics_1 | 0% | 0% |
(1 row)
2.3 - 用户配置文件
用户配置文件是与某个用户相关联的属性,用于控制该用户对多个系统资源的访问权限。这些资源包括:
-
分配给用户的资源池 (RESOURCE POOL)
-
用户会话可以使用的最大内存量 (MEMORYCAP)
-
用户会话可以使用的最大临时文件存储量 (TEMPSPACECAP)
-
用户查询可以运行的最长时间 (RUNTIMECAP)
可使用 CREATE USER 语句设置这些属性,之后可以使用 ALTER USER 修改这些属性。
可使用两种策略来限制用户对资源的访问权限:直接为用户设置属性来控制资源使用,或将用户分配到一个资源池。第一种方法允许您对单个用户进行微调,而第二种方法可以轻松将许多用户分到一组,然后设置他们的共同资源使用量。
如果要通过资源池分配来统一限制用户资源,请考虑以下事项:
-
除非用户拥有 GENERAL 池的权限或者已分配给默认资源池,否则他们无法登录 Vertica。
-
如果删除了用户的默认资源池,则用户的查询将使用 GENERAL 池。
-
如果用户没有 GENERAL 池的权限,则在您尝试删除为他们分配的资源池时,DROP 操作将失败。
在 Eon 模式数据库中,您可以将用户的默认资源池设置为特定于子群集的资源池。如果是这种情况,Vertica 将使用以下方法之一来确定在用户连接到子群集时使用哪个资源池进行查询:
-
如果子群集使用为用户分配的默认资源池,那么用户的查询将使用为用户分配的资源池。
-
如果子群集不使用用户分配的默认资源池,但用户有权访问 GENERAL 池,则用户的查询使用 GENERAL 池。
-
如果子群集不使用为用户分配的资源池,并且用户对于 GENERAL 池没有权限,则用户无法从该子群集的任何节点进行查询。
以下示例说明了何设置用户的资源池属性。有关其他示例,请参阅将用户定义的池和用户配置文件用于工作负载管理中描述的场景。
示例
设置用户的 RESOURCE POOL 属性以将该用户分配到一个资源池。若要创建一个名为 user1
的用户,并且该用户具有对资源池 my_pool
的访问权限,请使用以下命令:
=> CREATE USER user1 RESOURCE POOL my_pool;
若要不通过指定池的方式来限制用户的内存量,可将该用户的 MEMORYCAP
设置为一个特定单位或占总可用内存的百分比。例如,若要创建一个名为 user2
的用户,并且将其会话限制为每个会话使用 200 MB 内存,请使用以下命令:
=> CREATE USER user2 MEMORYCAP '200M';
若要限制允许用户查询运行的时间,可设置 RUNTIMECAP
属性。若要阻止 user2
的查询运行超过五分钟,可使用以下命令:
=> ALTER USER user2 RUNTIMECAP '5 minutes';
若要限制用户会话可以使用的临时磁盘空间量,可将 TEMPSPACECAP
设置为一个特定大小或占可用临时磁盘空间的百分比。例如,下一个语句将创建 user3
,并将其限制为使用 1 GB 的临时空间:
=> CREATE USER user3 TEMPSPACECAP '1G';
可以将不同属性组合到一个命令中:例如,若要为 user3
限制 MEMORYCAP
和 RUNTIMECAP
,可将这两个属性包含在一个 ALTER USER 语句中:
=> ALTER USER user3 MEMORYCAP '750M' RUNTIMECAP '10 minutes';
ALTER USER
=> \x
Expanded display is on.
=> SELECT * FROM USERS;
-[ RECORD 1 ]-----+------------------
user_id | 45035996273704962
user_name | release
is_super_user | t
resource_pool | general
memory_cap_kb | unlimited
temp_space_cap_kb | unlimited
run_time_cap | unlimited
-[ RECORD 2 ]-----+------------------
user_id | 45035996273964824
user_name | user1
is_super_user | f
resource_pool | my_pool
memory_cap_kb | unlimited
temp_space_cap_kb | unlimited
run_time_cap | unlimited
-[ RECORD 3 ]-----+------------------
user_id | 45035996273964832
user_name | user2
is_super_user | f
resource_pool | general
memory_cap_kb | 204800
temp_space_cap_kb | unlimited
run_time_cap | 00:05
-[ RECORD 4 ]-----+------------------
user_id | 45035996273970230
user_name | user3
is_super_user | f
resource_pool | general
memory_cap_kb | 768000
temp_space_cap_kb | 1048576
run_time_cap | 00:10
另请参阅
2.4 - 查询预算
在执行查询之前,Vertica 会设计一个查询计划,并将其发送到将参与执行查询的每个节点。资源管理器评估每个节点上的计划,并估算节点执行其查询部分需要的内存量和并发程度。这是查询预算,Vertica 将其存储在系统表
V_MONITOR.RESOURCE_POOL_STATUS
的 query_budget_kb
列中。
查询预算基于查询将执行的资源池的几个参数设置:
-
MEMORYSIZE
-
MAXMEMORYSIZE
-
PLANNEDCONCURRENCY
您可以使用
ALTER RESOURCE POOL
修改 GENERAL 资源池的 MAXMEMORYSIZE
和 PLANNEDCONCURRENCY
。此资源池通常执行未分配给用户定义资源池的查询。您可以在使用
CREATE RESOURCE POOL
或者稍后使用
ALTER RESOURCE POOL
创建任何由用户定义的资源池时设置所有三个参数。
计算 GENERAL 池查询预算
Vertica 使用以下公式计算 GENERAL 池中的查询预算:
queryBudget = queuingThresholdPool / PLANNEDCONCURRENCY
注意
Vertica 将 GENERAL 池的排队阈值计算为其 MAXMEMORYSIZE
设置的 95%。
计算用户定义的资源池的查询预算
对于用户定义的资源池,Vertica 使用以下算法:
-
如果 MEMORYSIZE
设置为 0 并且 MAXMEMORYSIZE
未设置:
queryBudget = queuingThresholdGeneralPool / PLANNEDCONCURRENCY
-
如果 MEMORYSIZE
设置为 0 并且 MAXMEMORYSIZE
设置为非默认值:
query-budget = queuingThreshold / PLANNEDCONCURRENCY
注意
Vertica 将用户定义的池的排队阈值计算为其 MAXMEMORYSIZE
设置的 95%。
-
如果 MEMORYSIZE
设置为非默认值:
queryBudget = MEMORYSIZE / PLANNEDCONCURRENCY
通过仔细调整资源池的 MEMORYSIZE
和 PLANNEDCONCURRENCY
参数,可以控制能够为查询预算多少内存。
当心
查询预算通常不需要调整,但是,如果由于其他目的需要内存而减少 MAXMEMORYSIZE
,请注意这样做也会减少查询预算。减少查询预算会对查询性能产生负面影响,尤其是在查询很复杂的情况下。
为了保持资源池的原始查询预算,一定要一起减小参数 MAXMEMORYSIZE
和 PLANNEDCONCURRENCY
。
另请参阅
您是否需要在预算范围内查询? 在 Vertica 用户社区中。
3 - 在查询运行时管理资源
资源管理器估算运行查询所需的资源,然后确定查询的优先级。您可以通过多种方式控制资源管理器如何确定查询执行的优先级:
3.1 - 为资源池设置运行时优先级
对于每个资源池,可以管理分配给正在运行的查询的资源。您可以为每个资源池分配 HIGH、MEDIUM 或 LOW 运行时优先级。这些设置确定了运行查询时资源池中为其分配的运行时资源量(如 CPU 数量和 I/O 带宽)。优先级为 HIGH 的资源池中的查询获得的运行时资源比运行时优先级为 MEDIUM 或 LOW 的资源池中的查询要多。
确定资源池中查询的优先级
虽然运行时优先级有助于管理资源池的资源,但有些情况下,您可能希望资源池内具有一定灵活性。例如,您可能希望确保每个短小查询都以高优先级运行,同时确保所有其他查询以中等或低优先级运行。
资源管理器可以为资源池设置运行时优先级阈值,从而提供这种灵活性。使用此阈值,您可以指定一个时间限制(以秒为单位),查询必须在该时间限制内完成,否则会被分配资源池的运行时优先级。所有查询在开始运行时优先级均为 HIGH;当查询的持续时间超过运行时优先级阈值中指定的时间限制后,将为其分配资源池的运行时优先级。
设置运行时优先级和运行时优先级阈值
通过使用
CREATE RESOURCE POOL
或
ALTER RESOURCE POOL
设置两个资源池参数,指定运行时优先级和运行时优先级阈值:
-
RUNTIMEPRIORITY
-
RUNTIMEPRIORITYTHRESHOLD
3.2 - 更改正在运行的查询的运行时优先级
CHANGE_CURRENT_STATEMENT_RUNTIME_PRIORITY
允许您更改查询的运行时优先级。您可以更改已在执行的查询的运行时优先级。
此函数具有两个实参:
限制
超级用户可以将任何查询的运行时优先级更改为任何优先级。对于其他用户,以下限制适用:
过程
更改查询的运行时优先级涉及到一个两步过程:
-
通过查询系统表
SESSIONS
来获取查询的事务 ID。例如,以下语句返回有关所有正在运行的查询的信息:
=> SELECT transaction_id, runtime_priority, transaction_description from SESSIONS;
-
运行 `CHANGE_CURRENT_STATEMENT_RUNTIME_PRIORITY```,指定查询的事务 ID 和所需的运行时优先级:
=> SELECT CHANGE_CURRENT_STATEMENT_RUNTIME_PRIORITY(45035996273705748, 'low')
3.3 - 手动将查询移至不同的资源池
数据库管理员可以使用 MOVE_STATEMENT_TO_RESOURCE_POOL 元函数将查询移至另一个执行当中的资源池。
如果某一个查询正在使用大量资源,您可能希望利用这一功能,以防止执行较小的查询。
当查询移至另一个资源池时会发生什么情况
将查询从一个资源池移至另一个资源池时,如果目标池具有足以容纳传入查询的资源,该查询便会继续执行。如果在目标池中无法至少在一个节点上分配足够的资源,则 Vertica 会取消该查询并尝试重新计划查询。如果 Vertica 无法重新计划查询,则该查询将被无限期地取消。
当您成功将查询移至目标资源池后,该查询的资源将由目标池提供,而在第一个池中占用的资源将被释放。
如果将查询移至具有 PRIORITY HOLD 的资源池,Vertica 会取消该查询并将其排入目标池的队列中。在您更改 PRIORITY 或将查询移至另一个没有 PRIORITY HOLD 的资源池之前,该取消状态将一直有效。如果要存储长时间运行的查询以便日后使用,可使用此选项。
若要确定目标池能否容纳要移动的查询,可查看 RESOURCE_ACQUISITIONS 或 RESOURCE_POOL_STATUS 系统表。请注意,当您查询系统表时以及调用 MOVE_STATEMENT_TO_RESOURCE_POOL 元函数时,这些表可能发生变化。
当查询从一个资源池成功移至另一个执行当中的资源池时,该查询会一直执行,直至达到现有 RUNTIMECAP 和新 RUNTIMECAP
之间的较大者为止。例如,如果初始池的 RUNTIMECAP
大于目标池,则查询可在达到初始 RUNTIMECAP
之前一直执行。
当查询从一个资源池成功移至另一个执行当中的资源池时,CPU 关联性将改变。
使用 MOVE_STATEMENT_TO_RESOURCE_POOL 函数
若要手动将查询从其当前资源池移至另一资源池,请使用 MOVE_STATEMENT_TO_RESOURCE_POOL 元函数。如下所示提供会话 ID、事务 ID、语句 ID 和目标资源池名称:
=> SELECT MOVE_STATEMENT_TO_RESOURCE_POOL ('v_vmart_node0001.example.-31427:0x82fbm', 45035996273711993, 1, 'my_target_pool');
另请参阅:
4 - 还原资源管理器默认设置
系统表 RESOURCE_POOL_DEFAULTS 存储所有内置和用户定义的资源池的所有参数的默认值。
如果更改了任何资源池中任何参数的值并想要将其还原为默认值,只需更改表并将参数设置为 DEFAULT 即可。例如,以下语句可将资源池 sysquery 的 RUNTIMEPRIORITY 重新设置为默认值:
=> ALTER RESOURCE POOL sysquery RUNTIMEPRIORITY DEFAULT;
5 - 工作负载资源管理最佳实践
本部分提供如何针对各种常见情景设置和优化资源池的一般指导原则和最佳实践。
注意
资源池参数的具体设置主要取决于查询组合、数据大小、硬件配置和并发要求。Vertica 建议您亲自实验确定系统的最佳配置。
5.1 - 可扩展性和并发优化的基本原则
Vertica 数据库在一组商用硬件上运行。对数据库运行的所有加载和查询均需占用 CPU、内存、磁盘 I/O 带宽、文件句柄等系统资源。给定查询的性能(运行时间)取决于为其分配的资源量。
在系统中同时运行多个查询时,这些查询会共享资源;因此,每个查询的运行时间可能比其单独运行时要长。在可扩展的高效系统中,如果某个查询占用计算机的所有资源且运行时间为 X,则运行两个此类查询可能会使每个查询的运行时间增加一倍。如果查询的运行时间超过 2X,则说明系统并非可线性扩展;如果查询的运行时间小于 2X,则说明单个查询在资源使用方面存在浪费情况。请注意,只要查询获得其运行所需的最少资源且受 CPU 周期限制,就会发生上述情况。相反,如果因系统瓶颈导致查询无法获得运行所需的足够特定资源,则说明系统已达到极限。在这种情况下,为了提高并发性,必须通过另外添加此资源来扩展系统。
实际上,Vertica 应在达到系统资源限制之前,通过提高并发性而在运行时间方面实现近乎线性的可扩展性。如果达到足够的并发性且未引发任何瓶颈,便可认为系统大小非常适合工作负载。
注意
通常,分段表的 Vertica 查询将在群集的多个(可能是全部)节点上运行。添加更多节点通常会近乎线性地改善查询的运行时间。
5.2 - 为查询设置运行时限制
可以为允许查询运行的时间长度设置限制。您可以将此限制设置为三个级别,按优先级降序排列:
-
要将用户分配到的资源池。
-
具有 RUNTIMECAP
(由
CREATE USER
/ALTER USER 配置)的用户配置文件
ALTER USER
-
会话查询(由 SET SESSION RUNTIMECAP 设置)
SET SESSION RUNTIMECAP
在所有情况下,您都可以使用不超过一年的 interval 值设置运行时限制。在多个级别设置运行时限制时,Vertica 始终使用最短的值。如果为非超级用户设置了运行时限制,则该用户无法将任何会话设置为更长的运行时限制。超级用户可以将其他用户和他们自己的会话的运行时限制设置为不超过一年(包含)的任意值。
示例
user1
被分配至 ad_hoc_queries
资源库:
=> CREATE USER user1 RESOURCE POOL ad_hoc_queries;
user1
的 RUNTIMECAP
设置为 1 小时。
=> ALTER USER user1 RUNTIMECAP '60 minutes';
ad_hoc_queries
资源池的 RUNTIMECAP
设置为 30 分钟。
=> ALTER RESOURCE POOL ad_hoc_queries RUNTIMECAP '30 minutes';
在本例中,如果 user1
的查询超过 30 分钟,Vertica 会终止这些查询。尽管 user1
的运行时间限制设置为一小时,但运行查询的池(具有 30 分钟的运行时间限制)具有优先权。
注意
如果使用 CASCADE TO
函数为 ad_hoc_queries
池指定了一个辅助池,则当查询超过 ad_hoc_queries
池上的 RUNTIMECAP
时,就会在该辅助池上执行查询。
另请参阅
5.3 - 处理会话套接字阻止
针对给定查询等待客户端输入或输出时,会话套接字可能会被阻止。会话套接字通常因多种原因而被阻止 — 例如,当 Vertica 执行引擎将数据传输到客户端时,或
COPY LOCAL
操作等待从客户端加载数据时。
在极少数情况下,会话套接字可能会无限期地保持被阻止状态。例如,客户端上的查询超时,这会尝试强制取消查询或者依赖会话 RUNTIMECAP
设置来终止查询。在任何一种情况下,如果查询在等待消息或数据时结束,则套接字可能会保持阻止状态,会话将挂起,直到它被强制关闭。
配置宽限期
您可以为系统配置一个宽限期,在此期间滞后的客户端或服务器可以跟上并传递待定的响应。如果套接字保持被阻止状态的连续期间超过宽限期设置,服务器将关闭套接字并引发致命错误。随后,会话终止。如果没有设置宽限期,查询会使套接字无限期地保持被阻止状态。
您应该将会话宽限期设置为高到足以覆盖可接受的延迟范围并避免会话过早关闭 — 例如,为了对服务器进行响应而设置正常的客户端延迟。超大负载操作可能会要求您根据需要调整会话宽限期。
您可以将宽限期设置为四个级别,按优先级降序排列:
-
会话(最高)
-
用户
-
节点
-
数据库
为数据库和节点设置宽限期
在数据库和节点级别,可以通过 BlockedSocketGracePeriod
配置参数将宽限期设置为不超过 20 天的任意间隔:
-
ALTER DATABASE db-name SET BlockedSocketGracePeriod = 'interval';
-
ALTER NODE node-name SET BlockedSocketGracePeriod = 'interval';
默认情况下,这两个级别的宽限期都设置为空字符串,允许无限期阻止。
为用户和会话设置宽限期
您可以为单个用户和给定会话设置宽限期,如下所示:
用户可以将会话设置为等于或小于为该用户设置的宽限期的任意间隔。超级用户可以将其他用户和他们自己的会话的宽限期设置为不超过 20 天(包含)的任意值。
示例
超级用户 dbadmin
将数据库宽限期设置为 6 小时。此限制仅适用于非超级用户。 dbadmin
可以将自己的会话宽限期设置为不超过 20 天的任意值 — 在本例中为 10 小时:
=> ALTER DATABASE VMart SET BlockedSocketGracePeriod = '6 hours';
ALTER DATABASE
=> SHOW CURRENT BlockedSocketGracePeriod;
level | name | setting
----------+--------------------------+---------
DATABASE | BlockedSocketGracePeriod | 6 hours
(1 row)
=> SET SESSION GRACEPERIOD '10 hours';
SET
=> SHOW GRACEPERIOD;
name | setting
-------------+---------
graceperiod | 10:00
(1 row)
dbadmin
创建未设置宽限期的用户 user777
。因此,user777
的有效宽限期派生自数据库的 BlockedSocketGracePeriod
设置,即 6 小时。user777
将会话宽限期设置为大于 6 小时的任何尝试都会返回错误:
=> CREATE USER user777;
=> \c - user777
You are now connected as user "user777".
=> SHOW GRACEPERIOD;
name | setting
-------------+---------
graceperiod | 06:00
(1 row)
=> SET SESSION GRACEPERIOD '7 hours';
ERROR 8175: The new period 07:00 would exceed the database limit of 06:00
dbadmin
为 user777
设置 5 分钟的宽限期。现在,user777
可以将会话宽限期设置为等于或小于用户级别设置的任何值:
=> \c
You are now connected as user "dbadmin".
=> ALTER USER user777 GRACEPERIOD '5 minutes';
ALTER USER
=> \c - user777
You are now connected as user "user777".
=> SET SESSION GRACEPERIOD '6 minutes';
ERROR 8175: The new period 00:06 would exceed the user limit of 00:05
=> SET SESSION GRACEPERIOD '4 minutes';
SET
5.4 - 将用户定义的池和用户配置文件用于工作负载管理
本部分中的场景介绍常见的工作负载管理问题,并提供带示例的解决方案。
5.4.1 - 周期性批量加载
场景
您每天晚上都执行批量加载,偶尔(很少)在白天执行批量加载。当加载正在运行时,减少查询的资源使用量是可接受的,但在其他所有时间,您希望所有资源都可用于查询。
解决方案
为加载创建一个单独的资源池,使其优先级高于内置 GENERAL 池上的预配置设置。
在此场景中,在从 GENERAL 池中借用内存时,每天晚上的加载具有优先权。在没有运行加载时,所有内存将可自动用于查询。
示例
创建一个优先级高于 GENERAL 池的资源池:
-
创建 PRIORITY 设置为 10 的资源池 load_pool
:
=> CREATE RESOURCE POOL load_pool PRIORITY 10;
-
修改用户 load_user
以使用新的资源池:
=> ALTER USER load_user RESOURCE POOL load_pool;
5.4.2 - CEO 查询
场景
CEO 在每周一的上午 9 点运行报告,您想要确保该报告始终运行。
解决方案
若要确保某个查询或某类查询始终获得资源,可以为其创建专用池,如下所示:
-
使用 PROFILE 命令,运行 CEO 每周运行的查询,确定应当分配的内存量:
=> 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: Statement is being profiled.HINT: select * from v_monitor.execution_engine_profiles where
transaction_id=45035996273751349 and statement_id=6;
NOTICE: Initiator memory estimate for query: [on pool general: 1723648 KB,
minimum: 355920 KB]
-
创建具有上述提示所报告的 MEMORYSIZE 的资源池,确保至少为 CEO 查询保留此内存大小:
=> CREATE RESOURCE POOL ceo_pool MEMORYSIZE '1800M' PRIORITY 10;
CREATE RESOURCE POOL
=> \x
Expanded display is on.
=> SELECT * FROM resource_pools WHERE name = 'ceo_pool';
-[ RECORD 1 ]-------+-------------
name | ceo_pool
is_internal | f
memorysize | 1800M
maxmemorysize |
priority | 10
queuetimeout | 300
plannedconcurrency | 4
maxconcurrency |
singleinitiator | f
-
假设 CEO 报告用户已存在,使用 ALTER USER 语句将此用户与上述资源池相关联。
=> ALTER USER ceo_user RESOURCE POOL ceo_pool;
-
发出以下命令确认 ceo_user 与 ceo_pool 相关联:
=> SELECT * FROM users WHERE user_name ='ceo_user';
-[ RECORD 1 ]-+------------------
user_id | 45035996273713548
user_name | ceo_user
is_super_user | f
resource_pool | ceo_pool
memory_cap_kb | unlimited
如果 CEO 查询内存使用量过大,可以让资源管理器将其降至符合特定预算的水平。请参阅查询预算。
5.4.3 - 防止失控查询
场景
Joe 是一位经常在中午运行大型报告的业务分析员,这些报告占用了整个机器的资源。您想要防止 Joe 使用超过 100MB 的内存,并且想要将 Joe 的查询运行时间限制在 2 小时以内。
解决方案
用户配置文件 为此场景提供了一个解决方案。若要限制 Joe 一次可以使用的内存量,使用 ALTER USER 命令将 Joe 的 MEMORYCAP 设置为 100MB。若要限制 Joe 的查询可以运行的时间长度,使用相同的命令将 RUNTIMECAP 设置为 2 小时。如果 Joe 运行的查询超过其最高限值,Vertica 会拒绝该查询。
如果您有一批需要限制查询的用户,也可以为他们创建一个资源池并为该资源池设置 RUNTIMECAP。将这些用户移至此资源池后,Vertica 会将这些用户的所有查询限制为您为该资源池指定的 RUNTIMECAP。
示例
=> ALTER USER analyst_user MEMORYCAP '100M' RUNTIMECAP '2 hours';
如果 Joe 尝试运行超过 100MB 的查询,系统会返回一个错误,说明请求超出内存会话限制,如以下示例所示:
\i vmart_query_04.sqlvsql:vmart_query_04.sql:12: ERROR: Insufficient resources to initiate plan
on pool general [Request exceeds memory session limit: 137669KB > 102400KB]
只有系统数据库管理员 (dbadmin) 可以提高 MEMORYCAP 设置。用户不能提高自己的 MEMORYCAP 设置,如果他们尝试编辑其 MEMORYCAP 或 RUNTIMECAP 设置,则将看到类似于以下内容的错误:
ALTER USER analyst_user MEMORYCAP '135M';
ROLLBACK: permission denied
5.4.4 - 限制临时查询应用程序的资源使用率
场景
您最近将数据仓库提供给一大群用户,而他们并不熟悉 SQL。一些用户对大量的行运行报告,耗尽了系统资源。您想要制约这些用户的系统使用量。
解决方案
-
为 MAXMEMORYSIZE 等于 MEMORYSIZE 的临时应用程序创建资源池。这可以防止该资源池中的查询从 GENERAL 池中借用资源。另外,设置 RUNTIMECAP 以限制临时查询的最大持续时间。
=> CREATE RESOURCE POOL adhoc_pool
MEMORYSIZE '200M'
MAXMEMORYSIZE '200M'
RUNTIMECAP '20 seconds'
PRIORITY 0
QUEUETIMEOUT 300
PLANNEDCONCURRENCY 4;
=> SELECT pool_name, memory_size_kb, queueing_threshold_kb
FROM V_MONITOR.RESOURCE_POOL_STATUS WHERE pool_name='adhoc_pool';
pool_name | memory_size_kb | queueing_threshold_kb
------------+----------------+-----------------------
adhoc_pool | 204800 | 153600
(1 row)
-
将此资源池与应用程序用于连接到数据库的数据库用户相关联。
=> ALTER USER app1_user RESOURCE POOL adhoc_pool;
提示
其他解决方案包括像在
防止失控查询中一样限制单个用户的内存使用量。
5.4.5 - 为应用程序设置硬性并发限制
场景
为了便于开票,分析员 Jane 希望对此应用程序的并发性实施硬性限制。如何做到这一点?
解决方案
最简单的解决方案是为该应用程序的用户创建一个单独的资源池,并将其 MAXCONCURRENCY 设置为所需的并发级别。任何超过 MAXCONCURRENCY 的查询都会进入队列。
提示
Vertica 建议将 PLANNEDCONCURRENCY 保留为默认级别,以便查询获得最大的资源量。从而使整个系统以最高效率运行。
示例
在本示例中,存在四位与开票池相关联的开票用户。目的是对资源池设置硬性限制,使一次最多可以执行三个并发查询。所有其他查询将排队并在资源释放后完成。
=> CREATE RESOURCE POOL billing_pool MAXCONCURRENCY 3 QUEUETIMEOUT 2;
=> CREATE USER bill1_user RESOURCE POOL billing_pool;
=> CREATE USER bill2_user RESOURCE POOL billing_pool;
=> CREATE USER bill3_user RESOURCE POOL billing_pool;
=> CREATE USER bill4_user RESOURCE POOL billing_pool;
=> \x
Expanded display is on.
=> select maxconcurrency,queuetimeout from resource_pools where name = 'billing_pool';
maxconcurrency | queuetimeout
----------------+--------------
3 | 2
(1 row)
> SELECT reason, resource_type, rejection_count FROM RESOURCE_REJECTIONS
WHERE pool_name = 'billing_pool' AND node_name ilike '%node0001';
reason | resource_type | rejection_count
---------------------------------------+---------------+-----------------
Timedout waiting for resource request | Queries | 16
(1 row)
如果查询正在运行并且没有在规定时间内完成(默认超时设置为 5 分钟),请求的下一查询将收到一条类似于以下内容的错误:
ERROR: Insufficient resources to initiate plan on pool billing_pool [Timedout waiting for resource request: Request exceeds limits:
Queries Exceeded: Requested = 1, Free = 0 (Limit = 3, Used = 3)]
下表显示在开票池中存在三个活动查询。
=> SELECT pool_name, thread_count, open_file_handle_count, memory_inuse_kb FROM RESOURCE_ACQUISITIONS
WHERE pool_name = 'billing_pool';
pool_name | thread_count | open_file_handle_count | memory_inuse_kb
--------------+--------------+------------------------+-----------------
billing_pool | 4 | 5 | 132870
billing_pool | 4 | 5 | 132870
billing_pool | 4 | 5 | 132870
(3 rows)
5.4.6 - 处理混合工作负载:批处理与交互式处理
场景
您具有一个带交互门户的 Web 应用程序。有时,当 IT 人员运行批处理报告时,Web 页面需要很长时间才能刷新,引起用户抱怨,因此您想要为网站用户提供更好的体验。
解决方案
可以应用先前场景中学习到的原则解决此问题。基本思想是将查询分离成与不同资源池相关联的两组。先决条件是存在两个不同的数据库用户,他们发出不同类型的查询。如果情况与此不同,请将此视为应用程序设计的最佳方法。
方法 1
: 创建专门用于 Web 页面刷新查询的资源池,同时:
这可确保网站查询始终运行并且从不排列在大型批处理作业之后。让处理作业不在 GENERAL 池上运行。
例如,以下池是根据从 Web 运行的查询所需的平均资源量以及并发查询的预期数量来确定的。另外,它给予 Web 查询的优先级要高于任何正在运行的批处理作业,并假定将查询调整为每个查询占用 250M:
=> CREATE RESOURCE POOL web_pool
MEMORYSIZE '250M'
MAXMEMORYSIZE NONE
PRIORITY 10
MAXCONCURRENCY 5
PLANNEDCONCURRENCY 1;
方法 2
创建具有固定内存大小的资源池。这将限制批处理报告可用的内存量,使内存始终留作其他用途。有关详细信息,请参阅限制临时查询应用程序的资源使用率。
例如:
=> CREATE RESOURCE POOL batch_pool
MEMORYSIZE '4G'
MAXMEMORYSIZE '4G'
MAXCONCURRENCY 10;
如果您有三个或更多不同类别的工作负载,此原则同样适用。
5.4.7 - 对不同用户发出的查询设置优先级
场景
您希望一个部门的用户查询比另一个部门的查询具有更高的优先级。
解决方案
解决方案类似于混合工作负载场景。在此场景中,您没有限制资源使用量;您设置了不同的优先级。若要这样做,可创建两个不同的池,每个池都具有 MEMORYSIZE=0% 以及一个不同的 PRIORITY 参数。这两个池都从 GENERAL 池中借用资源,但在争夺资源时,优先级决定了每个池的请求获得批准的顺序。例如:
=> CREATE RESOURCE POOL dept1_pool PRIORITY 5;
=> CREATE RESOURCE POOL dept2_pool PRIORITY 8;
如果您发现此解决方案不足以满足需要,或者一个部门的查询一直使另一个部门的用户难以执行查询,则可以通过设置 MEMORYSIZE 为每个池添加预留,这样会保证每个部门都可以使用一些内存。
例如,两个资源都使用 GENERAL 池获取内存,所以您可以通过使用 ALTER RESOURCE POOL 更改每个池的 MEMORYSIZE,为每个资源池分配一些内存。
=> ALTER RESOURCE POOL dept1_pool MEMORYSIZE '100M';
=> ALTER RESOURCE POOL dept2_pool MEMORYSIZE '150M';
5.4.8 - 持续加载和查询
场景
您希望应用程序运行连续加载流,但许多应用程序运行的是并行查询流。您希望确保性能是可预计的。
解决方案
此场景的解决方案取决于您的查询组合。在所有情况下,以下方法均适用:
-
确定所需的连续加载流数量。如果单个流没有提供足够的吐吞量,则这可能与所需加载速率有关,或者与要加载的数据源数量有更直接的关系。为加载创建一个专用资源池,并将其与要执行加载的数据库用户相关联。有关详细信息,请参阅CREATE RESOURCE POOL。
通常,加载池的并行设置应少于每个节点的内核数。除非源进程较慢,否则会更高效地为每个加载贡献更多内存,并且具有更多的加载队列。如果预计有队列,请调整加载池的 QUEUETIMEOUT 设置。
-
运行加载工作负载一会儿,观察加载性能是否符合预期。如果 Tuple Mover 没有经过充分优化以涵盖加载行为,请参阅管理 Tuple Mover。
-
如果系统中有多种类型的查询(例如,对于某些查询,必须为交互用户快速提供答复,而其他查询属于批量报告处理的一部分),请遵循处理混合工作负载:批处理与交互式处理中的准则。
-
运行查询并观察性能。如果某些类别的查询没有按预期执行,那么您可能需要按照限制临时查询应用程序的资源使用率中所述调整 GENERAL 池,或者为这些查询创建更多专用资源池。有关详细信息,请参阅CEO 查询和处理混合工作负载:批处理与交互式处理。
有关在混合工作负载环境中获得可预测结果的信息,请参阅关于管理工作负载和CREATE RESOURCE POOL的部分。
5.4.9 - 确定运行时短查询的优先级
场景
您最近为没有 SQL 方面经验并且经常运行临时报表的用户创建了一个资源池。到目前为止,您通过创建 MEMORYSIZE 和 MAXMEMORYSIZE 相等的资源池来管理资源分配。这可以防止该资源池中的查询从 GENERAL 池中借用资源。现在,您希望在运行时管理资源并优先考虑短查询,使其不会因为运行时资源有限而排队。
解决方案
例如:
=> ALTER RESOURCE POOL ad_hoc_pool RUNTIMEPRIORITY medium RUNTIMEPRIORITYTHRESHOLD 5;
由于 RUNTIMEPRIORITYTHRESHOLD
设置为 5,因此资源池 ad_hoc_pool
中在 5 秒内完成的所有查询都以高优先级运行。超过 5 秒的查询将下降到分配给该资源池的 RUNTIMEPRIORITY
MEDIUM。
5.4.10 - 删除运行时较长查询的优先级
场景
您希望资源池中的大部分查询以 HIGH 运行时优先级运行,但能够将长于 1 小时的作业调整为更低的优先级。
解决方案
将资源池的 RUNTIMEPRIORITY 设置为 LOW,将 RUNTIMEPRIORITYTHRESHOLD 设置为一个仅截断最长作业的数值。
示例
要确保向所有持续时间长于 3600 秒(1 小时)的查询分配低运行时优先级,请按如下所示修改资源池:
=> ALTER RESOURCE POOL ad_hoc_pool RUNTIMEPRIORITY low RUNTIMEPRIORITYTHRESHOLD 3600;
5.5 - 调整内置池
本部分中的场景介绍如何优化内置池。
5.5.1 - 将 Vertica 限制为仅占用 60% 的内存
场景
您有一个嵌入 Vertica 的单节点应用程序,部分 RAM 需要专用于该应用程序进程。在此场景中,您想要将 Vertica 限制为仅使用可用 RAM 的 60%。
解决方案
将 GENERAL 池的 MAXMEMORYSIZE 参数设置为所需的内存大小。有关资源限制的讨论,请参阅资源池架构。
5.5.2 - 为恢复进行调整
场景
您有一个大型数据库,其中包含一个具有两个投影以及默认设置的大型表,恢复操作所需的时间过长。您想要为恢复操作提供更多内存以提高速度。
解决方案
将 RECOVERY 池的 PLANNEDCONCURRENCY 和 MAXCONCURRENCY 设为 1,使恢复操作可以从 GENERAL 池中获得尽可能多的内存并且每次仅运行一个线程。
当心
此设置会降低您系统中其他查询的速度。
5.5.3 - 调整刷新
场景
当
刷新操作正在运行时,系统性能会受到影响,用户查询会被拒绝。您想要降低刷新作业的内存用量。
解决方案
将刷新池的 MEMORYSIZE 设置为固定值。然后,资源管理器调整刷新查询,使其仅使用此数量的内存。
重要
请记得在刷新操作完成后,将刷新池的 MEMORYSIZE 重置为 0%,以便可将内存用于其他操作。
5.5.4 - 调整 Tuple Mover 池设置
场景 1
在重负载操作期间,您偶尔会注意到 ROS 容器的数量激增。您希望 Tuple Mover 更主动地执行合并以合并 ROS 容器,并避免 ROS 推回。
解决方案
使用 ALTER RESOURCE POOL 增加 TM 资源池 中 MAXCONCURRENCY 的设置。此设置确定有多少线程可用于合并。默认情况下,此参数设置为 7。Vertica 将一半线程分配给处于活动状态的分区,其余一半根据需要分配给处于活动状态和非活动状态的分区。如果 MAXCONCURRENCY 设置为奇整数,Vertica 会向上舍入以支持处于活动状态的分区。
例如,如果您将 MAXCONCURRENCY 增加到 9,则 Vertica 会将五个线程专门分配给处于活动状态的分区,并将剩余的四个线程分配给处于活动状态和非活动状态的分区。
场景 2
您有一个专用于时间敏感型分析查询的辅助子群集。您希望限制此子群集上可能干扰其处理查询的任何其他工作负载,并同时释放内存以执行查询。
默认情况下,每个子群集都有一个用于 Tuple Mover 操作的内置 TM 资源池,该资源池可用于执行 Tuple Mover 合并操作。TM 池消耗可用于查询的内存。此外,合并操作可能会给子群集的处理稍微增加一点开销。您希望重新分配由 TM 池消耗的内存,并阻止子群集运行合并操作。
解决方案
使用 ALTER RESOURCE POOL 覆盖辅助子群集的全局 TM 资源池,并将其 MAXMEMORYSIZE 和 MEMORYSIZE 都设置为 0。这允许您使用由全局 TM 池消耗的内存来运行分析查询,并防止为子群集分配要执行的 TM 合并操作。
5.5.5 - 为机器学习进行调整
场景
大量机器学习功能正在运行,您希望为它们提供更多内存以提高性能。
解决方案
Vertica 在 BLOBDATA 资源池中执行机器学习功能。为了提高机器学习功能的性能并避免将查询溢出到磁盘,请使用 ALTER RESOURCE POOL 增加池的 MAXMEMORYSIZE 设置。
有关调整查询预算的更多信息,请参阅查询预算。
另请参阅
5.6 - 缩短查询运行时间
查询的运行时间取决于查询的复杂性、计划中的运算符数、数据量和投影设计。I/O 或 CPU 瓶颈可能导致查询运行速度低于预期。您通常可以使用更好的投影设计来纠正 CPU 使用率过高的问题。高 I/O 通常可以追溯到由溢出到磁盘的联接和排序引起的争用。但是,没有单一的解决方案可以解决所有导致高 CPU 或 I/O 使用率的查询。您必须单独分析和优化每个查询。
可通过两种方式评估运行缓慢的查询:
检查查询计划会揭露以下一个或多个问题:
分析
Vertica 提供的分析机制可帮助您评估不同级别的数据库性能。例如,可为单个语句、单个会话或所有节点上的所有会话收集分析数据。有关详细信息,请参阅对数据库性能执行分析。
5.7 - 管理 Eon 模式数据库中的工作负载资源
您主要使用子群集来控制 Eon 模式数据库中的工作负载。例如,您可以为特定用例(如 ETL 或查询工作负载)创建子群集,也可以为不同的用户组创建子群集以隔离工作负载。在每个子群集中,您可以创建单独的资源池以根据工作负载优化资源分配。有关 Vertica 如何使用子群集的详细信息,请参阅管理子群集。
全局资源池和特定于子群集的资源池
您可以定义影响数据库中所有节点的全局资源池分配。您还可以在子群集级别创建资源池分配。如果您同时创建这两种分配,则子群集级别的设置会覆盖全局设置。
注意
GENERAL 池需要至少 25% 的可用内存才能正常运行。如果您尝试将用户定义的资源池的 MEMORYSIZE 设置为 75% 以上,Vertica 会返回错误。
您可以使用此功能移除子群集不需要的全局资源池。此外,您可以使用适合大多数子群集的设置创建资源池,然后根据需要为特定子群集定制设置。
优化 ETL 和查询子群集
覆盖子群集级别的资源池设置将允许您隔离内置和用户定义的资源池并按工作负载优化它们。您通常为不同的子群集分配特定的角色:
-
专用于 ETL 工作负载和 DDL 语句(这些语句用来更改数据库)的子群集。
-
专用于运行长时间运行的深入分析查询的子群集。为了获得最佳性能,需要为这些查询分配更多的资源。
-
用于运行许多短时间运行的“仪表板”查询(您希望快速完成且并行运行这些查询)的子群集。
定义由每个子群集执行的查询类型后,您可以创建一个特定于子群集的资源池,并对该资源池进行优化以提高此工作负载的效率。
以下方案按工作负载优化 3 个子群集:
有关资源池调整的其他方案,请参阅工作负载资源管理最佳实践。
配置 ETL 子群集以提高 TM 性能
Vertica 选择在存储库中的合并操作中涉及 ROS 容器最多的子群集来执行合并(请参阅 Eon 模式数据库中的 Tuple Mover)。通常,执行 ETL 的子群集将是执行合并的最佳候选者,因为该子群集加载的数据参与合并。您可以选择通过更改 TM 池的 MAXCONCURRENCY 设置来提高子群集上合并操作的性能,以增加可用于合并操作的线程数。您无法在子群集级别更改此设置,因此您必须在全局设置它:
=> ALTER RESOURCE POOL TM MAXCONCURRENCY 10;
有关 Tuple Mover 资源的更多信息,请参阅调整 Tuple Mover 池设置。
配置仪表板查询子群集
默认情况下,辅助子群集将内存分配给 Tuple Mover 资源池。此池设置允许 Vertica 将合并操作分配给辅助子群集,这会增加少量开销。如果您将辅助子群集主要用于查询,则最佳做法是回收 TM 池使用的内存并防止将合并操作分配给辅助子群集。
要优化仪表板查询辅助子群集,请设置其 TM 池的 MEMORYSIZE 和 MAXMEMORYSIZE 设置为 0:
=> ALTER RESOURCE POOL TM FOR SUBCLUSTER dashboard MEMORYSIZE '0%'
MAXMEMORYSIZE '0%';
重要
请勿在
主子群集上将 TM 池的 MEMORYSIZE 和 MAXMEMORYSIZE 设置为 0。它们必须始终能够运行 Tuple Mover。
若要确认覆盖,请查询 SUBCLUSTER_RESOURCE_POOL_OVERRIDES 表:
=> SELECT pool_oid, name, subcluster_name, memorysize, maxmemorysize
FROM SUBCLUSTER_RESOURCE_POOL_OVERRIDES;
pool_oid | name | subcluster_name | memorysize | maxmemorysize
-------------------+------+-----------------+------------+---------------
45035996273705046 | tm | dashboard | 0% | 0%
(1 row)
若要针对网页上短时间运行的查询优化仪表板子群集,请创建一个名为 dash_pool 的子群集级资源池,该池使用子群集 70% 的内存。此外,增加 PLANNEDCONCURRENCY 以使用机器的所有逻辑核心,并将 EXECUTIONPARALLELISM 限制为不超过机器可用核心的一半:
=> CREATE RESOURCE POOL dash_pool FOR SUBCLUSTER dashboard
MEMORYSIZE '70%'
PLANNEDCONCURRENCY 16
EXECUTIONPARALLELISM 8;
配置分析查询子群集
若要针对网页上长时间运行的查询优化分析子群集,请创建一个名为 analytics_pool 的子群集级资源池,该池使用子群集 60% 的内存。在这种情况下,您无法为该池分配更多内存,因为该子群集中的节点仍将内存分配给其 TM 池。此外,将 EXECUTIONPARALLELISM 设置为 AUTO 以使用节点上的所有可用核心来处理查询,并将 PLANNEDCONCURRENCY 限制为不超过 8 个并发查询:
=> CREATE RESOURCE POOL analytics_pool FOR SUBCLUSTER analytics
MEMORYSIZE '60%'
EXECUTIONPARALLELISM AUTO
PLANNEDCONCURRENCY 8;
6 - 管理系统资源使用率
您可以使用 使用系统表 来跟踪群集上的总体资源使用情况。Vertica 系统表中介绍了这些系统表和其他系统表。
如果您的查询因资源不可用而遇到错误,则可使用以下系统表获取更多详细信息:
当某种类型的资源请求被拒绝时,请执行以下操作之一:
RESOURCE_REJECTIONS 中的 LAST_REJECTED_VALUE
字段指示问题原因。例如:
-
消息 Usage of a single requests exceeds high limit
表示系统没有可用于单个请求的足够资源。当文件处理限制设置得过低且您正在加载包含大量列的表时,通常会出现上述情况。
-
消息“等待资源预留超时或已取消等待资源预留 (Timed out or Canceled waiting for resource reservation)”通常表示资源争夺过于激烈,因为硬件平台无法支持使用它的并发用户数。
6.1 - 管理会话
Vertica 为数据库管理员提供了用于查看和控制会话的强大方法。具体方法因会话类型而异:
配置最大会话数
每个节点的最大用户会话数由配置参数 MaxClientSessions
设置,默认值为 50。您可以将 MaxClientSessions
参数设置为 0 到 1000 之间的任何值。除了这个最大值外,Vertica 还允许每个节点最多五个管理会话。
例如:
=> ALTER DATABASE DEFAULT SET MaxClientSessions = 100;
注意
如果使用管理工具 (Administration Tools) 的“连接到数据库 (Connect to Database)”选项,则当本地连接未成功时,Vertica 将会尝试连接到其他节点。与您在给定 MaxClientSessions
值的情况下的预期相比,这些情况可以产生更多成功的“连接到数据库 (Connect to Database)”命令。
查看会话
系统表
SESSIONS
包含有关用户会话的详细信息,每个会话将返回一行。超级用户可以无限制地访问所有数据库元数据。其他用户的访问权限因他们的权限而异。
中断和关闭会话
您可以使用 Vertica 函数
INTERRUPT_STATEMENT
中断正在运行的语句。中断正在运行的语句会将会话返回到空闲状态:
-
没有语句或事务正在运行。
-
没有保留任何锁。
-
数据库不代表会话做任何工作。
关闭用户会话将中断该会话并处置与其相关的所有状态,包括用于目标会话的客户端套接字连接。以下 Vertica 函数关闭一个或多个用户会话:
SELECT
用来调用这些函数的 SELECT 语句在中断或关闭消息传递到所有节点后返回。该函数可能会在 Vertica 完成中断或关闭操作的执行之前返回。因此,在语句返回之后以及在中断或关闭操作在整个群集中生效过程中可能存在一个延迟。若要确定会话或事务是否结束,请查询 SESSIONS
系统表。
为了关闭数据库,您必须首先关闭所有用户会话。有关数据库关闭的更多信息,请参阅停止数据库。
6.2 - 管理加载流
您可以使用系统表 LOAD_STREAMS 在数据加载到群集时对数据进行监控。此表中的几列显示每个节点上每个加载流的指标,包括:
取决于数据大小,在 PARSE_COMPLETE_PERCENT
达到 100% 的时间与 SORT_COMPLETE_PERCENT
开始增长的时间之间可能会出现明显的滞后。