资源隔离不停是 StarRocks 用户讨论较多的话题,对于资源隔离的诉求,紧张集中在四点:
1. 许多用户关注资源的隔离性,盼望当有焦点业务的查询运行时,可以限定其他类型使命的利用资源,进而保障焦点业务的相应时间。
2. 及时熔断大查询,避免其浪费许多资源后才失败。
3. 限定各个租户之间以及一个租户内各种类型使命的 CPU / IO /内存等资源,将这些类型使命的资源隔脱离。
4. 许多用户也关注资源的利用率,盼望当有多种类型的工作负载在同一个集群运行时可以具有肯定的隔离性。并且当某些资源组空闲时,其他正在运行的资源组可以弹性地利用这部分资源。
总的来说,用户盼望我们能够提供资源隔离的功能来合理地控制 CPU / IO / 内存等资源,既要能够实现多租户的资源隔离,也要能够充实利用资源,让不同的负载工作在同一个集群上,来降低集群的管理成本。
除此以外,资源隔离功能也可以为未来的 Serverless 化提供支持。由于相比于增加节点数目的 SQL out 模式,提高单个节点资源的 SQL up 模式可以做到更加快速的秒级以内的弹性。但是 SQL up 模式会导致多个租户共享同一个集群,所以资源隔离是此中关键的技术。
如安在保证资源隔离的前提下提高资源的利用率,是资源隔离的关键点和挑战:如果没有资源隔离,那么集群会具有良好的资源利用率,但是会完全没有隔离性;而如果完全举行物理隔离,会具有良好的隔离性,但是弹性会显着不足。
所以我们选择在用户态来实现调度策略,举行逻辑上的隔离。
#01 资源隔离的现有本事
如今我们提供了两个方面的资源隔离本事:一方面是资源的隔离,另外一方面是资源的限定。
对于资源的隔离,我们提供了内存资源的硬隔离、CPU 资源和 IO 资源的软隔离以及短查询资源组对于 CPU 和 IO 资源的硬隔离。
对于资源的限定,我们提供了并发资源的限定以及大查询的熔断控制。
1.1 界说资源组
在实行各类资源隔离的功能之前,需要先明确如何去界说不同租户之间以及一个租户内不同类型的工作负载的资源隔离。在这里我们抽象出了资源组的概念,下图是一个资源组,可以界说各类资源的配额,并且绑定多个分类器。利用分类器就可以将不同租户以及一个租户内不同的工作负载匹配到不同的资源组。
1.2 查询分类
查询分类是基于用户、脚色、IP 等特点举行的,具体来说,一个分类器可以提供如下五个条件中的恣意一个,包括用户、用户所属脚色、SQL 类型、发起查询的 IP 以及查询访问的数据库。此中 SQL 类型如今只支持 select 语句,即查询,对于导入等使命类型的支持也正在逐步开发中。当发起一个查询后,大概会有多个资源组的分类器满意条件,这个时间就需要从多个满意条件的分类器中选择最符合的一个。这里紧张分为三步:
首先,优先选择有 DB 条件的分类器,如果有n个或者0个有 DB 条件的分类器,则会优先选择条件数目最多的分类器。如果有多个条件数目相等的分类器,则会选择条件最准确的分类器。
以上图为例,分类器A到D的优先级会渐渐升高,此中它们是否有 DB 条件、条件的数目、条件的准确程度都有所不同。
在界说了资源组和分类器以后,就可以实行各项资源隔离的功能了。
1.3 内存资源的硬隔离
内存资源的硬隔离,即一个资源组只能利用 memory limit 的内存资源。当该资源组利用的内存资源超限以后,那么该资源组内的查询会返回失败的状态。
1.4 CPU 资源的软隔离
CPU 资源的软隔离会将全部正在运行的资源组按照 cpu_core_limit 的比例来分配 CPU 时间片。
以下图为例,三个资源组会按照1:3:4的比例来利用全部16核的 CPU 资源,即从逻辑上会分别分配到2核、6核和8核的 CPU ,并且当资源空闲时,正在运行的资源组可以弹性利用更多的资源。当第一个调度周期结束以后,第三个资源组的全部使命都已经完成了,所以在接下来的调度周期2和3中,其他的资源组1和2就可以利用全部的 CPU 资源了,也就是每个周期可以分配到更多的时间片。
1.5 短查询资源组与 CPU 资源的硬隔离
CPU 资源的软隔离的方式会存在少量的调度延时,所以对于高优先级的点查这一类对调度延迟很敏感的非常的场景,我们提供了短查询资源组的功能。当有短查询资源组的查询时,会为其保留 cpu_core_limit 的 CPU 资源,其他资源组只能利用剩余的 CPU 资源。
以下图为例:在第一个调度周期中,资源组1和2的 CPU 资源已经达到利用上限,所以即使短查询资源组的全部使命都处于阻塞状态,没有可以运行的使命,也不能去调度资源组 1 和 2 的使命去执行。而当第一个调度周期结束以后,短查询资源组的全部使命都完成了,所以在接下来的调度周期 2 和 3 中,其他的资源组 1 和 2 不再有对于 CPU 资源的硬限定,也就是可以利用全部的 CPU 资源了。
1.6 IO 资源的软隔离与短查询资源组的硬隔离
对于 IO 资源的隔离策略也分为两个方面:
一方面,每个资源组会按照 cpu_core_limit 的比例来分配 IO 时间片。
另一方面,当有短查询资源组的查询时,也会为其预留cpu_core_limit 的 IO 资源。
从这两方面,我们提供了对于 CPU 资源和 IO 资源的隔离。但是如果在同一时刻涌入了过多的查询,也会导致集群的资源过载。因此,我们也提供了并发资源的硬限定功能。
1.7 并发资源的硬限定
并发资源的硬限定,即一个查询只能同时处理 concurrency_limit 的并发请求,如果发起的请求数目高出了该阈值,会直接返回失败的状态。在后续版本中,会支持实时查询使命列队的功能,来避免直接返回失败的状态。
1.8 大查询的熔断控制
当一个查询利用的 CPU 时间、IO 扫描的行数以及内存资源高出阈值时,大查询会直接被熔断,返回失败的状态。
以上就是对于资源组合分类器的界说以及各类资源隔离的功能。总的来说,对于利用资源隔离,首先要创建资源组和分类器,来指定各类的资源配额,并且指定匹配的租户以及工作负载类型。当发起一个查询后,会根据分类器来匹配到最符合的资源组,每个节点会按照资源组的资源配额来调度 CPU 和 IO 资源,并且限定内存和并发资源,同时检查是否需要熔断。
#02 资源隔离的实际结果
对于资源隔离的实际结果,我们紧张举行了三个方面的测试,分别是不同资源组运行类似负载的测试、巨细查询的测试、短查询资源组的测试。
2.1 不同资源组运行类似负载的测试
我们利用了两个资源组,其 cpu_core_limit 之比为 2:1,每个资源组各自4并发运行类似的查询。我们盼望两个资源组的 QPS 之比为2:1,来阐明它们按照比例利用了资源。
下面图中是 SSB 100GB 的测试结果,可以看到每一个查询的 QPS 都符合了2:1的比例。
接下来是TBC-DS 100GB 前20个 query 的测试结果,每一个查询也根本符合了2:1的 QPS 比例,这阐明对于不同资源组运行类似负载的测试,两个资源组可以按照比例利用资源将资源隔脱离。
2.2 巨细查询的测试
在实际利用中,巨细查询混淆的工作负载模式会更加常见。所以我们也举行了这一类的测试。
本次仍旧利用两个资源组,其 cpu_core_limit 之比为 2:1,第一个资源组运行8并发的小查询,第二个资源组运行4并发的大查询。我们盼望与大查询混跑的小查询的 QPS 与单独跑的 QPS 之比为2:3,来阐明该资源组利用了2/3的资源,没有受到另外一个资源组的大查询的影响。此中对于小查询和大查询,我们都提供了各种类型的查询举行测试。
下图是第一个小查询的测试结果,此中黄色的折线是关闭资源组的测试结果,蓝色的折线是打开资源组的测试结果。而在两条虚线中心的部分是与大查询混跑的小查询的 QPS ,可以看到混跑的小查询的 QPS 与单跑的小查询的 QPS 之比符合2:3的比例。
接下来是第二个小查询的测试结果,可以看到也根本符合2:3的比例。这阐明对于巨细查询的测试,运行小查询的资源组没有受到另外一个运行大查询资源组的影响,可以将资源隔脱离。
2.3 段查询资源组的测试
对于高优先级的很短的点查询,我们提供了短查询资源组的功能,并且举行了相应的测试。
短查询资源组与另外一个资源组的 cpu_core_limit 之比为 3:1,短查询资源组运行8并发的点查询,另外一个资源组运行4并发的大查询。我们盼望与大查询混跑的点查的 QPS 与单独跑的 QPS 之比为3:4,来阐明短查询资源组利用了3/4的资源。
下图是具体的测试结果:与大查询混跑的点查的 QPS 与单独跑的 QPS 之比根本符合3:4的比例,这阐明可以为短查询资源组预留3/4的资源。
#03 资源隔离的工作原理
下图是资源隔离的整体架构,当发起一个查询用后,会根据分类器绑定符合的资源组,然后将查询拆分为多个执行单元的使命,分发给各个 BE 节点。每一个 BE 节点会根据对应资源组的资源配额来调度 CPU 和 IO 使命,并且限定内存和并发资源,同时检查是否需要熔断、大查询。
3.1 内存资源的硬限定
对于内存资源的硬限定,复用了 StarRocks 已经提供的对于内存资源统计和检查的功能,利用 TCmalloc 的 Hook 在申请和开释内存时对内存举行统计和检查,在每一个线程运行时会绑定一个 Memory Tracker 到一个 Thread Local 变量。这个 Memory Tracker 就是用来纪录和检查内存的,它是一个多级的树布局。此中对于资源隔离来说,会添加每一个资源组的 Memory Track 到树形布局中。
3.2 CPU 和 IO 资源的软隔离
对于 CPU 和 IO 资源的软隔离是基于 StarRocks 的 pipeline 执行引擎实现的:pipeline 执行引擎会将全部查询的执行单元的使命在用户态举行调度。
具体来说会有核数个执行线程以及一个查询单元使命的就绪队列。每一个执行线程会从就绪队列中取出符合的使命来执行,并且正在执行的使命会由于时间耗尽或者其他调度因素的影响,及时的让出执行线程并且放回就绪队列,执行校验程再从就绪队列中取出下一个符合的使命来执行。
pipeline 执行引擎会将全部查询的执行单元使命在用户态举行调度,因此可以很方便地实行各种不同的调度策略。而当没有资源隔离时,全部使命是通过多级反馈队列举行调度的。
当有资源隔离以后,会利用一个两级的队列举行调度,这里与 Linux 进程的完全公平调度算法类似:第一级是资源组的优先级队列,第二级是每个资源组内部的多级反馈队列。每次执行线程在选择符合的使命执行时,会选择当前 Vruntime 最小的资源组的使命来执行,Vruntime 就是将 CPU 执行时间或者 IO 执行时间除以 cpu_core_limit 得到的。
通过这种方式可以保证全部资源组按照 cpu_core_limit 的比例来利用 CPU 和 IO 资源。同时为了尽量减小调度延迟,我们会不断地检查当前正在执行使命的 Vruntime 是否还是最小的,如果它不再是最小的,会及时让出 CPU 或者 IO 资源。为了避免频繁地更换使命,会保证一个使命至少执行 5 毫秒之后才让出。
此外,如果一个好久没有使命的资源组再次有使命到来时,由于其他的资源组不停在运行,它们的 Vruntime 在持续增加,所以这个资源组的 Vruntime 会相对小许多。为了避免不停调度它的使命去执行,导致其他资源组饥饿,所以会调解它的 Vruntime 为当前最小的资源组的 Vruntime ,并且减去一个常量作为它的嘉奖。
3.3 短查询资源组与 CPU 和 IO 资源的硬隔离
同样,针对高优先级的很短的点查询,我们提供了短查询资源组的功能。
当有短查询资源组的使命时,别的的资源组在每个周期只能利用 hard limit 的资源。如果在一个周期内它们利用的资源高出了该阈值上限,则本周期不会再调度它们的使命去执行。
但是在同一时刻大概会有多个这些资源组的使命在执行,所以当发现资源超限时,它们的资源用量大概已经高出许多了。因此,我们添加了惩罚策略来保证在总体上,对于这些资源组的硬隔离:如果在本周期,它们的资源用量在一倍 hard limit 到两倍 hard limit 之间,那么会将它的下一个周期的资源用量初始值赋值为当前用量减去 hard limit ,也就是在下个周期可以利用少量的资源。而如果当前用量在两倍 hard limit 以上,那么会将它下个周期的资源用量初始值赋值为 hard limit ,即下个周期无法调度它们的使命去执行。
#04 未来规划
总的来说,利用资源隔离,我们首先要界说资源组和分类器来指定各类资源的配额,并且指定匹配的租户以及工作负载类型。当发起一个查询后,会根据分类器匹共同适的资源组,根据对应资源组的配额对 CPU 资源和 IO 资源举行软隔离,并且当有短查询资源组的使命存在时,会对 CPU 和 IO 资源举行硬隔离,同时会限定内存和并发资源,并且检查是否需要熔断大查询。
当前,我们正在开发使命列队机制以及 Spill 机制,来避免在并发资源或者内存资源超限时导致查询失败;同时也筹划支持更多的负载类型,逐步支持数据库分析导入和 Compaction ,并且也筹划增加多个短查询资源组,来满意更多的用户场景。
-关于StarRocks
StarRocks 是数据分析新范式的开创者、新标准的领导者。面世三年来,StarRocks 不停专注打造世界顶级的新一代极速全场景 MPP 数据库,帮助企业创建“极速统一”的湖仓新范式,是实现数字化转型和降本增效的关键根本办法。
StarRocks 持续突破既有框架,以技术创新全面驱动用户业务发展。当前全球高出 200 家市值 70 亿元以上的头部企业都在基于 StarRocks 构建新一代数据分析本事,包括腾讯、携程、平安银行、中原银行、中信建投、招商证券、众安保险、大润发、百草味、顺丰、京东物流、TCL、OPPO 等,并与全球云计算领导者亚马逊云、阿里云、腾讯云等告竣战略合作同伴。
拥抱开源,StarRocks 全球开源社区飞速发展。停止 2022 年底,已有高出 200 位贡献者,社群用户近万人,吸引几十家国内生手业头部企业参与共建。项目在 GitHub 星数已超 3800 个,成为年度开源热力值增速第一的项目,市场渗透率跻身中国前十名。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |