ClickHouse 数据库中的 “超时”

打印 上一主题 下一主题

主题 1971|帖子 1971|积分 5913


一、超时范例

关于Clickhouse数据库超时问题,必要留意三种不同的超时设置:
1.1 distributed_ddl_task_timeout超时问题:



  • 这是分布式DDL查询(带有 on cluster )的实行等候时间,默认值为180秒。
  • 可以通过在DMS上实行命令来设置全局参数:set global on cluster ck_cluster distributed_ddl_task_timeout = 1800;
  • 分布式DDL基于clickhouse-keeper构建任务队列异步实行,实行等候超时并不代表查询失败,只是表示之前发送的任务还在排队等候实行。可以在system.distrubuted_ddl_queue表中查到。
  • 这个超时的出现,一般是有什么异常DDL操作卡住了,导致背面的所有DDL语句都是一种超时状态。办理这个卡住的DDL语句就可以啦。
1.2 max_execution_time超时问题:



  • 这是一般查询的实行超时时间,默认值为3600秒。
  • 用户可以举行查询级别更改,比方:select * from system.numbers settings max_execution_time = 3600;
  • 可以在DMS上实行以下命令来设置全局参数:set global on cluster default max_execution_time = 3600;
  • 该参数在chproxy 代理上也可以设置(用到9090端口)
1.3 socket_timeout超时问题:



  • 这是HTTP协议在监听socket返回效果时的等候时间
  • 该参数不是Clickhouse系统内的参数,而是属于jdbc在HTTP协议上的参数。它会影响到前面的max_execution_time参数设置的效果,由于它决定了客户端在等候效果返回时间上的时间限制
  • 用户在调整 max_execution_time 参数的时间也必要配套调整 socket_timeout 参数,比方:jdbc:clickhouse://127.0.0.1:9090/ceelake?socket_timeout=3600000
以是这也是为什么很多应用超过30s就报超时的原因


二、insert数据超时优化策略

⚠️优化策略必要在确保插入语句没有问题之后才必要考虑,这里必要提前留意下不是由于 select 超时而导致insert 超时
2.1 max_insert_threads

默认值:0
增长并发插入线程----对于大数据量的插入操作,尤其是宽表(列非常多),默认的主动设置可能无法最大化使用系统的资源,导致插入速度较慢。
假如你的机器有多个CPU焦点,可以考虑手动增长max_insert_threads的值,以进步插入的并发度。你可以将其设置为与CPU焦点数雷同,大概略高一些。比方:
SETTINGS max_insert_threads = 16; -- 根据你服务器的焦点数调整
这可以增长插入操作的并行度,尤其是在大数据量的插入时,这样每个线程可以处理不同的数据分块,进步整体插入吞吐量。
实例:700多列 3000万数据的insert (大宽表)
2.2 insert_quorum

假如你的ClickHouse集群是分布式的,可以调整insert_quorum来控制写入的节点数量。淘汰insert_quorum可以淘汰等候节点确认的时间,从而提升插入速度。好比:
SETTINGS insert_quorum = 2; -- 根据集群规模调整
这个设置会使得插入操作在部门节点完成后就返回成功,从而加速插入过程。

2.3 max_memory_usage

插入大数据量时,内存消耗也很高。你可以通过调整max_memory_usage来限制每个插入操作的内存使用,制止因内存不足导致的瓶颈:
SETTINGS max_memory_usage = 10000000000; -- 设置为符合的内存限制

2.4 批量插入

假如一次性插入的数据量过大,实验将数据分批插入。ClickHouse在处理大批量数据时,分批插入可以淘汰资源压力。比方,每次插入100万条数据,而不是一次插入500万条数据。


2.5 得当调整max_insert_block_size

默认值:1048449
可以调整max_insert_block_size来限制每个插入块的巨细。固然默认设置一般得当,但在某些情况下,较小的块巨细可能会进步插入性能:
SETTINGS max_insert_block_size = 1048576; -- 比方:1MB巨细
插入表时要形成的块的巨细(以行数表示)。此设置仅实用于服务器形成块的情况。比方,对于通过HTTP接口的INSERT,服务器解析数据格式并形成指定巨细的块。但是,当使用clickhouse客户端时,客户端会自己解析数据,服务器上的“max_insert_block_size”设置不会影响插入块的巨细。使用INSERT SELECT时,该设置也没有目的,由于数据是使用SELECT后形成的雷同块插入的。
默认值略大于max_block_size。这样做的原因是,某些表引擎(*MergeTree)在磁盘上为每个插入的块形成一个数据部门,这是一个相当大的实体。同样,*MergeTree表在插入过程中对数据举行排序,足够大的块巨细答应在RAM中对更多数据举行排序。


2.6 并行批量插入

可以使用并行化工具(如clickhouse-client的并行插入功能,大概通过编写多线程的脚本)来进一步进步插入性能。通过并行插入多个小批次,可以进步吞吐量。




三、select 数据超时优化策略

3.0 语句优化

除了数据本身的问题,比方是否有字段大量使用NLLAble(影响性能), 具体查询语句具体优化;

3.1 单节点join

clickhouse单机join默认采取的是hash join算法,也就是说,先将右表全量读取到内存,然后构建hashmap,然后从左表分批读取数据,到hashmap中去匹配,假如掷中,那么就作为join之后的效果输出。
由于右表是要全量加载到内存的,这就要求要足够小。但是实际上右表大于TB级是很常见的事情,这时间就很容易出现OOM。

为了办理这个问题,有一种办理思路是将右表构建成大宽表,将维度拍平,使行尽量少,这样右表只必要加载少量的列进内存,从而缓解这一情况。
一个典范的落地实施案例就是clickhouse_sinker存储Prometheus指标的方案。它将指标分拆成两张表,一张metric表,用来存储时序指标值,一张metric_series表,用来存储具体的指标。两张表通过series_id举行关联。
在metric表中,每个时间点的每个值,都对应着一个series_id,我们通过这个series_id,反查metric_series表,就可以找到这个series_id对应的指标以及label。

3.2 分布式join

clickhouse的分布式join有两种玩法,一种是带global,一种是不带global。
普通join

汇总节点将左表更换为本地表
将左表的本地表分发到每个节点
在每个节点实行本地join
将效果汇总回汇总节点
这种做法有一个非常严重的问题。在第三步,每个节点实行分布式join的时间,假如右表也是分布式表,那么集群中的每个节点都要去实行分布式查询,那也就是说,假如集群有N个节点,右表查询就会在集群中实行N*N次,这就是查询放大现象。(对这个感爱好的可以看看文档。。。。 ,具体报告了查询放大的现象)

正是由于这种问题的存在,在比较新的clickhouse版本中,分布式join假如不加global,已经会从语法层面报错了。这说明官方已经克制了这种写法的存在。

global join

汇总节点将右表改成子查询,先在汇总节点将右表的数据效果集查询出来
将右表的效果集广播给各个节点,与各个节点的左表本地表举行join查询
各个节点将查询效果发送给汇总节点
由于右表的效果已经在汇总节点计算出来了,那么也就不必要在其他节点重复计算,从而制止了读放大的问题。
但global join 的问题是它必要将整个子查询的效果集发送给各个节点,假如右表的效果集特别大,那么整个过程耗费的网络带宽也将黑白常恐怖的。

正确姿势



  • 大表在左,小表在右
  • 数据预分布,实现colocate join。也就是将涉及到join的表按照雷同的join key分片,使必要join的数据尽量都能在本地完成。也就是前文提到的shardingkey的用处。
  • 改大宽表

并发查询

并发查询也是clickhouse的一个比较单薄的领域。

由于对于clickhouse的查询来说,一个大的查询SQL往往会把整个服务器的资源吃满,假如并发查询比较多的话,那么不可制止地造成资源竞争,最终的效果就是谁也快不了,甚至还会出现OOM的情况。
官方默认的最大并发数是100, 这个100是每个节点的最大并发数,而不是整个集群的。它包含了查询的并发和写入的并发。

我们很容易碰到这样的场景:在界面上点击一个查询耗时比较久,等得不耐心,就多点了几下。究竟上,clickhouse并不会由于你在界面上多点了一下鼠标,就取消之前的SQL运行,反而会产生多个SQL在并发实行,假如这种耗时比较久的SQL越积CPU打满,造成的效果就是恶性循环,其他SQL也会越来越慢,最终导致并发的SQL超过了设置的最大并发数,再也无法实行任何查询语句,甚至写入都会受到影响。
我们一般建议将最大查询并发数,设置为最大并发数的90%,预留出10%的并发数量供数据写入使用。这样即使查询并发数打满了,仍旧不会影响到数据的写入。

我们可以通过配置来实现这一策略:
  1. <clickhouse>
  2.     <max_concurrent_queries>100</max_concurrent_queries>
  3.     <max_concurrent_select_queries>90</max_concurrent_select_queries>
  4. </clickhouse>
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

南飓风

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表