# 架构设计思想AKF拆分原则

## 单机、单进程的问题

1. 单点故障
2. 容量有限
3. 承受压力有限

## 什么是AKF

AKF 立方体也叫做scala cube，它在《The Art of Scalability》一书中被首次提出，旨在提供一个系统化的扩展思路。AKF 把系统扩展分为以下三个维度：

* **X 轴**：直接水平复制应用进程来扩展系统。
  * 横向扩展，比如主从角色（主写从读）,集群等
  * 单点故障可以解决、容量有限不一定可以解决、承受压力读可以解决但是写不一定可以解决
* **Y 轴**：将功能拆分出来扩展系统。
  * 纵向扩展，将系统按照功能划分多个，分别存储数据以及压力
  * 主要解决容量有限与压力的问题。
* **Z 轴**：基于用户信息扩展系统。
  * 按照数据拆分，比如将1000w的用户拆分为两个库存储，每个存储500w
  * 主要解决容量过高的场景。

![img](https://2351062869-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7b2CdwBN9liniVJpfEAc%2Fuploads%2Fgit-blob-e6aa5e1e57284286ac22ec2119c5f74961b84fe8%2F1477786-20200830113116204-1448568678.jpg?alt=media)

## 沿X轴扩展系统

![](https://2351062869-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7b2CdwBN9liniVJpfEAc%2Fuploads%2Fgit-blob-03a2b065fe8e0b36fecc23fa1115f706ee1bbc06%2FPasted%20image%2020240410154224.png?alt=media)

X轴的扩展方案主要有：

* 集群，如果是无状态系统，该种方式开发成本近乎于零，直接复制服务进程分担请求流量。
* 主从，单个主节点常用来提供写服务，多个从节点用来提供读服务。
* 主备，主节点提供读写服务，备用节点会在主节点发生故障时主动顶替，保证服务的可用性。

X轴扩展方案也有一些问题：

* 集群中的节点服务存在数据不一致的问题，可通过分布式一致性算法保证。
* 主从结构存在单点故障问题，可使用`故障监控+选举算法`重新选举主服务器，选举过程的目的是为了保证状态的一致性。

## 沿Y轴扩展系统

当数据库的 CPU、网络带宽、内存、磁盘 IO 等某个指标率先达到上限后，系统的吞吐量就达到了瓶颈，此时沿着 AKF X 轴扩展系统，是没有办法提升性能的。在现代经济中，更细分、更专业的产业化、供应链分工，可以给社会带来更高的效率，而 AKF Y 轴与之相似，当遇到上述性能瓶颈后，拆分系统功能，使得各组件的职责、分工更细，也可以提升系统的效率。比如，当我们将应用进程对数据库的读写操作拆分后，就可以扩展单机数据库为主备分布式系统，使得主库支持读写两种 SQL，而备库只支持读 SQL。这样，主库可以轻松地支持事务操作，且它将数据同步到备库中也并不复杂，如下图所示：

![](https://2351062869-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7b2CdwBN9liniVJpfEAc%2Fuploads%2Fgit-blob-9b29a2c0e914d550138ae96ca0556b91d59ed29a%2FPasted%20image%2020240410153656.png?alt=media)

## 沿Z轴扩展系统

AKF Z 轴则从用户维度拆分系统，它不仅可以提升数据持续增长降低的性能，还能基于用户的地理位置获得额外收益。以博客平台为例，当注册用户数量上亿后，无论你如何基于 Y 轴的功能去拆分表（即“垂直”地拆分表中的字段），都无法使得关系数据库单个表的行数在千万级以下，这样表字段的 B 树索引非常庞大，难以完全放在内存中，最后大量的磁盘 IO 操作会拖慢 SQL 语句的执行。这个时候，关系数据库最常用的分库分表操作就登场了，它正是 AKF 沿 Z 轴拆分系统的实践。比如已经含有上亿行数据的 User 用户信息表，可以分成 10 个库，每个库再分成 10 张表，利用固定的哈希函数，就可以把每个用户的数据映射到某个库的某张表中。这样，单张表的数据量就可以降低到 1 百万行左右，如果每个库部署在不同的服务器上（具体的部署方式视访问吞吐量以及服务器的配置而定），它们处理的数据量减少了很多，却可以独占服务器的硬件资源，性能自然就有了提升。如下图所示：

![](https://2351062869-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7b2CdwBN9liniVJpfEAc%2Fuploads%2Fgit-blob-ac9e15e13530da64895a60403f3fa7074eaf4aec%2FPasted%20image%2020240410153706.png?alt=media)

> 🤔 让我想起来了，移动掌上营业厅，每个省份都有自己的APP以及对应的服务器。这就是典型的使用地域划分扩展系统的样例。 在数据库层面，水平分库也是一种Z轴扩展，垂直分库则是一种Y轴扩展。
