乐趣区

GaussDB-for-DWS内存自适应控制技术总结

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 估算对内存的评估影响较大,局部场景存在失真须要进行参数管制;零碎中内存应用状况比较复杂,还存在局部内存不在管控范畴内须要加强。欢送各位在实用过程中,将遇到的各种问题及时反馈,也帮忙咱们更好的改良!

点击关注,第一工夫理解华为云陈腐技术~

退出移动版