自动负载均衡(Load balance)
背景
tablet是tera中管理数据的基本单位,所有的数据存取访问会落在tablet之上,通过预分表、split、merge等操作可以调整tablet所覆盖的数据范围,这样表格的逻辑结构得以确定。
当一个表格被分割为若干tablet之后,每个tablet中包含的数据量不同、承载的数据读写压力也不同。如何将这些tablet合理的分配到tabletnode之上,并且在系统运行过程中动态调整,保证上层服务稳定运行便是“自动负载均衡”需要解决的问题。
负载类型及特点
数据量
- 关键资源:缓存容量(SSD、内存等)
- 数据量均衡后可以最大化利用缓存磁盘或内存,使系统服务尽可能多的数据。
- 经验表明,其它几种负载通常与数据量有很强联系,因此在系统运行中,保持各tabletnode之间数据量均衡是首要目标。
- 对时间不敏感,数据量的变化通常较慢,而存储通常有较大buffer,因此只要在一个较长的间内保持均衡即可。
随机读
- 关键资源:CPU
- 当读压力大时,CPU会成为系统首先被用完的资源。最大化利用CPU,使系统提供尽可能高的读吞吐。
- 一旦CPU被耗完,系统响应任何请求都会受到较大影响,因此读负载的均衡也非常重要。
- 时效性要求高,读负载变化很快,容易形成热点,如果不能在较短时间内将热点的单机负载降低,CPU长时间用尽对系统危害很大。
顺序扫描
- 关键资源:CPU、线程池
- 通常扫描需要返回的数据量更多,单个任务的执行时间较长。当请求很多时,CPU和线程池的负载会显著增长。
写
- 关键资源:IO(网络、磁盘)
- 写会产生后台的compact操作(写放大),使系统的IO消耗较高。但在万M网卡及DFS环境下,磁盘和网络IO通常不是瓶颈。
实现
几种负载中数据量和读对系统的服务能力有较大影响,tera当前在这两种维度下实现自动负载均衡。
tera负载均衡由master完成,依赖tablet move操作,即从一个tabletnode上将其unload,再从另外一个tabletnode上load。
负载均衡在query tabletnode完成一轮后启动,保证用最新的tabletnode负载信息进行操作。
目标:从当前tabletnode->tablet的映射集合中通过策略选出部分需要移动的tablet,将其从原tabletnode中unload,并在负载较轻的tabletnode上load起来。
每次负载均衡会有一个待迁移tablet总量控制,保证每次并不会迁移过多tablet,可以保证任一时刻tablet的可用比例,以及cache失效比例。
过程分为两阶段:
- 第一阶段优先进行读负载均衡,将读热点打散。
- 第二阶段进行数据量均衡,视负载不均的情况可能执行N轮。
读负载均衡
- 判定出现读热点:此tabletnode上发生读请求pending数目超过某阈值。
- 并不期待将所有tabletnode的读请求完全平均,只将读热点打散至可服务状态即可。
- 区分cache失效导致pending和cpu不足导致的pending,只对后者进行迁移
- 迁移时每次选qps第二高的tablet,保证最忙tablet优先得到服务
- 优先触发,剩余迁移quota用于size均衡
- 将历史负载值加权加和至最新值中,平滑负载抖动
数据量负载均衡
- 判定需要迁移:最大与最小数据量tabletnode比值超过某阈值。
- 迁移前校验迁移结果,防止出现数据量反转,形成迁移的死循环。
- 迁移时选择最有可能将数据量均衡的tablet进行迁移,防止迁移过多小tablet。
- 在允许范围内可一次执行多轮,提高均衡较果。