一、概念理解
垂直切分:包含垂直分库和垂直分表
1.1、垂直分库 :专库专用(按照业务类型对表分类)
1.2、垂直分表:基于数据表的列(字段)为依据切分的,是一种大表拆小表的模式。
1.3、垂直切分优点:
·不同业务的数据进行独立维护,监控,扩展;
·在高并发场景下,一定程度上缓解了数据库的压力。
1.4、垂直切分的缺点:
·提高了开发的复杂度,由于业务的隔离性,很多表无法直接访问,必须通过接口方式聚合数据;
·分布式事务管理难度增加;
·数据库还是存在单表数据量过大问题。
水平切分
2.1、水平分库:把同一个表按一定规则拆分到不同的数据库中,每个库都可以位于不同的服务器上。
水平分库可以解决单库存储量以及性能瓶颈问题,但由于同一个表被分在不同数据库中,数据访问需要额外的路由工作,因此系统的复杂度也被提升。
2.2、水平分表:是在同一个数据库内,把一张大数据量的表按一定规则,切分成多个结构完全相同的表,而每个表只存原表的一部分数据。
只解决了单一表数据量过大的问题。
2.3、水平切分的优点:
·解决高并发时单库数据量过大的问题,提升系统稳定性与负载能力;
·业务系统改造的工作量不是很大。
2.4、水平切分的缺点:
·跨分片的事务一致性难以保证;
·垮库的join关联查询性能比较差;
·扩容的难度和维护量比较大。
一定规则:
·这个规则是一种路由算法,就是决定一条数据具体应该存在那个数据库那张表里。常见的有 取模算法 和 范围限定算法。
3.1、取模算法:按照字段取模(对hash结果取余数 (hash() mod N))n为数据库实例数或者子表数量,是最为常见的一种切分方式。
优点:数据分片相对比较均匀,不易出现请求都打到一个库上
缺点:这种算法存在问题当某台机器宕机,本应该落在该数据库的请求就无法得到正确的处理,这时候宕掉的实例会被踢出集群,姿势的算法变成hash(userId) mod N-1,用户信息可能就不再在同一个库中了。
3.2、范围限定算法:按照 时间区间 或者 ID区间 来切分。
优点:·单表数据量是可控的
·水平扩展简单只需增加节点即可,无需对其他分片数据进行迁移
·能快速定位要查询的数据在哪个库
缺点:由于连续分片可能存在数据热点,会存在默写数据频繁查询某些数据很少查询。
4.分库分表的难点
4.1、分布式事务
由于表分布在不同的库中,不可避免会带来垮库事务的问题。一般可使用“三阶段提交”和“两阶段提交”处理,但是这种方式性能很差,代码开发量也比较大。
·阿里的分布式事务框架Seata 来做分布式事务的管理
4.2、分页、排序、垮库联合查询
分页、排序、联合查询是开发中使用频率非常高的功能,但在分库分表后,这些看似普通的操作却是让人非常头疼的问题。将分散在不同库中表的数据查询出来,再将所有结果进行汇总整理后提供给用户。
4.3、分布式主键
分库分表后数据库的自增主键意义就不大了,因为我们不能依靠单个数据库实例上的自增主键来实现不同数据库之间的全局唯一主键,此时一个能够生成全局唯一ID的系统是非常必要的,那么这个全局唯一ID就叫 分布式ID。
4.4、读写分离
大部分主流的关系型数据库都提供了主从架构的高可用方案,而我们需要实现读写分离 + 分库分表,读库与写库都要做分库分表处理
4.5、数据脱敏
5、sharding-jdbc
·是一款轻量级的java框架,以jar包形式提供服务,是属于客户端产品不需要额外的部署,它相当于是个增强版的jdbc驱动。
·兼容性也非常强大,适用于任何基于jdbc的orm框架,如:JPA, Hibernate,Mybatis,Spring JDBC Template 或直接使用的 JDBC。
·完美兼容任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP,Druid, HikariCP 等,几乎对所有关系型数据库都支持。
·对项目的侵入性很小,几乎不用做任何代码层的修改,也无需修改 SQL 语句,只需配置待分库分表的数据表即可。
二、分片规则
上边我们提到可以用分片健取模的规则分片,但这只是比较简单的一种,在实际开发中我们还希望用 >=、<=、>、<、BETWEEN 和 IN 等条件作为分片规则,自定义分片逻辑,这时就需要用到分片策略与分片算法。
从执行 SQL 的角度来看,分库分表可以看作是一种路由机制,把 SQL 语句路由到我们期望的数据库或数据表中并获取数据,分片算法可以理解成一种路由规则。
标准分片策略
使用场景:SQL 语句中有>,>=, <=,<,=,IN 和 BETWEEN AND 操作符,都可以应用此分片策略。
标准分片策略(StandardShardingStrategy),它只支持对单个分片健(字段)为依据的分库分表,并提供了两种分片算法 PreciseShardingAlgorithm(精准分片)和 RangeShardingAlgorithm(范围分片)。
一旦我们没配置范围分片算法,而 SQL 中又用到 BETWEEN AND 或者 like等,那么 SQL 将按全库、表路由的方式逐一执行,查询性能会很差需要特别注意。
精准分片算法
精准分库算法
实现自定义精准分库、分表算法的方式大致相同,都要实现PreciseShardingAlgorithm 接口,并重写 doSharding() 方法,只是配置稍有不同,而且它只是个空方法,得我们自行处理分库、分表逻辑。其他分片策略亦如此。