本文翻译整理自:Best Practices for Preparing Your Cluster for Rebalance
关于vertica在rebalance过程中的原理及优化,请参考之前的博文。
集群rebalance前的操作
必须进行的操作
硬件检查
当在新的数据库节点上执行重新平衡时,请确认新节点的系统配置与集群中的现有节点相同或更好。此配置包括CPU数量,处理器的时钟速度,内存大小,磁盘IO和网络吞吐量。要检查系统配置是否相同或更好,请在新节点上运行vioperf,vnetperf和vcuperf,并将结果与现有节点进行比较。
在新节点上配置操作系统参数以匹配现有节点上的参数。
清理不必要的数据
删除非必要的schema,表和projections,以及大表的一些非必要的分区。
提升AHM
如果您的表包含许多已删除的记录,并且AHM epoch比current epoch小太多,则重新平衡可能会花费更长的时间。发生这种情况是因为拆分的ROS容器在重新平衡过程中可能会遇到replay deletes操作,并消耗更多时间。为避免此问题,请运行以下命令来提升AHM:
SELECT make_ahm_now();
使用以下命令,检查确保AHM epoch只比current epoch小1。
SELECT get_ahm_epoch(), get_last_good_epoch(), get_current_epoch();
确认AHM已更新后,Vertica建议您在开始数据库重新平衡之前清除所有已删除的记录。特别是,请考虑从包含数百万条记录的事实表中清除所有已删除的记录。
修改参数
vertica在重新平衡过程中多次对storage_containers运行查询,以确定可以在不耗尽磁盘空间的情况下重新平衡表的顺序。包含大量ROS容器的数据库此查询需要几分钟才能返回结果。多次运行此查询会导致更长的重新平衡时间。
如果在重新平衡时,确定数据库磁盘空间充足,则可以通过将配置参数RebalanceQueryStorageContainers设置为0来避免运行这些查询。
方法如下:
dbadmin=> SELECT DISTINCT parameter_name, current_value, default_value, description
dbadmin-> FROM vs_configuration_parameters
dbadmin-> WHERE parameter_name = 'RebalanceQueryStorageContainers';
parameter_name | current_value | default_value | description
---------------------------------+---------------+---------------+----------------------------------------
RebalanceQueryStorageContainers | 1 | 1 | Check storage containers for rebalance
(1 row)
dbadmin=> ALTER DATABASE mydb SET RebalanceQueryStorageContainers = 0;
ALTER DATABASE
dbadmin=> SELECT DISTINCT parameter_name, current_value, default_value, description
dbadmin-> FROM vs_configuration_parameters
dbadmin-> WHERE parameter_name = 'RebalanceQueryStorageContainers';
parameter_name | current_value | default_value | description
---------------------------------+---------------+---------------+----------------------------------------
RebalanceQueryStorageContainers | 0 | 1 | Check storage containers for rebalance
(1 row)
资源池设置
将Refresh资源池的MAXCONCURRENCY和PLANNED CONCURRENCY参数设置为等于数据库中节点的CPU核数。
如果要在维护窗口期间执行重新平衡,请通过运行alter resource pool在用户定义的池上将MEMORYSIZE设置为0,以从已设置初始内存大小的任何用户资源池中临时释放内存。完成重新平衡后,可以还原到原始资源池设置。
检查重新平衡成功
重新平衡完成后,运行以下语句:
=> SELECT get_node_dependencies();
如果重新平衡成功完成,此命令将返回等于群集中节点数+ 1的行数。例如,在10个节点的群集中,它返回11行,并且每行中应有10位1和0。
可选操作
软件升级
如果您使用的Vertica版本早于8.0.1-x,请考虑升级到最新的Vertica版本以增强重新平衡性能。Vertica 8.0.1-x及更高版本中提供的一些重新平衡改进功能,包括:在分离存储容器中增强了并行性,并提高了重新平衡监视表(如rebalance_table_status和rebalance_projection_status)的效率。
备份数据库
在添加或删除节点并开始重新平衡活动之前,请对当前数据库执行备份。在对集群进行任何重大配置更改之前,执行备份是一项重要且建议执行的任务。
维护窗口
如果可能,请尝试通过停止ETL和所有用户查询来在维护时段内执行重新平衡。这将分配所有系统资源以进行重新平衡,以帮助尽快完成重新平衡。如果无法获得排他的维护窗口来进行重新平衡,请尝试最小化加载,更新和删除查询中涉及的ETL,同时允许选择用户查询。
重新启动数据库
如果可能,请在重新平衡之前重新启动数据库。如果数据库长时间处于UP状态,则重新启动有助于减小目录大小,并有助于提高总体重新平衡性能。
估计重新平衡时间
数据库重新平衡过程涉及以下步骤:
- 在每个现有节点上拆分ROS容器。
- 将ROS容器传输到所有节点。
- 在系统表上进行内部查询以查找每个投影所使用的磁盘空间。
- 杂项操作,例如目录更新和节点依赖性计算。
您可以使用以下公式估算重新平衡数据库所需的时间:
重新平衡数据库的总时间= ROS拆分时间+ ROS传输时间+对系统表的查询+杂项操作(节点依赖性计算,目录更新)
Ros分割时间估算
没有用于拆分ROS容器的历史时间信息。分割给定投影的ROS容器所需的时间等于合并相同大小的ROS容器所需的时间。
要估算分割ROS容器所需的时间,您必须找到ROS容器的数量,ROS容器的大小以及Tuple Mover合并不同大小的ROS容器所花费的时间。对于所有属于数据库中每个投影的ROS容器,在任何系统表中,Tuple Mover合并操作完成所花费的时间可能都不可用。为了进行此估算,我们根据大小将ROS容器分组到不同的存储桶中,然后找到ROS容器的数量以及每个组的平均合并时间。
估算方法如下:
- 获取不同大小ros容器的平均分割时间
建表:
CREATE TABLE merge_time( ros_size varchar(25),duration_sec float);
以下内容为基于从具有不同集群和数据大小的客户那里收集的250种不同检查结果计算得出的平均合并时间,可将这些内容插入到表merge_time中以进行时间估算。
ros_size | time_sec
-------------------------+------------
A_Less_than_100MB | 0.844
B_Between_100MB_to_200MB | 2.000
C_Between_200MB_to_400MB | 6.833
D_Between_400MB_to_600MB | 11.095
E_Between_600MB_to_800MB | 13.000
F_Between_800MB_to_1GB | 23.000
G_Between_1GB_to_2GB | 35.000
H_Between_2GB_to_4GB | 68.000
I_Between_4GB_to_8GB | 137.846
J_Between_8GB_to_16GB | 320.444
K_Between_16GB_to_32GB | 617.650
L_Greater_than_32GB | 2528.500
或者,可以从你自己的数据库中的系统表中,获取不同大小ros容器的平均分割时间,这样更准确一些。
INSERT into merge_time SELECT ros_size, max(avg_duration) time_sec from (SELECT
s.node_name,
CASE
WHEN s.total_size_in_bytes < 100000000 THEN 'A_Less_than_100MB'
WHEN (s.total_size_in_bytes > 100000000 AND
s.total_size_in_bytes < 200000000) THEN 'B_Between_100MB_to_200MB'
WHEN (s.total_size_in_bytes > 200000000 AND
s.total_size_in_bytes < 400000000) THEN 'C_Between_200MB_to_400MB'
WHEN (s.total_size_in_bytes > 400000000 AND
s.total_size_in_bytes < 600000000) THEN 'D_Between_400MB_to_600MB'
WHEN (s.total_size_in_bytes > 600000000 AND
s.total_size_in_bytes < 800000000) THEN 'E_Between_600MB_to_800MB'
WHEN (s.total_size_in_bytes > 800000000 AND
s.total_size_in_bytes < 1000000000) THEN 'F_Between_800MB_to_1GB'
WHEN (s.total_size_in_bytes > 1000000000 AND
s.total_size_in_bytes < 2000000000) THEN 'G_Between_1GB_to_2GB'
WHEN (s.total_size_in_bytes > 2000000000 AND
s.total_size_in_bytes < 4000000000) THEN 'H_Between_2GB_to_4GB'
WHEN (s.total_size_in_bytes > 4000000000 AND
s.total_size_in_bytes < 8000000000) THEN 'I_Between_4GB_to_8GB'
WHEN (s.total_size_in_bytes > 8000000000 AND
s.total_size_in_bytes < 16000000000) THEN 'J_Between_8GB_to_16GB'
WHEN (s.total_size_in_bytes > 16000000000 AND
s.total_size_in_bytes < 32000000000) THEN 'K_Between_16GB_to_32GB'
ELSE 'L_Greater_than_32GB'
END AS ros_size,
avg(DATEDIFF(SECOND,s.time,c.time)) as avg_duration
FROM dc_tuple_mover_events s
JOIN dc_tuple_mover_events c
ON s.node_name=c.node_name
AND s.projection_oid = c.projection_oid
AND s.transaction_id = c.transaction_id
AND s.session_id = c.session_id
WHERE s.operation = 'Mergeout'
AND c.operation = 'Mergeout'
AND s.event = 'Start'
AND c.event = 'Complete'
AND s.container_count > 1
AND c.container_count > 1
AND s.transaction_id not in (select distinct transaction_id from dc_tuple_mover_events where event ilike '%replay delete%')
GROUP BY 1,2 ) f GROUP BY 1;
commit;
2.获取数据库中的不同大小的ros容器的数目
建表:
CREATE TABLE public.ros_count( ros_size varchar(25),ros_count int);
插入数据
INSERT into ros_count
select ros_size,max(ros_count) max_ros_cnt from (
SELECT
node_name,
CASE
WHEN used_bytes < 100000000 THEN 'A_Less_than_100MB'
WHEN (used_bytes > 100000000 AND
used_bytes < 200000000) THEN 'B_Between_100MB_to_200MB'
WHEN (used_bytes > 200000000 AND
used_bytes < 400000000) THEN 'C_Between_200MB_to_400MB'
WHEN (used_bytes > 400000000 AND
used_bytes < 600000000) THEN 'D_Between_400MB_to_600MB'
WHEN (used_bytes > 600000000 AND
used_bytes < 800000000) THEN 'E_Between_600MB_to_800MB'
WHEN (used_bytes > 800000000 AND
used_bytes < 1000000000) THEN 'F_Between_800MB_to_1GB'
WHEN (used_bytes > 1000000000 AND
used_bytes < 2000000000) THEN 'G_Between_1GB_to_2GB'
WHEN (used_bytes > 2000000000 AND
used_bytes < 4000000000) THEN 'H_Between_2GB_to_4GB'
WHEN (used_bytes > 4000000000 AND
used_bytes < 8000000000) THEN 'I_Between_4GB_to_8GB'
WHEN (used_bytes > 8000000000 AND
used_bytes < 16000000000) THEN 'J_Between_8GB_to_16GB'
WHEN (used_bytes > 16000000000 AND
used_bytes < 32000000000) THEN 'K_Between_16GB_to_32GB'
ELSE 'L_Greater_than_32GB'
END AS ros_size,
COUNT(*) AS ros_count
FROM projection_storage
GROUP BY 1, 2 ORDER BY 1, 2) f group by 1;
commit;
3.通过下面的query计算时间
SELECT sum(duration_sec*ros_count) split_time_seconds FROM merge_time m JOIN ros_count r
ON r.ros_size=m.ros_size;
此时间以秒为单位。将其除以节点上CPU核心的数量即可得出ROS分割估计时间。
Ros传输时间估算
此步骤取决于网络吞吐量和每个节点上的数据量。要估算此步骤所需的时间,我们需要找到每个节点上的数据大小和网络速度。
内部系统表查询
vertica在重新平衡过程中多次对storage_containers运行查询,以确定可以在不耗尽磁盘空间的情况下重新平衡表的顺序。包含大量ROS容器的数据库此查询需要几分钟才能返回结果。多次运行此查询会导致更长的重新平衡时间。
如果在重新平衡时,确定数据库磁盘空间充足,则可以通过将配置参数RebalanceQueryStorageContainers设置为0来避免运行这些查询。
修改方法见上文。
其他平衡操作
必须对系统中的每个投影执行此步骤。要计算此步骤所需的时间,您必须在数据库中找到投影的数量。根据对从不同客户系统收集的多个详细检查的审查,平均而言,此步骤每个投影大约需要250毫秒。
例如,在具有30,000个分段和未分段投影的数据库上,此步骤大约需要2个小时。
可以使用rebalance_operations表监视重新平衡进度。