在Klustron集群中执行长时耗语句所需的设置
在Klustron集群中执行长时耗语句所需的设置
前言
一个分布式计算和存储系统的任何节点都可能因为节点负载过重,节点的计算、存储资源不足,网络延时,网络短暂不可达、计算或者存储工作量巨大等原因而导致操作超时。
分布式系统的任何操作在等待远程节点返回期间,通常会持有各种资源,不可以无限制等待下去,否则系统整体运行都会因此被阻塞而逐步停滞。
所以超时控制是所有分布式系统需要去解决好的问题,而解决不好就会导致系统运行停滞,无法正常工作。klustron有一系列超时控制变量,在执行特殊任务时需要特殊设置。
另外,在执行OLAP类型的查询时,需要增大CPU、内存资源配置,以便提升OLAP查询的性能。
本文介绍这些需要在特殊场景设置的超时参数和资源参数。
Klustron 的超时控制机制简介
Klustron 有以下超时控制变量
- 一部分在计算节点中,计算节点的超时变量都在计算节点实例的配置文件中,可以按需修改,并且修改后刷新运行实例的参数。
- 一部分在存储节点中,存储节点的超时变量在存储节点配置文件中,可以修改配置文件,也可以通过在计算节点或者存储节点执行 set 语句修改对应变量值。
通常情况下用户并不需要修改这些变量,因为我们已经针对常规情况最优化了计算节点和存储节点的配置参数。
在以下特殊场景需要修改超时变量
- 在一个 DML 语句中插入/更新/删除数百万行甚至更多的数据
- 一个select语句中要返回数百万行甚至更多的数据(比如OLAP类型的查询)
- 执行的DDL 语句需要修改大量数据,比如修改列的数据类型、是否可以NULL等
例如,逻辑导入超大的数据表或者全量数据,对超大的表做全表更新,数据分析( OLAP )查询需要扫描一个超大的表等。
这些场景下用户最好根据预估插入/更新/删除/读取的数据量,提前增大下述各个超时值,以确保相关语句和操作可以正常工作直至完成,不会被超时机制误认为是已经超时无法正确执行的语句而提前终止掉。
或者用户可以在尝试这些操作并得到错误之后,再增大这些超时值。
从Klustron-1.3版本开始,用户可以设置下述变量来快速地完成下文所有设置
set massive_write_mode = on
set enable_ddl_mode = on
set enable_olap_mode = on
Klustron 计算节点的超时变量功能
1. statement_timeout:语句超时。
如果计算节点执行查询的总时间超过这个限制,语句就会被回滚。
比如,如果计算节点使用存储集群返回的部分数据执行表连接时耗过长,那么最终会在达到这个超时限制后停止(默认 100 秒)。
2. mysql_read_timeout 和 mysql_write_timeout:计算节点于存储节点/元数据节点之间的通信收发(读写)超时。
读取超过 mysql_read_timeout 或者写入超过 mysql_write_timeout 那么计算节点使用的 mysql 客户端库就会报错并且从读取/写入等待中返回,这样语句执行就提前终止了。
如果一条发送给计算节点的一条insert语句会插入 100 万行数据,或者一条 select 语句会从存储节点返回上百万行数据,那么最好增加这两个变量的值,它们默认是 50 秒。
另外,这种情况下还要增大 mysql_max_packet_size 变量,确保这样的超大数据包可以正确发送给存储节点。
3. lock_timeout:计算节点等待表锁的时间。
并发执行的增删改查语句对表的所是相容的,不需要等待锁。
但是如果某个alter table语句正在执行,那么同一个计算节点上其他连接中无法执行针对这个表的 DML 语句,它们最多等这么久,还拿不到锁就会报错返回(默认 100 秒)。
4. log_min_duration_statement:超过这个时间的语句会作为慢查询记录到日志文件中。
如果要在每条insert语句中插入数万行甚至更多,那么一定要把这个变量增大,否则会在日志文件中记录大量数据,导致计算节点磁盘空间用尽(默认 10 秒)。
Klustron 存储节点的超时变量功能
所有下述需要对存储节点变量做的修改,都可以在灌入数据之前,在本集群任意一个计算节点执行set语句,例如 set global long_query_time=1000;
这个语句会被计算节点发送到集群所有storage shard的主节点。
1. lock_wait_timeout:mysql server 层的锁超时变量。
等待server层的表锁的最大时间。如果一个 DDL 语句在 alter table, 那么所有对该表做 DML 语句的事务会阻塞等待最多这么多表,还得不到表锁就会返回错误。
在 MySQL8.0 时代,加列和加索引这种最常见的曾经要锁住全表才能完成的操作已经不需要全表长期锁定了,已经变成了 online ddl,因此默认 5 秒一般来说足够了。
2. innodb_lock_wait_timeout:mysql innodb 的锁超时变量,等待 innodb 行锁的最大时间。
超过了那么 DML 语句就会报错返回。
如果要做全表更新,并且表的数据量非常大,比如几百 GB 甚至更多,那么 update 语句会锁住大量的行很长时间,此时其他事务通常会发生锁超时,除非增大了其 innodb_lock_wait_timeout(默认 20 秒)。
3. 如果存储集群使用了 MySQL Group Replication 做高可用
那么需要增大 MGR 的 group_replication_member_expel_timeout,group_replication_component_stop_timeout, group_replication_unreachable_majority_timeout 超时控制变量,否则 MGR 的备机会误以为主节点宕机了从而发起主备切换,或者主节点以为备机失去联系了从而无法写入。
不过从 Klustron-1.0 开始 Klustron已经不再支持在存储集群使用MGR。
4. 慢查询阈值 Long_query_time
增大Long_query_time,它默认10秒,可以增大到 例如100秒或者更多。如果一个插入100万行的insert语句被认为是慢查询而记录到慢查询日志的话,写入这个日志会占用大量的时间和磁盘存储空间。
5. 网络读写超时
如果存储节点负载很重,无法及时处理计算节点下发的请求,那么计算节点会收到断连错误。此时需要增大net_read_timeout和 net_write_timeout.
6. 设置max_allowed_packet
在Klustron-storage节点中这个变量默认是1GB。如果查询执行过程中,从Klustron-storage存储节点返回大量数据到Klustron-server计算节点,有可能会一次性返回超过这个阈值,从而导致报错。遇到如下错误:
Packet for query is too large (20682943>1048576). You can change this value on the server by setting the max_allowed_packet’ variable.
那么可以增大集群中所有存储节点的max_allowed_packet
OLAP mode的设置
当执行OLAP分析时,通常应用发起的连接数量并不多,但是每个语句执行所需的CPU和内存资源较大,所以需要在计算节点和存储节点中做适当设置以便达到最好的性能。本文列出这些变量,具体设置的数值可以按需调整,需要参考PostgreSQL或者MySQL的参考文档理解相关变量的意义和合理值范围。另外,可以在独立的若干个服务器上面专门安装若干个计算节点用于执行OLAP查询,并且使用Klustron的读写分离功能连接到备机执行OLAP功能,这样就完全把OLTP负载和OLAP负载分隔在不同的服务器上,不会相互干扰影响性能。
从1.3版本开始,用户可以设置enable_olap_mode=true来一次性在计算节点和存储节点中完成下述设置。
在计算节点(Klustron-server)中设置如下变量
max_parallel_workers_per_gather = 32
max_parallel_workers = 128
work_mem = 64MB
在存储节点(Klustron-storage)中设置如下变量
optimizer_switch='mrr_cost_based=off,batched_key_access=on'
join_buffer_size = 128M
sort_buffer_size = 64M
read_rnd_buffer_size = 64M
结语
Klustron 具备完善的超时控制机制,在任何节点间通信机制中都有超时控制,确保任何操作都有最大时耗上限,确保系统状态可以持续推进,系统资源持续可服务更多的服务请求。