分库分表
分库分表,读写分离会带来哪些问题?
前面一篇文章图解分布式系统架构(看推荐阅读)大概讲了一下分库分表,以及读写分离出现的场景,分库分表为了解决高并发和海量数据的问题。
垂直拆分(ER分片)
水平拆分
一致性Hash
范围拆分 可以按照ID
日期拆分
分库后会出现新的问题
- 跨库join问题
如有2个库,订单库,用户库,要查询买了某件商品的所有用户信息 - 事务问题
用户下订单的时候需要扣减商品库存,如果订单数据和商品数据在一个数据库中,我们可以使用事务来保证扣减商品库存和生成订单的操作要么都成功要么都失败,但分库后就无法使用数据库事务了,这时就要用到分布式事务了
分表后也会出现新的问题
- join操作
水平分表后,数据分散在多个表中,如果需要与其他表进行join查询,需要在业务代码或数据库中间件中进行多次join查询,然后将结果合并 - count()操作
业务代码或者数据库中间件对每个表进行count(*)操作,然后将结果相加。或者新建一张表,假如表名为“记录数表”,包含table_name和row_count两个字段,每次插入或删除子表数据成功后,都更新“记录数表” - order by操作
水平分表后,数据分散到多个字表中,排序操作无法再数据库中完成,只能由业务代码或数据库中间件分别查询每个子表中的数据,然后汇总进行排序
现在理论知识都有了,就剩怎么实现了?本来就是为了实现一个功能,现在好了,单写读写分离,跨库join,分布式事务,排序操作等就够你忙的了。
这时候你就应该想起数据库中间件了,它能帮你进行上述操作,把你从复杂的数据处理中解放出来,专注于开发业务代码。
数据库中间件能帮你做什么?
目前国内用的最多的中间件就是sharding-jdbc,mycat
https://shardingsphere.apache.org/document/current/cn/overview/
http://www.mycat.org.cn/
而数据库中间件针对数据源管理,目前主要有两种思路
- 客户端模式,在每个应用程序模块中配置管理自己需要的一个(或者多个)数据源,直接访问各个数据库,在模块内完成数据的整合,sharding-jdbc的实现方式
- 通过中间代理层来统一管理所有的数据源,后端数据库集群对前端应用程序透明,mycat的实现方式
[1]https://www.cnblogs.com/joylee/p/7513038.html
Mycat-Server的github
[2]https://github.com/MyCATApache/Mycat-Server
Mycat启动和安装
[3]https://blog.csdn.net/promise2017/article/details/79326535
[4]https://www.nowcoder.com/discuss/146537?type=0&order=1&pos=23&page=2
[5]https://github.com/doocs/advanced-java/blob/master/docs/high-concurrency/database-shard.md