引言
在云环境中租户之间的资源共享对于运营商的成本效益来说非常重要,但是一个主要问题是租户之间的资源隔离,这通常与Qos息息相关,从多租户的角度讲,安全性/性能与成本其实是互相矛盾的,[1]中提到:
• Degree of consolidation: The higher up in the stack virtualization is supported, the greater the degree of consolidation
achievable, leading to lower cost for the service provider.
• Degree of isolation: The lower down in the stack the virtualization logic is supported, the greater is the security and
performance isolation achievable across tenants.
所以核心要解决的问题是:在云环境Serverless的环境中,运营商如何在保证成本效益的情况下向用户提供一系列有意义的保障。
租户隔离其实可以理解为租户间的资源隔离,就这个角度讲,租户隔离需要在以下要点之间做trade-off:
- 绝对的资源保障,即提供给用户的资源与购买时相比是
任意时刻满足
还是周期内近似满足
- 不对用户实际运行的工作负载做假设,即
用户的查询可能在Mem/磁盘IO/网络IO/CPU任意维度先过载
- 满足用户
弹性扩容
和物理隔离
的需求 - 运营商成本效益,即单独的机器在近似满足其他约束的情况下尽可能多的放置租户,但是当资源被过度使用时,一个节点有可能没有足够的资源来满足其上所有数据库的资源需求,此时需要迁移或者扩容。
从公有云的定价策略来看,目前大体可以分为两种:
- 存储量+RU(某些模态可以是扫描的数据量)
- 存储+实例+其他
用户使用第一种(serverless)的初衷是为了省钱,为了扎实的价格竞争力在计算侧做资源级别的隔离是一个好的选择,因为这个时候计算层也可以选择大池子超卖。但是此时就会有超卖后不满足用户要求的情况出现。
用户使用第二种按照实例购买时,单独分配计算节点,存储节点依旧按照partition级别做隔离。而且当存算分离时存储节点基本上不会有CPU瓶颈,瓶颈基本集中在IO,而IO的基准线经测试是基本线性,此时多租户隔离很好做,因为在引擎层面工作负载的问题基本已经压缩到IO了,不需要大刀阔斧改引擎
计算侧多租户隔离
但是计算侧为了足够的成本效益仍旧需要放置多个租户在一台机器上,此时有这么几种方法。
2DFQ
应用场景为系统运行一组工作线程,工作线程从租户队列中选择下一个执行的请求,公平队列可以做到工作线程取任务执行的过程为每个租户提供公平的份额,且为不同租户服务时调度器不是突发的。
相对于一般的公平队列,2DFQ优势是The goal of Two-Dimensional Fair Queueing (2DFQ) is to produce smooth schedules for tenants with small requests.
但是正因为2DFQ是WFQ的变种,所以其计算时认为请求消耗的资源大小是像数据包大小一样可预测的,其实这很难做到,目前可行的方法是按照关系型数据库中SQL优化层中Cardinality estimation(不是count distinct的那个)的做法采样做预估。
设计挑战如下:
- 资源并发性
- 不同租户和不同API的请求对资源的需求可以达到1000倍(每一个请求在不同的线程中有不同的资格,小请求)
- 存在一个请求的资源需求和执行时间是不确定的(悲观估计策略)
2DFQ一篇论文其实就一段有用:
SQLVM
应用于单进程中多租户的性能隔离方案。这篇文章提出了在DBMS中内嵌一个VM,这个VM提供了资源最小使用粒度的reservation,并引入新的资源调度机制,以保证每个租户的资源reservations,最后在服务提供方无法满足约束时记录事件,后续补偿用户。
本质上仍然是在OS层面之上,即用户态中新增了一个资源调度层,以满足不同租户间的资源最低使用限度。文中只提到了IO调度的实际方法,[6]中提到了CPU的隔离方法,但是内存隔离没有提及。
但是其实方法是通用的,类似的方案可以在TiFlash中看到[8]。
其次SQLVM的做法其实是硬性限定了租户的资源使用上限,即最多就是reservations的值,不能多一点点,这对于突发请求防御性较差
Retro
这篇文章阐述的框架与Dynamo的RU控制框架较为类似。retro将机器上的组件抽象为控制流(每一个租户一个控制流),资源(执行资源的精确统计)和控制点(控制节点实际执行限流的措施,文中提到令牌桶)。一个控制节点提供一组API接受控制流的上报,执行BFAIR/RDRF/LATENCYSLO策略,决策控制点实际的限流策略。所以从隔离来讲其实还是基于限流点做,文中提到资源限制可以通过限制用户的吞吐来做(4.3节)。
但是Retro对于资源的态度与Dynamo也不一样。Dynamo是给每个租户分配一个配额,希望在周期内只使用这么多(不考虑burst),但是Retro对资源始终有一种探索上界的过程(BFAIR/RDRF),知道发现某个租户导致过载,则会减少资源需求,实际由控制点控制,这样可以让租户实际使用更多的资源。
(题外话:BFAIR/RDRF两种策略与我最近设计的两个算法莫名的相似。。。。)
其他隔离方法
类似Redis慢查询隔离和HTAP负载隔离解决方法其实是完全不同的解决思路,都是很简单的思路,难点在于工业实现上,本文不再阐述。
其他
二十三岁的九局下半
参考:
- Multi-Tenant Cloud Data Services: State-of-the-Art, Challenges and Opportunities
- Tenant Placement in Oversubscribed Database-as-a-Service Clusters
- SQLVM: Performance Isolation in Multi-Tenant Relational Database-as-a-Service
- Retro: Targeted Resource Management in Multi-tenant Distributed Systems
- 2DFQ: Two-Dimensional Fair Queueing for Multi-Tenant Cloud Services
- CPU Sharing Techniques for Performance Isolation in Multi-tenant Relational Database-as-a-Service
- 数据库内核那些事|PolarDB HTAP如何实现行列混存(IMCI)查询优化?
- TiDB 6.5 新特性解析丨过去一年,我们是如何让 TiFlash 高效又稳定地榨干 CPU?
- 为什么资源隔离对HTAP至关重要?
- OceanBase文档 租户间的资源隔离