Clickhouse-CPU内存资源优化配置

Posted 高世之智

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Clickhouse-CPU内存资源优化配置相关的知识,希望对你有一定的参考价值。

优化

CPU资源优化

config.xml 官网配置项 https://clickhouse.tech/docs/en/operations/server-configuration-parameters/settings/

物理机的CPU资源:

# 总核数 = 物理CPU个数 X 每颗物理CPU的核数 
# 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数

# 查看物理CPU个数
cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l

# 查看每个物理CPU中core的个数(即核数)
cat /proc/cpuinfo| grep "cpu cores"| uniq

# 查看逻辑CPU的个数
cat /proc/cpuinfo| grep "processor"| wc -l

CPU配置优化:

background_pool_size

此配置在users.xml中,用于设置后台线程池的大小, merge 线程就是在该线程池中执行,该线程池不仅仅是给 merge 线程用的,默认值 16,允许的前提下建议改成 cpu 个数的 2倍(线程数)。

<background_pool_size>128</background_pool_size>

background_schedule_pool_size

此配置在users.xml中,用于设置执行后台任务(复制表、 Kafka 流、DNS 缓存更新)的线程数。 默认 128,建议改成 cpu 个数的 2 倍(线程数)。

<background_schedule_pool_size>128</background_schedule_pool_size>

background_distributed_schedule_pool_size

此配置在users.xml中,用于设置分布式发送执行后台任务的线程数,默认 16,建议改成 cpu个数的 2 倍(线程数)。

<background_distributed_schedule_pool_size>128</background_distributed_schedule_pool_size>

max_concurrent_queries

此配置在config.xml中,用于设置最大并发处理的请求数 (包含 select,insert 等),默认值 100,推荐 200(不够再加)~300。

<max_concurrent_queries>200</max_concurrent_queries>

内存资源优化

config.xml 官网的配置项 https://clickhouse.tech/docs/en/operations/server-configuration-parameters/settings/

物理机的内存资源:

# 以GB显示,如下物理机内存资源为125gb
$ free -g
total        used        free      shared  buff/cache   available
Mem:            125          48          26           0          50          76
Swap:             0           0           0

内存配置优化:

服务器内存优化

echo 'never' | sudo tee /sys/kernel/mm/transparent_hugepage/enabled

max_memory_usage

此参数在 users.xml中, 表示单次 Query 占用内存最大值,该值可以设置的比较大,这样可以提升集群查询的上限。保留一点给 OS,比如 128G内存的机器,设置为 100GB。

<max_memory_usage>100000000000</max_memory_usage>

对于clickhouse而言,一下语句都算查询语句,包括insert插入

max_bytes_before_external_group_by

此参数在 users.xml中, 一般按照 max_memory_usage 的一半设置内存,当 group 使用内存超过阈值后会刷新到磁盘进行。因为 clickhouse 聚合分两个阶段:查询并及建立中间数据、合并中间数据,结合上一项,建议 50GB。注意变量是字节

<max_bytes_before_external_group_by>50000000000</max_bytes_before_external_group_by>

max_bytes_before_external_sort

此参数在 users.xml中, 当 order by 已使用 max_bytes_before_external_sort 内存就进行溢写磁盘(基于磁盘排序),如果不设置该值,那么当内存不够时直接抛错,设置了该值 order by 可以正常完成,但是速度相对存内存来说肯定要慢点(实测慢的非常多,但比报错好)。

建议是max_memory_usage的0.8

<max_bytes_before_external_sort>80000000000</max_bytes_before_external_sort>

max_table_size_to_drop

此参数在 config.xml 中,应用于需要删除表或分区的情况,默认是50GB,意思是如果删除 50GB 以上的分区表会失败。建议修改为 0,
这样不管多大的分区表都可以删除。

<max_table_size_to_drop>0</max_table_size_to_drop>

CPU内存优化配置示例

config.xml

<max_concurrent_queries>200</max_concurrent_queries>
<max_table_size_to_drop>0</max_table_size_to_drop>

users.xml

<background_pool_size>128</background_pool_size>
<max_memory_usage>100000000000</max_memory_usage>
<max_bytes_before_external_group_by>50000000000</max_bytes_before_external_group_by>
<max_bytes_before_external_sort>80000000000</max_bytes_before_external_sort>
<background_schedule_pool_size>128</background_schedule_pool_size>
<background_distributed_schedule_pool_size>128</background_distributed_schedule_pool_size>

冷热磁盘

官网链接:https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree#table_engine-mergetree-multiple-volumes

熔断机制

可以设置单次sql查询的熔断机制,比如用户某次查询时间过长或占用太多内存时熔断机制,此处可以查看官网
官网地址:https://clickhouse.com/docs/en/operations/quotas

sql优化

强烈建议所有待执行的sql都先经过语法优化后的语法:

C# 客户端内存优化分析

背景概述


C# 开发客户端系统的时候,.net 框架本身就比较消耗内存资源,特别是xp 这种老爷机内存配置不是很高的电脑上运行,所以就需要进行内存上的优化,才能流畅的在哪些低端电脑上运行. 想要对C# 开发的客户端内存优化需要了解以下几个概念。


虚拟内存


一句话概括虚拟内存既是使用磁盘,物理磁盘进行虚拟化出来的内存空间。


物理内存

物理内存(Physical memory)是相对于虚拟内存而言的。物理内存指通过物理内存条而获得的内存空间,而虚拟内存则是指将硬盘的一块区域划分来作为内存。内存主要作用是在计算机运行时为操作系统和各种程序提供临时储存。常见的物理内存规格有256M、512M、1G、2G等,现如今随着计算机硬件的发展,已经出现4G、8G甚至更高容量的内存规格。当物理内存不足时,可以用虚拟内存代替。在应用中,自然是顾名思义,物理上,真实存在的插在主板内存槽上的内存条的容量的大小。看计算机配置的时候,主要看的就是这个物理内存。


GC 垃圾回收机制


简介

C#中和Java一样是一种系统自动回收释放资源的语言,在C#环境中通过 GC(Garbage Collect)进行系统资源回收,在数据基本类型中介绍到,C#数据类型分为引用类型和值类型,


值类型保存在Stack上,随着函数的执行作用域执行完毕而自动出栈,所以这一类型的资源不是GC所关心 对象。GC垃圾回收主要是是指保存在Heap上的资源。


.NET的GC机制有这样两个问题:

- 首先,GC并不是能释放所有的资源。它不能自动释放非托管资源。

- 第二,GC并不是实时性的,这将会造成系统性能上的瓶颈和不确定性。

  

GC并不是实时性的,这会造成系统性能上的瓶颈和不确定性。所以有了IDisposable接口,IDisposable接口定义了Dispose方法,这个方法用来供程序员显式调用以释放非托管资源。使用using语句可以简化资源管理。


托管资源和非托管资源

上面介绍到,GC只释放托管资源,那么什么是托管资源和非托管资源。


- 托管资源   :托管资源指的是.NET可以自动进行回收的资源,主要是指托管堆上分配的内存资源。托管资源的回收工作是不需要人工干预的,有.NET运行库在合适调用垃圾回收器进行回收。


- 非托管资源:非托管资源指的是.NET不知道如何回收的资源,最常见的一类非托管资源是包装操作系统资源的对象,例如文件,窗口,网络连接,数据库连接,画刷,图标 等。这类资源,


垃圾回收器在清理的时候会调用Object.Finalize()方法。默认情况下,方法是空的,对于非托管对象,需要在此方法中编写回收非托管资源的代码,以便垃圾回收器正确回收资源。


总结:托管资源是释放由GC来完成,释放的时间吧不一定,一般是系统感觉内存吃紧,会进行紧急回收资源。一个对象想成为被回收,首先需要成为垃圾,GC是通过判断对象及其子对象有没有指向有效的引用,

如果没有GC就认为它是垃圾。垃圾回收机制通过一定的算法得到哪些没有被被引用、或者不再调用的资源,当这些垃圾达到一定的数量时,会启动垃圾回收机制,GC回收实际上是调用了析构函数。

垃圾回收机制意味着你不需要担心处理不再需要的对象了。咱们关心的主要是非托管资源的释放。

垃圾回收时对象一共有三代 :0,1,2。每一代都有自己的内存预算,空间不足的时候会调用垃圾回收。为了提高性能都是按代回收,第0代超预算之后就回收第0代的对象,而存活下来的对象就提升为第1代,

依次类推,而往往经过多次0代的垃圾回收才能回收一次第1代。


GC进行垃圾回收是系统决定的,下面是进行强制回收的执行代码(非特殊情况下不要使用此方法,会影响系统效率,削弱垃圾回收器中优化引擎的作用,而垃圾回收器可以确定运行垃圾回收的最佳时间)

//对所有代进行垃圾回收。GC.Collect();//对指定的代进行垃圾回收。GC.Collect(int generation); //强制在 System.GCCollectionMode 值所指定的时间对零代到指定代进行垃圾回收。GC.Collect(int generation, GCCollectionMode mode); 


关于 SetProcessWorkingSetSize 和内存释放

 在应用程序中,往往为了释放内存等,使用一些函数,其实,对于内存操作函数要谨慎使用,比如大家常常想到的 SetProcessWorkingSetSize,其实对于windows来说,系统会自动在程序闲置时(如程序被最小化)释放内存的,自己用内存释放 时,往往会造成一些莫名的内存错误,造成自己的应用程序及系统不稳定。


SetProcessWorkingSetSize的作用

- 物理内存转移到虚拟内存中

  - msdn解释:使用这个函数来设置应用程序最小和最大的运行空间,只会保留需要的内存.当应用程序被闲置或系统内存太低时,操作系统会自动调用这个机制来设置应用程序的内存.应用程序也可以使用 VirtualLock 来锁住一定范围的内存不被系统释放;当你加大运行空间给应用程序,你能够得到的物理内存取决于系统,这会造成其他应用程序降低性能或系统总体降低性能,这也可能导致请求物理内存的操作失败,例如:建立 进程,线程,内核池,就必须小心的使用该函数.也就是说,该函数不是节省内存,而是强制把进程的物理内存搬到虚拟内存中.


SetProcessWorkingSetSize 的劣势

- 危害:如果 SetProcessWorkingSetSize 函数被正常使用,是非常有用处的.但是为了蒙骗用户的眼睛,每秒,甚至几十毫秒就把大量内存往虚拟内存里面压,就会带来无可预计的危害.看看这篇文章怎么 说:“因为他只是暂时的将应用程序占用的内存移至虚拟内存,一旦,应用程序被激活或者有操作请求时,这些内存又会被重新占用.如果你强制使用该方法来设置 程序占用的内存,那么可能在一定程度上反而会降低系统性能,因为系统需要频繁的进行内存和硬盘间的页面交换.”.


优化内存代码:

[DllImport("kernel32.dll")]private static extern bool SetProcessWorkingSetSize(IntPtr proc, int min, int max);
private void FlushMemory(){ GC.Collect(); GC.WaitForPendingFinalizers(); if (Environment.OSVersion.Platform == PlatformID.Win32NT) { SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1); }}


以上是关于Clickhouse-CPU内存资源优化配置的主要内容,如果未能解决你的问题,请参考以下文章

记Filebeat系统资源使用优化

记Filebeat系统资源使用优化

tomcat内存配置优化

Android性能优化--冷启动优化(Application)

Oracle配置和性能优化方法

C# 客户端内存优化分析