目录
单表行数超过500万行,或单表容量超过2GB,推荐分库分表。
可以通过数据库连接池优化连接数问题,更好的方式是分库,避免数据库称为业务瓶颈。
垂直拆分和水平拆分
将表按库进行分离,或者修改表结构按照访问的差异将某些列拆分出去。应用时有垂直分库和垂直分表两种方式,一般谈到的垂直拆分主要指的是垂直分库。
垂直拆分优点:
垂直拆分缺点:
通过某个字段(或某几个字段),根据某种规则将数据分散至多个库或表中,每个表仅包含数据的一部分。
将一张含有很多记录数的表水平切分,不同的记录可以分开保存,拆分成几张结构相同的表。如果一张表中的记录数过多,那么会对数据库的读写性能产生较大的影响,虽然此时仍然能够正确地读写,但读写的速度已经到了业务无法忍受的地步,此时就需要使用水平分表来解决这个问题。
水平拆分优点:
水平拆分缺点:
分布式唯一ID,可参考分布式唯一id生成策略_零点冰.的博客-CSDN博客
通用唯一识别码,长度是16个字节,被表示为32个十六进制数字,以“ - ”分隔的五组来显示,格式为8-4-4-4-12,共36个字符。
UUID在生成时使用到了以太网卡地址、纳秒级时间、芯片ID码和随机数等信息,目的是让分布式系统中的所有元素都能有唯一的识别信息。
使用UUID做主键,可以在本地生成,没有网络消耗,所以生成性能高。
但是UUID比较长,没有规律性,耗费存储空间,在辅助索引回表查询时有所体现。
在InnoDB引擎下,UUID的无序性可能会引起数据位置频繁变动,影响性能。
保留UUID的前10个字节,用后6个字节表示GUID生成的时间(DateTime),这样我们将时间信息与UUID组合起来,在保留UUID的唯一性的同时增加了有序性,以此来提高索引效率。解决UUID无序的问题,性能优于UUID。
使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号,最后还有一个符号位,永远是0。
单独的创建一个MySQL数据库,在这个数据库中创建一张表,这张表的ID设置为自动递增,其他地方需要全局唯一ID的时候,就先向这个这张表中模拟插入一条记录,此时ID就会自动递增
主要依赖于Redis是单线程的,所以也可以用生成全局唯一的ID。可以用Redis的原子操作 INCR和INCRBY来实现。
规则,分片结果就是分库分表。
分片(Sharding)就是用来确定数据在多台存储设备上分布的技术。
数据库扩展方案:
分片键:用于划分和定位表的字段。
分片策略:分片规则。
根据特定字段的范围进行拆分,比如用户ID、订单时间、产品价格等。例如:
{[1 - 100] => Cluster A, [101 - 199] => Cluster B}
优点:新的数据可以落在新的存储节点上,如果集群扩容,数据无需迁移。
缺点:数据热点分布不均,数据冷热不均匀,导致节点负荷不均。
整型的Key可直接对设备数量取模,其他类型的字段可以先计算Key的哈希值,然后再对设备数量取模。假设有n台设备,编号为0 ~ n-1,通过Hash(Key) % n就可以确定数据所在的设备编号。该模式也称为离散分片。
优点:实现简单,数据分配比较均匀,不容易出现冷热不均,负荷不均的情况。
缺点:扩容时会产生大量的数据迁移,比如从n台设备扩容到n+1,绝大部分数据需要重新分配和迁移。
采用Hash取模的方式进行拆分,后期集群扩容需要迁移旧的数据。使用一致性Hash算法能够很大程度的避免这个问题。
一致性Hash是将数据按照特征值映射到一个首尾相接的Hash环上,同时也将节点(按照IP地址或者机器名Hash)映射到这个环上。对于数据,从数据在环上的位置开始,顺时针找到的第一个节点即为数据的存储节点。Hash环示意图与数据的分布如下:
一致性Hash在增加或者删除节点的时候,受到影响的数据是比较有限的,只会影响到Hash环相邻的节点,不会发生大规模的数据迁移。
回滚方案:万一数据迁移失败,需要将配置和数据回滚,改天再挂公告。
优点:简单
缺点:
适用场景:
平滑扩容就是将数据库数量扩容成原来的2倍。
此时已经扩容完成,但此时的数据并没有减少,新增的数据库跟旧的数据库一样多的数据,此时还需要写一个程序,清空数据库中多余的数据,如:
User1去除 uid % 4 = 2的数据;
User3去除 uid % 4 = 0的数据;
User2去除 uid % 4 = 3的数据;
User4去除 uid % 4 = 1的数据;
平滑扩容方案能够实现n库扩2n库的平滑扩容,增加数据库服务能力,降低单库一半的数据量。其核心原理是:成倍扩容,避免数据迁移。
优点:
缺点:
适用场景:
对业务进行分库,同一个操作可能分散到多个数据库中,设计跨库执行SQL语句,就会有分布式事务问题。
跨库和跨表的关联查询操作更复杂,性能会受到影响。
查询指定列表、或者需要对数据列表进行排序,则需要在内存中进行处理,整体性能差。
以上内容为个人学习理解,如有问题,欢迎在评论区指出。
部分内容截取自网络,如有侵权,联系作者删除。