前两节对分库分表和遇到一些问题进行解释和总结,本节对分库分表的数据存储和划分原则进行一个讲解
数据存储
分别是:
- 独立存储+缓存:适用于数据量少,基本不变的数据;
- 读写分离 : 适用于数据量适中,增长平缓,读多写少的数据
- 水平切分: 适用于数据量大,增长快速,读写频繁的数据
划分原则
- 能不分就不分,当单表记录达到一定数量级(>1000万)之后才考虑进行水平切分处理;
- 分片字段取决于最频繁的查询SQL,选择合适的切分规则,避免跨库聚合,跨库事务;
- 分片数量尽量少,分片尽量均匀分布在多个 DataHost 上,一个查询 SQL 跨分片越多,则总体性能越差;
- 考虑数据的增长模式,数据的访问模式,分片关联性能问题,分片扩容问题;
- 分片表要避免不带任何where条件的查询;
分片规则
下面对常用的分片进行一个介绍
范围约定
-
优点:此分片规则在扩容时只需要添加节点,指定日期范围,可以避免扩容时的数据迁移,
例如:表test规划了两个节点分别为db1、db2,db1存储2015.12之前的数据,db2存储2016.1-2016.6的数据,当时间达到2016.6以后,现有分片规则无法满足,所以就面临分片的增加,一般分片的增加需要进行数据迁移,而基于范围的分片规则,只需增加2016.7 -2016.12即可,不需要对以前的数据进行迁移。
-
缺点:负载不均衡
如2015.12以前这个业务发展不是特别快,数据量相对不大,但是以后随着营销和推广,业务飞速发展,那么2016.1-2016.6这个节点数据量就相对比较大。
取模
根据分片键的值进行hash,并根据节点数进行取余
- 优点:负载均衡
- 缺点:在扩容时需要全量迁移
一致性Hash
按照常用的hash算法来将对应的key哈希到一个具有232次方个桶的空间中,即0~(232)-1的数字空间中。现在我们可以将这些数字头尾相连,想象成一个闭合的环形.
- 首先求出数据库节点的哈希值,并将其配置到0-2^32圆上,如
- Hash(NODE1) = KEY1=2^10;
- Hash(NODE2) = KEY2=2^20;
- Hash(NODE3) = KEY3=2^30;
- 然后采用同样的方法求出存储数据的键的哈希值,并映射到相同的圆上。
- 然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器上。如果超过2^32仍然找不到服务器,则从0开始查找。
4. 示例:
根据用户ID分片,流水号规则为UR+12位序号,如UR000000000013, 进行hash计算为2^5,则属于NODE1
- 优点:负载相对均衡
- 缺点:在扩容时需要部分迁移