# 容量评估指标（异构数据库迁移场景）

![`smart`](CapacityPlanningMetrics_zh_001_20240314.png)

----------------------------------------------------
对于，异构数据库迁移场景，一般我们将需要评估的指标分为三大类分别是：集群处理能力，存储数据和成本。

1. 集群处理能力一般包含：

1.1. QPS
QPS 包含写入、复制、读取和读写混合，定义如下：

  - 写入 QPS
通过以上容量评估方法获取基准实例的写入 QPS，不过需要注意的是在传统单机数据库的单机写入 QPS 一般是远大于主从复制 QPS 的，所以单个集群写入能力是不能超过复制 QPS 的，否则会导致从库无法读取到最新数据。所以这种情况下单个集群真正的写入能力一般会取主从复制 QPS 能力，除非是仅单机部署。
如果是云厂商的云数据库 Aurora，因为是单点写入，数据同步通过底层共享存储来实现，一般情况下复制吞吐能力会比传统 MySQL 逻辑复制上限高很多。但是 Aurora 在写入时候就需要同时向共享存储写 redo log 6 次，如果在单行长度较大的场景，比如游戏服习惯的用 JSON 或者 Blob 存储玩家数据，单行长度可能会到几百 KB 级别，这时如果写入量较大，可能会导致主节点的网卡被打满，容量评估时需要考虑这种情况对写入能力的限制。

  - 复制 QPS
上面也说到传统单机关系型数据库写入能力不只受限于实例的配置，同时还受限于主从复制能力，并且主从复制能力一般情况下是小于主节点写入能力的，尤其是 MySQL 基于逻辑日志复制的机制下。例如典型的 MySQL 5.7 集群，电商订单业务的主从并行复制最大 QPS 大概在 10000 QPS 左右，运维人员容量评估时为了保险起见，会将单集群写入能力限定在 5000 - 8000 QPS 左右，避免业务写入量大导致主从延迟，进而导致用户在从节点无法读取到最新的用户数据产生数据不一致问题。所以如果遇到写入大于  5000 - 8000 QPS 的业务，除非经过实际的业务流量压测出实际的主从复制能力，否则则需要进行分库分表或者迁移到分布式关系型数据库。
同时需要评估的是同步到下游数据的能力，确保写入的数据可以准实时（秒级）的发送到下游业务及时的进行消费和处理。

  - 读取 QPS
如果是传统单机关系型数据库读取 QPS 需要在有主从复制写入情况下测试。读取 QPS 不管是在传统关系型数据库（通过增删读实例，读实例上线一般在 10-20 个左右）还是分布式数据库，一般情况下是可以做到近似线性扩展，所以一般只需要评估出参考集群的读取能力即可按照业务需求进行水平或者垂直扩展。

  - 读写混合 QPS
有了单元数据库集群单独的读取和写入 QPS 评估数据，并不代表就能通过计算得到业务需要的容量，因为有部分数据库在读写混合模式下，可能会出现写入影响读取的情况，比如 Aurora，在写入量大的情况下，读节点引用 redo 日志的速度会受到影响，进而影响读取的性能，所以还需要根据一定的读写比例压测出该型数据库在参考集群配置下的读写 QPS 容量。

1.2. 基准实例
指的是以目标数据库的主流配置为基础，通过上文介绍的容量评估方法来进行基本指标的测试，包括，QPS 和单个实例的存储容量。

1.3. 集群数量
如果是非分布式关系型数据库，一般都是一写多读架构，写入节点或者复制吞吐能力容易成为集群写入瓶颈，所以需要根据评估的写入节点处理能力和复制吞吐能力来评估需要多少个集群来满足业务需求。例如：业务要求日订单 5000 千万左右的容量，业务高峰期的写入 QPS 大概在 30000/s左右，该场景下经过业务压测 MySQL 5.7 的主从并行复制能力在 10000 QPS，但是为了安全起见会冗余 20%的写入容量，那该业务场景 MySQL 单机群的写入吞吐设定为 8000 QPS，需要的集群数为 ceil(30000/8000) = 4 个集群。

2. 存储数据
存储指标就是需要计算出需要使用的存储的大小，相对于实例指标评估数据，存储指标评估数据相对比较容易获取，并且一般情况下存储的成本相对于实例成本是比较低的，所以存储可以接受一定程度的冗余来满足业务的正常需求。
存储数据评估的主要指标是：

2.1. 单实例存储
如果是 Share-Nothing 架构（例如：MySQL、TiDB），需要评估单实例（机器）使用的存储大小，MySQL 等传统关系型数据库，一般受限于单盘大小，但是也要根据Buffer Pool 命中率、热数据比例、性能要求、存储空间冗余比例、单块磁盘大小等综合评估使用的单实例存储容量。 TiDB 需要官方要求单个 TiKV 存储的大小在 3-6TB，同时也需要根据业务场景（存储 or 计算）、Region 大小、单实例 CPU、业务性能要求、存储空间冗余比例、单块磁盘大小等进行综合评估。
如果是 Share-Disk 架构（Aurora、PolarDB），使用的是共享云盘，一般数据库层面看只需要一副本的数据存储空间，并且可以做到按需使用，弹性秒级扩展，没有单实例存储大小的概念，但是还是需要根据数据量、热数据比例和内存大小从性能角度考虑单个集群的存储大小。

2.2. 数据压缩率
一般传统单机关系型数据库在线业务不会开启数据的压缩功能，只有在部分温冷数据存储场景才会开启来降低成本；分布式关系型数据库一般是基于 LSM-Tree 的结构，默认是会对数据进行压缩，压缩率大概在 0.1~0.75 左右，实际的压缩率在异构数据迁移时需要通过从源数据库导数据到目标数据库的方式来获取。

2.3. 索引空间占比
一般情况下，业务的索引少则 1-2 个，多则十几甚至几十个，索引需要占用存储空间和行记录对比大概在 5%-80%左右，极端情况下会更高。如果是在数据库异构迁移场景，可以基于源数据库的统计信息获取该值。

2.4. 碎片率
一般传统单机关系型数据库例如 MySQL（RDS MySQL、Aurora、PolarDB 等）数据存储是基于 B+ Tree 格式，碎片率（默认填充因子为 15/16，并且还会存放一些少量的其他字段比如 page level，index number 等等）默认最低为 1/16，如果是频繁更新、删除数据，可能会达到 1/2 甚至2/3。如果是新的分布式关系型数据库例如 TiDB，一般没有碎片率的问题。

2.5. 存储空间冗余
如果是 Share-Nothing 架构（例如：MySQL、TiDB），每个存储数据库实例使用的本地存储，一般是无法做到按需扩展，所以为了保证业务未来一段时间（1 个月/季度/年等）的存储需求，需要冗余一部分的存储空间，尤其是像传统单机关系型数据库 MySQL/PostgreSQL 等无法做 Scale Out 横向扩展，需要根据业务数据增长速度和业务要求冗余较长时间的存储空间，例如需要确保存储空间占比不超过 60%/80%等，那存储空间冗余比例则为 40%/20%。如果是新型的分布式数据库如 TiDB、OceanBase 等，一般可以在小时/天级别完成完成的 Scale Out 流程，所以冗余比例一般不需要像 MySQL 那样高，一般冗余 20%左右存储空间即可。
另外，在某些数据库中，我们可能还要考虑到 UNDO 数据所占的存储空间大小。

2.6. 副本数
副本数一般出于从高可用、读写分离和备份等角度来进行考虑，在进行设计时需要确定下来再进行评估。比如 TiDB 数据库默认副本数是 3，MySQL、PostgreSQL 没有默认副本数，但一般出于高可用和读写分离的需求，往往需要指定副本。

3. 成本
除了以上需要评估的集群规模外，还需要关注成本的评估，确保迁移后成本的变化也是符合业务要求的。




