在分布式服务中,一个业务的单个节点性能不能满足需求,需要很多节点同时工作来满足性能和高可靠需求。例如:网络的SLB服务(负载均衡),即使是超大规格的ECS(虚拟机),单个ECS的吞吐量只有不到50G,整个公有云有成千上万的租户,加起来的吞吐量需求是以T为单位的,这就需要大量的ECS来满足超大吞吐量需求。
在实际的公有云运营中,公有云这样的多租户系统在租户之间共享资源,这意味着一个租户的活动可能会对另一个租户对系统的使用产生负面影响。这就是noisy neighbour(坏邻居)问题。
多租户相互影响会带来什么问题
当构建要由多个租户共享的服务时,通常构建为多租户系统,例如公有云。多租户系统的一个好处是资源可以在租户之间集中和共享。这通常会降低成本并提高效率。但是,如果单个租户使用了系统中不成比例的可用资源,则系统的整体性能可能会受到影响。当一个租户的性能由于另一个租户的活动而下降时,就会出现noisy neighbour(坏邻居)问题。
假设一个只有两个租户的多租户系统。租户 A 的使用模式和租户 B 的使用模式重合,这意味着在高峰时间,总资源使用率高于系统的总容量。这时,先到达的租户A的请求将优先得到处理,然后另一个租户B的请求因为超过了系统的处理能力,将得不到响应,租户B的业务就受到了遇到noisy neighbour的影响。
那怎么才能做到多个租户不要相互影响呢?一般的做法是为所有租户都预留好足够的资源。这个方案的确可以解决多个租户相互影响的问题,但业务流量是时刻变化的,并不总是处于峰值,大多数时间,业务流量都在系统的承载范围内,按峰值需求预留大量资源,会导致大量的资源在非峰值时间被闲置、浪费,同时,成本也无法接受。
那有没有一种可以兼顾到成本,同时又能做到租户不相互影响的方案呢?
一种解决方案
AWS的HyperPlane架构中给出了一个解决方案——shuffle sharding
AWS HyperPlane 是AWS的一个内部服务,它支撑了NAT、PrivateLink、LoadBalancer和 Elastic File System 等服务。它最早在2017年 AWS re:Invent 对外正式公布,但是从AWS公开的信息看,在2015年就已经开始在应用了。
HyperPlane具备以下优点:
- 独立的,最小化的错误域
- 通用的数据和控制面
- 连接不中断的高可用性
- 多租户之间互不影响
技术原理
从资源使用率的角度来看,HyperPlane不绑定特定的租户。但是另一方面,也就意味着HyperPlane需要被多个租户共享。怎么确保多个租户间互不影响是公有云需要解决的一个问题。
在一个共享的网络中,如果一个租户的网络流量很大,就像一个嘈杂的邻居(noisy neighbor)一样,必然会影响其他的租户。Hyperplane通过随机分片(Shuffle Sharding)来解决这个问题,整体算法思想比较简单。
假设有8个Hyperplane节点。最原始的想法是,对于每个网络连接都随机分配其中一个节点,那么每个网络连接有1/8的概率选中某个节点。如果有个租户的有多个连接,并且流量很大,这样会导致8个节点中每个节点的负担都很大,进而影响其他租户的体验。
一个改进方法是,将8个Hyperplane节点分成4片,每个租户随机选择一个分片,这样,如果一个租户流量很大,那么也只会影响1/4的租户。虽然不是很完美,但是比最开始已经好很多了。
可以更进一步,对分片算法做个改进,每个租户随机选择8个节点中的3个来使用,比如说橙色租户使用下面3个节点。
另外一个粉色租户随机使用3个节点。在下面的图里面,这两个租户在一个HyperPlane节点(第二行第二个)有重合。两个租户只有在场合的HyperPlane节点才有可能相互影响。
如果有8个Hyperplane节点,每个租户随机选3个。那么两个租户之间的重合概率如下图所示,分别是:18%的概率没有重合;54%概率有一个节点重合,就像上图一样;2%的概率全重合。只有在完全重合的时候,noisy neighbor租户才会完全影响到其他租户。所以现在,如果存在大流量的租户,只有2%的其他租户会受到影响。这比之前一种全局分片的想法又有了大大的提升,这里其实就是随机分片(Shuffle Sharding)的核心思想。
这里可能体现不出Shuffle Sharding的真正威力,如果把HyperPlane的池子变大,每个租户分配的节点数变多,可以得到更好的结果。在AWS的实际场景中,会有数百个Hyperplane节点,对于每个租户,会随机选择5个节点。这样算下来两个租户之间的重合概率如下图所示,分别是:77%概率完全不重合,21%概率重合一个;1.8%的概率,有两个节点会重合;两个租户完全重合的概率几乎为0。
在实际使用中,因为重合大于等于3个节点的可能性非常低,可以通过调度去掉这些情况,从而使得两个租户之间不会有超过2个节点重合。所以现在,如果有一些租户的流量非常大,这个租户对应的5个Hyperplane节点负担会非常重。在最坏的情况下,也只有2%的概率,其他租户会与这个租户有2个重合节点。没有租户会完全被这个noisy neighbor租户影响到,这又比之前好了很多。
AWS Hyperplane系统从设计上具备弹性能力,即使丢掉几个节点仍然可以正常工作。所以,在上面的最坏情况下,可以直接丢掉这2个重合节点。因为就算丢掉2个,其他3个节点的容量也足够承载租户的网络流量。通过这样的设计,即使多个租户跑在一套HyperPlane系统中,也可以做到完全互不影响。
总结和展望
使用多个节点组成的分布式系统为多租户提供服务,noisy neighbour(坏邻居)问题是一个绕不过去的坎。
咱们得物容器化其实也是在使用这样一个分布式系统。众多Node组成了一个Cluster,各个应用共享这个Cluster中的资源,有的应用在某一时刻资源占用会很多,这就会影响到同一Node上的其他应用,为避免相互影响,咱们现在建立了众多的Cluster,预留了大量资源,造成成本上升。为解决这个问题,AWS Hyperplane使用的Shuffle Sharding无疑提供了一种很好的思路。
*文/陆毅