Implement High Availability (实现高可用性)

高可用是分布式系统的基本要求. 本章我们来讨论为了实现高可用性, 有哪些技术问题和解决方案.

Application Case

我们以电商网站举例. 假设我们的服务器, 每台每秒能处理 1,000 个订单. 我们现在有 12 台服务器.

问题 1: Peak Traffic (在流量出现大幅增长的情况下系统的响应时间保持依然可用)

  • 当检测到每秒的订单数接近 12,000 * 70% = 8,400 时, 我们就要进行扩容, 增加 3 台服务器. 可以支持最多每秒 15,000 * 70% = 105,000 个订单.

  • 当检测到每秒的订单数低于 12,000 * 40% = 4,800 时, 我们就要进行缩减, 减少 3 台服务器. 可以支持最多每秒 9,000 * 70% = 6,300 个订单.

问题 2: Server Error (服务器有一定概率定期挂掉)

服务器是有概率死掉的. 当 LB (Load balancer 负载均衡器) 检测到某台服务器挂掉, 则将其杀死, 并在同样的网络环境中启动一台新的, 使得数量保持在 10 台,

问题 3: Network Error (网络可能有一定概率挂掉, 导致大量服务器不可用)

以 AWS 为例, 所有的服务器被部署到 3 个不同的 Availability Zone (AZ 可用区域) 上, 每个可用区域的网络是独立的, 挂掉的概率相互独立.

那么每当一个 AZ 挂掉时, 我们会损失 33% 的运算量. 此时优先再在新的 AZ 上重启损失的服务器.

Database Case

我们以 DynamoDB 举例. DynamoDB 会用 Partition Key 将流量 route 到不同的节点上.

问题 1: Peak Traffic (在流量出现大幅增长的情况下系统的响应时间保持依然可用)

假设目前我们有 3 个 节点, 那么我们用 Hash(partition key) 的值除以 3 的余数, 根据节点的序号决定运算发生在哪个节点.

当数据量增长时, 我们就增加 1 个节点, 并使用 Consistent Hash 一致性哈希算法 算法进行 数据迁徙 和 负载路由更新.

问题 2: Server Error (服务器有一定概率定期挂掉)

每一个节点背后其实有 3 台位于不同 AZ 的虚拟机, 同一时间只有一台是 Master, 提供 read / write (或是只有 write), 而其他两台是 Slave. 当 Slave 挂掉, 在同一个 AZ 重启就好. 当 Master 挂掉, 则在 Slave 中选举出一个 Master, 然后再重启 Master, 并将其变成 Slave 即可.

问题 3: Network Error (网络可能有一定概率挂掉, 导致大量服务器不可用)

在该情况出现时, 则相当于是 问题 2 的情况出现于所有的节点上, 按照 问题 2 中的流程, 重新选举 Master, 再重启 Slave 即可.