Aurora Serverless Thought
2024-11-16
TL, DR
- 能原地扩容就原地扩容, 不能的时候就迁移.
- 迁移的本质是一个 bin packing problem. Aurora 采用了反应式MCDM迁移决策算法, 但具体的屁都没说.
Intro
无服务器这个需求很容易理解. 没有Serverless, 用户需要自己预估工作负载购买合理容量的计算资源, 设计扩容缩容策略, 甚至还要自己负责安全, 软件更新, OS tuning等等工作. 并不是所有用户都有精力自己搞定这些, 相当一部分用户更愿意专注在业务逻辑的开发上, 这有助于他们早日实现生意的成功. Aurora Serverless中将资源抽象为了ACU, 一个ACU定义为2GB内存以及与之配套的CPU, 网络, IOPS等计算资源的集合. 用户只需要指定资源用量(预算)上下界, 然后就可以开使干活儿了.
当然, Serverless只是一个用户视角的称呼, 服务器并不是真的消失不见了. 真正的服务仍然运行在某一台机器中, 云服务提供商需要来负责orchestration. Aurora Serverless的论文里主要讨论了两个问题的解决方案: 1) 什么时候扩容/缩容. 2) 扩缩容时发生需要迁移的情况时, 把谁迁移到哪儿? 在Aurora中, 这两个问题由Fleet级的决策系统和Host级的决策系统的组合来解决.
开始讨论之前先澄清一些词汇. Fleet: 一组物理机器组成的集群, 每个AZ都有一个fleet. Host: 一台物理机. Instance: 一台VM.
Fleet级
迁移
舰队资源管理器的一个重要的职责是定期轮询监控实例的情况, 并执行以下三步:
1. 决定哪些主机需要迁出
对于每个主机, 舰队管理器会通过定期查看该主机上的每个实例的预留ACU的和是否超过了阈值(多少没说)判断主机是否过热, 过热就迁出. 论文里说了判断过热后会继续判断是否有足够网络带宽自持迁出, 但也没说不支持的时候会怎么办.
2. 决定从主机上迁出哪些实例
考量有3:
- CPU,网络占用大的可能合适.
- memory map大小和脏页率影响迁移时间.
- 公平, 不要频繁迁移一个实例.
步骤有3:
- 迁移资格过滤 (如近期迁移过的排除).
- 偏好排名, 多个偏好通过一个二进制加权求和reduce成一个标量. (文中又他妈用最近迁移过做例子)
- 两个排序. 一个返回与实例预留ACU成比例的分数. 用人话说就是过热的时候你希望迁出一个大的以更多缓解过热和保证少的迁移次数. 另一个以网络, IOPS等剩余资源的加权求和排序, 没说为啥但我才可能是为了让迁出工作有更多可用资源.
3. 迁入到哪里
- 找活的, 够大的, 带宽能满足迁移的
- 类似的偏好打分. 比如偏好将同一个集群的实例放到不同主机上, 还偏好最近没fail过的主机.
- 计算两个标量的乘积,值越高越是理想迁入目标. 一个是通过最佳匹配启发式算法找嵌入后热度与$\theta_{acu}^{mig}$的比. 能装满且不溢出最好, 这样可以故意留出空闲主机做为今后的迁入目的地. 另一个值是$1- frac{most_used_resource}{\theta_{acu}^{mig}}$. 用以减少不同计算资源的负载不均.
整体来说, 决策的过程是一个反应式(基于当前状态做出决策)的MCDM(Multi-Criteria Decision Making), 没有什么预定义与预测. 且论文中对各种阈值, 偏好类型, 打分权重等关键信息都没有披露.
放置新实例
舰队管理器还负责放置用户新创建的实例, 由于此时只有MIN MAX ACU作为参考信息, 且Aurora Serverless 扩容比缩容快得多, 所以选MIN ACU并执行上述步骤3. 扩容比缩容快得原因后面有提到.
保持Fleet大小
Fleet管理首先会在周或月的大时间尺度下评估并修改Fleet的大小. 啊对, RDS团队是要花钱像EC2团队订购主机开展业务的.
主机级
机制
论文说的是Instance Manager, 每个实例一个. 不确定Hypervisor级别有没有魔改, 但估计没有, 因为如果要动估计需要EC2团队的配合. 有以下机制:
- 收集数据预估资源用量, 但是魔改引擎直接收集buffer pool的信息, 毕竟Andy hate mmap.
- 5.1.2就是来凑字数的. 为了能原地扩容用了EC2团队Nitro实例类型.
- 硬件资源的超额预定. 资源管理中为了提高硬件利用率的的常见手段, 也是导致吵闹邻居的罪魁祸首之一.
- Linux倾向于把free memory用光, 但这会导致ACU增加到用户指定的最大值. Aurora魔改内核, 实现了一些功能保证内存瘦身.
- 边界执行就是说保证实例在给定的预留ACU上界内使用资源. 至于说到cgroup我猜是因为把HostManager, InstanceManager等管理进程和数据库进程, 存储进程等真用户进程分开.
策略
边界管理 就是讨论修改预留ACU的大小, 理想情况是既能敏捷相应变化又不会预留过多导致浪费. 内存是通过数据平面过去一分钟的最大内存用量来估计的, 其他指标也会看但怎么看没说. 限流部分是说, 当主机中某个实例快速变热时, 我们放宽限流, 让它快速获取资源. 同时对不活跃的实例保持较严格的限流, 以保证在迁移它补救的过程中不会给舰队管理器太大压力.
原地扩展 部分则是通过检查过去几分钟的资源利用情况, 判断有一个资源需要拓展时就扩容, 所有资源都过剩时再缩容. 再加上预留ACU, 这就是扩容比缩容快的多的原因.
Questions
- In section 4.1 step 1, what is this threshold exactly?
- In section 4.1 step 1, what if a host do not have enough network bandwidth to sustain an out-migration?
- In section 4.1 step 2 stage 2a and stage 2b, what are those filter predicates and preferences? Same question for step 3 stage 3a and stage 3b.
- In section 4.1 step 2 stage 2c, two rankers are a bit contradictory to me. How can one instance have high reserved ACU but low network IO and disk IO.
- In section 4.2, the paper mentioned scale up is much faster than scale down, why?
- In section 5.1.4 db.serverless instance class have grow up to 128 ACU, but section 3.2 mentioned Aurora Serverless procures hosts comprising 256 ACUs. What if my Aurora cluster have only 1 writer?
- In section 5.2.1: reffig:acus. Maybe
\ref{fig:acus}
? Figure 4?
结论
这论文啥也没说.