任何一个技术的出现,都不是为了秀肌肉而产生的。
sharding jdbc 这个分库分表技术要解决的问题就是,随着数据量级的提升,物理硬件达到瓶颈,单表的性能优化也带来了瓶颈。 而数据量仍然要突破的难题。
这个问题的解决方案,其实就是一种分治的思想。用一句白话来解释,就是大事化小,举个简答的例子,就是让你查一斤大米确切的有几个,如果让你一个人来查花费时间太多,假如需要花费三个小时。那么找两个人,把一斤大米分成两份,花费的时间大约就是一个半小时。如果分成六份,六个人来查,大概就是花费半个小时。 这就是分治的思想,效果又很明显,从三个小时,到半个小时。
把这个问题还原成数据库的问题,数据库有库的概念,表的概念。 那么解决问题就是要分库分表。
如果还不了解分库分表的概念请看我一篇文章:https://blog.csdn.net/star1210644725/article/details/104375267
# # 分库分表带来的问题
在 https://blog.csdn.net/star1210644725/article/details/104375267 这篇文章里的已经介绍了一些问题。
此外,还有一些问题是一定要解决的:比如对数据源问题,分库以后在不同的服务器上,访问ip地址都不一样了。等等
# # sharding jdbc
轻量级框架,以jar包的形式使用,相当于是增强版的jdbc驱动。
核心功能是:提供数据分片,和读写分离。
优点所在是:应用可以透明的使用 jdbc 访问数据库,达到让应用程序对分库分表无感知。也就是说,分库分表明明带来的问题,但是就是又有人帮你做处理,让应用程序仍然按照之前的逻辑来写,并不用因为分库分表了做任何改变。
# # 问题解决过程
因为数据库性能瓶颈,所以需要进行分库分表。
因为引入了分库分表,所以引入多数据源问题。
因为有多数据源问题,所以代码逻辑需要修改。
应为sharding 的出现,所以解决了修改逻辑的难题,
最终做到让业务无感多数据源,做到分库分表。
# # 无感的解决问题,带来的是:单机性能损耗的问题。
为什么会消耗内存呢?
其实中间多了一层 sql 截取 和重装的过程,因为对数据库操作的本质还是sql,因为数据库只认识sql
因为是分库分表,所以结果还是要汇总的。
# # sharding jdbc 的使用
就像是jdbc 驱动一样,先配置数据源。
然后再配置数据节点
配置主键生成测测咯,主键不能是数据库自增了,要使用全局主键。
上图所谓的表名是逻辑表名
看最后一行:其实这是 逻辑表名 和 实际数据库表名形成映射的关键所在 后边加上数字,就是实际数据库的表名。而逻辑表名实际上就是我们写的sql 的表名。
# # 相关概念
逻辑表:就是我们在 操作过程中写的 sql 中表名,所谓的逻辑就是假装有。
真实表: 就是数据库中真实存在的,这里的真实 是和 逻辑 相映射的。
数据节点: 如下,带逻辑表名,以及 后边根据算法而来的真实表名。
绑定表:这个一般用于 和子表关联 ,这样不用产生笛卡尔积。 比如 a 和 b表 ,a分表后是 a1 和 a2 ,b分后是 b1 和 b2 ,如果是笛卡尔积,那就是四种情况,发四条sql 语句。如果是绑定表,则只需要两条。
广播表:就是在每个库上都建一个表,一个操作,同时操作多份。
分片键:就是根据这个字段进行算法分表的。
分片算法:
分片策略:=分片键+分片算法 尾数取模,哈希,时间,等等
自增主键生成策略:解决分布式主键冲突问题,用全局自增主键。
# # 执行过程
先进行sql 语法解析,解析后,进行路由,然后sql 重新组装,执行sql,然后结果归并。
# # 查询结果归并
流式归并,内存归并,装饰者归并
# # sharding 需要特别注意的问题
如果我们设置了分片键,在做查询的时候,查询就要加上分片键。否则就是扫描全部的表,也就是说打比方分了三个库,每个库三个表。如果你业务上的sql 没有带上分片键,也就是说sharding 无法根据你sql解析来路由到哪里,也就是说知道到九个表中做全部的查询,也就是说不做分库分表,是一条语句,分库分表后,如果不带 分片键就是 9条sql。这就造成了不必要的资源浪费。
从这个角度上来讲,其实 sharding 并不是说的那么好。并不是业务对sql是无感,很准确的说,我们的sql,要强行加分片键,否则结果就是造成不必要的性能损耗,甚至说不如不做分库分表来的好。
# # 公共表(一般用来关联查询的时候 字典表)
# # sharding 读写分离
先配置数据库能够读写分离,这一块sharding 不能帮,需要我们自己操作。
配置成以后,路由问题,可以交给 sharding 来管理,
任何一个数据源都要告诉 sharding,先把从库的数据源告诉sharding ,就是通过配置的形式。
明显最上边能做的的仅仅是知道了数据源,sharding也不能通过名字就知道谁是主库,谁是从库。
于是有下边的红框的内容告诉 sharding ,谁是主库,谁是从库。
这也还不够,还需要在数据节点上,添加这个读写分离的操作。