Apache Doris 支持基于资源标签(Resource Tag)和工作负载组(Workload Group)的工作负载隔离功能。它提供了在隔离级别、资源利用率和稳定性能之间进行权衡的解决方案,以适应不同的权衡点。
这是对Apache Doris的工作负载隔离能力的详细介绍。首先,你什么时候需要进行工作负载隔离?如果你遇到以下任何一种情况,请继续阅读,你将找到解决办法:
- 您有不同业务部门或租户共享同一个集群,并希望防止不同部门或租户之间的工作负载相互干扰。
- 您有不同优先级的任务,并希望优先为关键任务(如实时数据分析和在线交易)分配资源和执行权。
- 您需要工作负载隔离,但同时也希望保持高成本效益和资源利用率。
Apache Doris 支持基于资源标签和工作负载组的工作负载隔离。可以将不同工作负载的 CPU 和内存资源在后端节点层面进行隔离,而工作负载组机制可以进一步在后端节点内划分资源,提高资源使用效率。
基于资源标签的资源隔离技术让我们从 Apache Doris 的架构开始。关于 Doris 的两种节点类型,可以参见 Apache Doris 官方文档:前端(FE)和后端(BE)。FE 节点负责存储元数据,管理集群,处理用户请求以及解析查询计划,而 BE 节点则负责计算任务和数据存储。因此,可以说 BE 节点是主要的资源消耗者。
基于资源标签隔离方案的主要思想是通过给集群中的 BE 节点分配标签来划分计算资源,具有相同标签的 BE 节点将形成一个资源组。资源组可以当作存储和计算数据的单元。对于输入到 Doris 的数据来说,系统将根据配置,把数据副本写入不同的资源组。查询也将被分配到相应的资源组执行。
例如,如果你想在一个由3个BE组成的集群中将读和写的工作负载分开,你可以按照以下步骤来做:
- 将资源标签分配给BE:将2个BE分配到“读”标签,1个BE分配到“写”标签。
- 将资源标签分配给数据副本:假设表1有3个副本,将其中2个分配到“读”标签,1个分配到“写”标签。写入到副本3的数据将被同步到副本1和副本2,此同步过程消耗较少的BE1和BE2资源。
- 将工作负载分配给资源标签:SQL中包含“读”标签的查询将自动路由到标记为“读”的节点(在这种情况下,即为BE1和BE2)。对于数据写入任务,还需要将它们分配到“写”标签,以便可以路由到相应的节点(BE3)。这样,读写工作负载之间就不会出现资源争用,除了从副本3到副本1和副本2的数据同步开销。
资源标签还实现了多租户支持在 Apache Doris 中。例如,标记为“用户 A”的计算和存储资源仅供用户 A 使用,而标记为“用户 B”的计算和存储资源则仅供用户 B 使用。这就是 Doris 如何通过资源标签实现多租户资源隔离在 BE 端。
将BE节点(即业务节点)分组能够实现高度的隔离。
- 不同租户的CPU、内存和I/O是物理隔离的。
- 一个租户的故障(如进程崩溃)绝不会影响到另一个租户。
但它也有一些缺点:
- 在读写分离中,一旦数据写入停止,标记为‘写’的BE节点就会闲置,从而降低了整体集群利用率。
- 在多租户场景下,如果你想通过为同一租户的不同工作负载分配单独的BE节点来进一步隔离它们,你将不得不承担高成本并面对低资源利用率。
- 租户数量与数据副本数量相关联。例如,若有5个租户,则需5个数据副本,这将造成巨大的存储冗余。
为了进一步改进这一点,我们在 Apache Doris 2.0.0 中提供了一个基于工作负载组的隔离解决方案,并在 Apache Doris 2.1.0 中进行了进一步增强。
基于工作负载组,隔离工作负载基于Workload Group的解决方案实现了更细致的资源划分。它进一步在BE节点的进程中对CPU和内存资源进行细分,这意味着一个BE节点内的查询可以在一定程度上相互独立。这避免了BE进程中资源的竞争问题,并优化了资源的利用效率。
用户可以将查询关联至工作负载组,并因此限制查询可以使用的 CPU 和内存资源的百分比。在集群负载较高时,Doris 可以自动杀死工作负载组中资源消耗最大的查询。在集群负载较低的时候,Doris 可以允许多个工作负载组共享空闲资源。
Doris 支持 CPU 软限制和硬限制。软限制允许工作负载组在必要时突破限制,利用闲置资源,实现更高效的资源使用。而硬限制则防止工作负载组之间的相互干扰,确保稳定性能。
(CPU软限制和硬限制是相互矛盾的。您可以根据自己的需求选择其中一个。)
它和基于资源标签的解决方案相比,不同之处在于:
- 工作负载组是在进程内创建的。同一BE节点内的多个工作负载组会相互竞争资源。
- 因为工作负载组只是资源管理的一种手段,所以不涉及数据副本的分布。
CPU软限制是通过设置cpu_share
参数实现的,这个参数的概念与权重类似。在每个时间槽内,具有更高cpu_share
值的工作负载组将被分配更多CPU时间。
例如,如果组 A 设置了 cpu_share
为 1,而组 B 为 9,在 10 秒内,当两组都处于满载状态时,组 A 和组 B 将分别占用 1 秒和 9 秒的 CPU 时间。
在软限制的情况下,如果组B的工作负载较低或为零,集群中的工作负载并不总是满负荷运行。那么组A将能够使用全部的CPU时间,从而提高整个集群的CPU利用率。
软限制(soft limit)带来了灵活性和更高的资源使用效率,但另一方面,它可能会导致性能的不稳定。
CPU硬性限制Apache Doris 2.1.0的CPU硬限制功能是为需要稳定性能的用户设计的。简单来说,CPU硬限制规定工作负载组不能使用超出其限定的CPU资源,无论是否有未使用的CPU资源。
这是它的运作方式:
假设组 A 设置为 cpu_hard_limit=10%
,而组 B 设置为 cpu_hard_limit=90%
。如果组 A 和组 B 都达到最大负载,那么它们将分别使用 10% 和 90% 的总 CPU 时间。区别在于一旦组 B 的工作负载减少,在这种情形下,不管组 A 的负载有多高,它不应该使用超过分配给它的 10% 的 CPU 资源。
与软限制相比,硬限制确保系统稳定,但牺牲了灵活性,可能降低资源利用率。
内存限制BE节点的内存组成包括以下部分:
操作系统预留的内存。
非查询占用的内存,这部分内存不被工作负载组的内存统计所包含。
查询占用的内存,包括写入数据。这部分可以由工作负载组跟踪和管理。
memory_limit
参数定义了 BE 进程内工作负载组可用的最大 (%) 百分比 内存。它还影响资源组优先级。
在初始情况下,高优先级的资源组会获得更多的内存分配。通过设置 enable_memory_overcommit
,你可以允许资源组在如果有闲置空间的情况下占用超出限制的内存。内存紧张时,Doris 会取消任务来回收它们占用的内存。在这种情况下,系统会尽可能保留高优先级资源组的内存。
查询等待队列
这个集群现在承担的任务超出了它的处理能力。在这种情况下,提交新的查询请求不仅没有效果,还会中断正在进行的查询请求。
为了更好地优化这一点,Apache Doris 提供了 查询排队 机制。用户可以设置并发查询的数量限制。当查询排队已满或等待超时后,查询会被拒绝,从而确保系统在高负载下的稳定性。
查询队列机制涉及到三个参数:最大并发数
,最大队列大小
和 队列超时
。
为了展示CPU软上限和硬上限的效果,我们进行了一些测试。
- 环境设置:一台机器,16核,64GB
- 部署方式:1个FE + 1个BE
- 数据集:ClickBench,TPC-H
- 负载测试工具:使用Apache JMeter
启动两个客户端程序,并分别持续提交查询请求(ClickBench Q23),一个使用工作负载组,另一个则不使用。请注意应禁用页面缓存以防止它影响测试结果。
从这两次测试中比较这两个客户端的数据吞吐量,我们可以看出:
- 未配置工作负载组时,两个客户端会平均使用CPU资源。
- 配置工作负载组,并将
cpu_share
设置为2:1,两个客户端的吞吐量比是2:1。较高的cpu_share
值能给客户端1分配更多的CPU资源,因此其吞吐量也会更高。
启动客户端,将工作负载组的 cpu_hard_limit
设置为 50%
,并在并发级别分别为 1、2 和 4 的情况下,运行 ClickBench Q23 5 分钟。
随着查询并发量的增加,CPU利用率保持在大约80%,这意味着使用了8个核心中的一个。在一个16核的机器上,这是50%的利用率,这是可以预期的。此外,由于施加了CPU硬限制,随着并发量的增加,TP99延迟的增加也是预料之中的。
生产环境模拟测试在实际使用中,用户特别在意查询延迟而不仅仅是查询吞吐量的多少,因为延迟更易于在用户体验中的感知。这就是为什么我们决定在一个模拟生产环境中测试工作负载组的表现。
我们挑选了一组SQL查询,这些查询应在1秒内完成(例如ClickBench Q15, Q17, Q23 和 TPC-H Q3, Q7, Q19),包括单表聚合和连接查询等。TPC-H数据集大小为100GB。
同样,我们也会测试配置和未配置工作负载组的情况。
结果显示:
- 未配置工作负载组(比较测试1和测试2):当增加客户端2的并发量时,两个客户端的查询延迟增加到原来的2到3倍。
- 配置工作负载组(比较测试3和测试4):随着客户端2并发量的增加,客户端1的性能波动明显减小,这证明了其通过工作负载隔离得到了有效隔离保护。
基于资源标签的解决方案是一个全面的工作负载隔离方案。基于工作负载组的解决方案实现了资源隔离与利用率之间的更好平衡,并通过查询队列机制来确保稳定性。
那你要选哪个呢?我们给你一些建议如下:
- 资源标签:用于部门的不同业务线共享同一个集群的情况,因此资源和数据在物理上为不同的租户隔离。
- 工作负载组:用于一个集群需要处理多种查询工作负载的情况,从而实现灵活的资源分配。
在未来的版本中,我们将不断优化工作负载组和查询队列的用户体验。
- 通过取消查询来释放内存是一种激进的方法。我们计划通过磁盘溢出实现这一点,这将带来更高的查询性能稳定性。这样修改后,句子更加连贯,符合中文表达习惯。
- 由于BE中非查询所消耗的内存未包含在工作负载组的内存统计中,用户可能会观察到BE进程内存使用量与工作负载组内存使用量之间的差异。我们将解决这个问题,以避免用户感到困惑。
- 在查询队列机制中,集群负载通过设置最大查询并发度来控制。我们计划根据BE可用资源动态调整最大查询并发度。这样可以在客户端持续提交高负载时,对客户端施加后向压力,从而提高Doris的可用性。
- 资源标签的主要思想是将BE节点进行分组,而工作负载组则是进一步细分单个BE节点的资源。为了使用户掌握这些概念,他们需要首先了解Doris中的BE节点的概念。但从操作的角度来看,用户只需关注每个工作负载的资源消耗比例,以及在集群负载饱和时的优先级。因此,我们将尝试找到一种方法来降低用户的上手难度,例如,将BE节点的概念隐藏起来。
如需更多关于Apache Doris隔离工作负载的帮助,请加入我们Apache Doris社区。
共同学习,写下你的评论
评论加载中...
作者其他优质文章