1.技术背景
在SQL语句简单、解决数据量大的AP场景下,单个查问对内存的需要越来越大,多个语句的并发很容易将零碎的内存吃满,造成内存不足的问题。为了应答这种问题,GaussDB for DWS引入了内存自适应控制的技术,在上述场景下可能对运行的作业进行内存级的管控,防止高并发场景下内存不足产生的各种问题。
2. GaussDB的动态内存管理机制及缺点
GaussDB的执行引擎继承自PG,对于优化器生成的执行打算树,总体采取执行算子+流水线的解决形式,如下图所示。
对于NestLoop算子节点,须要首先从左树的IndexScan算子节点获取元组,而后到右子树的IndexScan算子节点进行连贯,匹配元组后进行输入。流水线的执行形式使得对于NestLoop, IndexScan类的个别算子,同时只有肯定数量的元组处于内存中,对于行引擎每个算子仅占用一条元组的空间,对于列引擎占用一个batch(最多1000条元组)的空间,占用的空间较小,根本能够忽略不计。
然而,GaussDB中也有一些须要将所有数据收集后进行解决的算子,在执行时须要应用较多的内存,通常咱们称这类算子为物化算子。GaussDB中次要存在如下不同品种的物化算子:
(1)HashJoin:Hash连贯操作符,次要思维是计算左右两表连贯列的hash值,通过hash值比拟缩小元组比拟的次数,须要将一个表建设hash表,另一个表进行hash值比拟操作,建设hash表须要在内存中进行。
(2)HashAgg:Hash汇集操作符,次要思维同HashJoin相似,通过hash值比拟缩小元组去重比拟的次数,须要将不同值的元组保留的内存中。
(3)Sort:排序操作符,须要获取所有元组后进行排序操作,待排序元组均存在于内存中。
(4)Materialize:物化操作符,通常在须要反复扫描时应用,通过将后果存储在内存中,保障反复扫描时的效率。
同时,GaussDB也提供下盘的机制,当上述操作符须要应用的内存太大时,能够将局部或全副的数据下盘解决,进步内存的应用效率,但相应的查问性能也会受到影响。PG应用 work_mem参数来管制算子可应用内存的阈值,当应用内存超过阈值时,就须要做下盘解决。GaussDB的动态内存管理机制也连续了PG的解决机制,应用work_mem来管制单算子的内存应用下限。
GaussDB的动态内存治理存在较大弊病,须要调优人员可能依据数据量、语句复杂程度和零碎的内存大小设置正当的work_mem,既防止work_mem设置太大导致系统资源不够用,还要思考到数据规模,保障大部分算子不下盘。通常状况下,这个是很难做到的,有以下几点起因:
(1)通常状况下,简单语句的执行打算中蕴含多个简单算子,每个算子的内存应用下限是work_mem,咱们没有方法计算一个语句要应用多少内存,因而也就不容易设置一个最优的work_mem参数,保障尽可能不下盘,同时内存又够用。并发场景更无奈设置了。
(2)work_mem只是每个算子内存应用的下限,并不是预调配;如果数据量没有那么大的话,理论内存应用是达不到work_mem的。因而也会影响work_mem的设置。
(3)每个语句的场景不一样,有的语句蕴含多个物化算子,而另外的语句只有一个物化算子,而这个算子对内存的需要会比拟大,因而无奈全局对立地进行设置。
3. GaussDB的内存自适应技术介绍
针对动态内存管理机制的弊病,咱们设计了内存自适应控制技术,目标有两个:
(1)去除动态内存治理对work_mem的依赖。能够由SQL引擎优化器模块主动估算每个算子所需的内存。
(2)防止大并发场景下内存不足景象的产生。资源管理模块依据SQL引擎优化器对于每个查问内存的估算值,对每个查问进行调度,如果超过零碎可用内存,则进行排队。
如上图所示,动静资源管理与内存自适应技术的组件图如上图所示。咱们从多个CN中抉择一个CN,命名为CCN(Central CN),进行语句队列的治理。对于每个查问SQL,CN在生成完执行打算后,为每个物化算子调配适合的内存,同时计算整个语句内存使用量,并将语句及对应的内存使用量发给CCN。CCN保护零碎可用的内存值,对于新来的语句,如果语句内存使用量小于可用内存值,则容许其下发到DN执行,否则挂起,等到有语句完结开释内存后再次将其唤醒,是否能够下发。
为了达到上述目标,SQL引擎实现了内存自适应控制技术,步骤如下:
(1)对于每个SQL,生成打算前首先从资源管理模块获取零碎以后的最大可用内存(Query Max Mem)和以后可用内存(System Available Mem)。最大可用内存通常为每个DN的最大可用内存去除零碎预分配内存,例如:数据缓存等,示意语句可用的最大内存,如果语句应用内存超过该值,必须下盘。以后可用内存用于示意以后零碎的忙碌水平,如果以后可用内存比拟小,偏向于抉择消耗内存少的打算。
(2)根据以后可用内存生成打算,同时依据SQL引擎优化器打算生成过程中的cost估算值估算每个物化算子的内存使用量,以及流水线场景下整个查问应用的内存总量估算值。如果该值大于以后可用内存,则尝试将整个查问的内存使用量调到以后可用内存以下,此时会造成局部算子下盘。
(3)将语句及估算的语句内存发送到CCN,如果以后可用内存小于语句估算内存,则估算语句的内存进一步缩小是否对查问性能造成较大的影响,如果依据cost评估影响不大,则进一步缩小算子的内存应用,使语句内存应用满足以后可用内存,将语句下发执行,否则则进入排队状态。
(4)因为每个算子的内存使用量是基于cost评估取得,可能存在肯定的误差。因而,在SQL语句执行时,反对内存的动静调整,包含:执行算子内存的主动扩大和提前下盘。当算子达到估算的内存值下限,但零碎还有拮据的内存时,会进行算子内存的扩大,持续放弃不下盘的状态。当零碎已用内存达到80%或更高时,如果算子已有最小内存保障,则会触发提前下盘逻辑,保障不会因为内存不足而报错。
4.GaussDB内存自适应的应用和参数管制
通过开启use_workload_manager和enable_dynamic_workload两个参数开启GaussDB for DWS的内存自适应控制机制。
应用内存自适应机制时,打印SQL语句的explain performance执行打算运行信息时,会蕴含以下额定的信息辅助定位问题:
(1)在最下方的Query Summary一栏中,会显示出System available mem、Query max mem和Query estimated mem,别离示意:零碎以后可用内存、语句可用最大内存(零碎可用最大内存),语句估算内存使用量,均为单DN的掂量值。下图示意以后语句的语句最大可用内存和零碎以后可用内存均为22G,语句估算内存应用为1.6G。
(2)在Memory Information一栏,会显示CN和每个DN的内存应用峰值,如下图所示,语句理论内存应用,单DN应用16GB,CN应用76MB。
(3)在Memory Information一栏下方每个算子对应的地位,会显示每个算子单DN的内存峰值,同时会显示每个DN上内存应用的主动扩大和提前下盘状况,例如下图,能够看出第15号HashJoin算子,每个SMP线程的内存应用均为3.8GB,估算内存是860MB,经验了五次内存主动扩大,在第五次扩大后,零碎内存告急,算子未用到第五次扩大后的峰值即提前下盘。
(4)在explain performance最顶层的表格中,汇总了每个算子的估算内存和理论应用内存的状况,见下图的E-memory和Peak Memory两列所示。与下面信息对应,第15号算子单SMP线程的peak memory,最大值为3766MB,最小值为3753MB,估算内存值(单DN4个SMP线程)为860MB。
能够看出,下面例子因为cost估算不准导致内存估算值较小,理论场景也会呈现内存估算值较大的场景,会导致CCN预留内存较多,阻塞其它作业的执行。因而,能够应用参数query_mem来管制语句最大可用内存下限(单DN),相当于代替了Query max mem。此参数默认为0,示意未开启。当此值大于32MB(最小语句内存调配值)时,示意开启,此时应用work_mem控制系统以后可用内存进行估算,相当于代替了System available mem进行估算。此时,CCN会应用query_mem值进行语句内存估算值的预留和排队,进步并发场景下的内存应用效率。
5.总结
内存自适应控制技术是GaussDB for DWS的资源管理联合SQL引擎所做的一次尝试,当然还存在一些有余,比方:cost估算对内存的评估影响较大,局部场景存在失真须要进行参数管制;零碎中内存应用状况比较复杂,还存在局部内存不在管控范畴内须要加强。欢送各位在实用过程中,将遇到的各种问题及时反馈,也帮忙咱们更好的改良!
点击关注,第一工夫理解华为云陈腐技术~