背景
最近在研究clickhouse,发现了不少坑,有些坑是官方的无法解决,有些是配置的问题。配置问题及优化的问题就需要我们不断的调整配置以及优化sql。优化sql最主要是理解clickhouse是如何查询的,我们才能找到瓶颈点,找到优化方法。
问题
在8G内存4核CPU的机器上,单节点的默认配置的clickhouse,保存数据8000W+,一个复杂的多表关联的查询,每次查询到98%的时候,clickhouse就自动宕机了,报错如下:
Exception on client:
Code: 32. DB::Exception: Attempt to read after eof: while receiving packet from localhost:9000, ::1
Connecting to localhost:9000.
Code: 210. DB::NetException: Connection refused (localhost:9000, ::1)
查看clickhouse日志正常,error日志也未见异常。很是神奇。
服务被强制干掉了。
在官网的issues中可以查到不少人跟我情况一样
问题排查
为什么会这样,就是clickhouse在查询的时候会把数据加载到缓存中,缓存撑爆了,发生OOM了,可以通过linux命令
dmesg
查看linux状态,发现最后一行如下所示
[14666975.982367] Out of memory: Kill process 2591 (clickhouse-serv) score 412 or sacrifice child
[14666975.989771] Killed process 2591 (clickhouse-serv) total-vm:6092664kB, anon-rss:3145272kB, file-rss:165208kB, shmem-rss:0kB
如何解决
目前没看到有什么好的解决方案,我是如何解决的
- 换一个更大内存的服务器8G——>16G
- 优化sql,缩小查询范围
- 优化索引,跳过更多的数据扫描
- 调整用户查询限制,不能超过内存大小(至少先保证服务正常,不能说一个大查询直接把服务kill了)
经过以上优化基本保证了服务不会被kill掉,并且查询速度也会明细提升。
修改user.xml <max_memory_usage>10000000000</max_memory_usage>
限制最大内存不能超过系统最大可用内存