前言

之前总在聊微服务, 微服务自身也是分布式体系,其实微服务的中心思维是分而治之,把一个杂乱的单体体系,依照事务的交付,分红不同的自服务,以降低资深杂乱度,同时能够提升体系的扩展性。

今日想聊一下分库分表,由于对于快速添加的事务来说,这个是无法回避的一环。之前我在做商城相关的SAAS体系,产品池是一个存储瓶颈,产品池数量会根据租户添加和运营变得指数级添加,短短几个月就能涨到几千万的数据,而运营半年后就或许过亿。而对于订单这种数据,也会跟着事务的成长,也会变得愈发巨大。

存储层来说,提升大数据量下的存储和查询功用,就涉及到了另一个层面的问题,但思维还是相同的,分而治之。

咱们面对什么样的问题

联系型数据库在大于一定数据量的情况下检索功用会急剧下降。在面对海量数据情况时,一切数据都存于一张表,显然会轻易超过数据库表可接受的。

此外单纯的分表虽然能够解决数据量过大导致检索变慢的问题,但无法解决过多并发请求访问同一个库,导致数据库呼应变慢的问题。所以需求分库来解决单数据库实例功用瓶颈问题。

数据库架构计划

在讲具体解决计划之前,咱们需求先了解一下数据库的三种架构涉及计划。

1. Shared Everything

一般指的是单个主机的环境,彻底透明同享的CPU/内存/硬盘,并行处理才能是最差的,一般不考虑大规模的并发需求,架构比较简单,一般的运用需求根本都能满意。

2. Shared Disk

各处理单元运用自己的私有CPU和Memory,同享磁盘体系。典型的代表是Oracle RAC、DB2 PureScale。例如Oracle RAC,他用的是同享存储,做到了数据同享,可经过添加节点来进步并行处理的才能,扩展才能较好,运用Storage Area Network (SAN),光纤通道连接到多个服务器的磁盘阵列,降低网络耗费,进步数据读取的功率,常用于并发量较高的OLTP运用。其类似于SMP(对称多处理)方式,可是当存储器接口到达饱满的时候,添加节点并不能获得更高的功用,同时更多的节点,则添加了运维的本钱。

3. Shared Nothing

各处理单元都有自己私有的CPU/内存/硬盘等,Nothing,望文生义,不存在同享资源,类似于MPP(大规模并行处理)方式,各处理单元之间经过协议通讯,并行处理和扩展才能更好。典型代表DB2 DPF、带分库分表的MySQL Cluster,各节点相互独立,各自处理自己的数据,处理后的成果或许向上层汇总或在节点间流通。

咱们常说的Sharding其实便是Shared Nothing,他是将某个表从物理存储上被水平切割,并分配给多台服务器(或多个实例),每台服务器能够独立作业,具有共同的schema,例如MySQL Proxy和Google的各种架构,只需添加服务器数就能够添加处理才能和容量。

至于MPP,指的是大规模并行剖析数据库(Analytical Massively Parallel Processing (MPP) Databases),他是针对剖析作业负载进行了优化的数据库,一般需求聚合和处理大型数据集。MPP数据库往往是列式的,因而MPP数据库通常将每一列存储为一个目标,而不是将表中的每一行存储为一个目标。这种体系结构使杂乱的剖析查询能够更快,更有效地处理。例如TeraData、Greenplum,GaussDB100、TBase。

根据以上的这几种架构计划,咱们能够给出大数据量存储的解决计划:

分而治之--浅谈分库分表及实践之路 | 京东云技术团队

以上几种解决计划各有利弊,分区方式最大的问题是准share everything架构,无法水平扩展cpu和内存,所以根本能够扫除;nosql自身其实是个十分好的备选计划,可是nosql(包含大部分开源newsql)硬件耗费十分大,运维本钱较高。而常用的一种计划便是根据Mysql的分库分表计划。

分库分表架构计划

对于分库分表,首先看一下市道上有哪些产品。

业界组件 原厂 功用特性 补白
DBLE 爱可生开源社区 专心于mysql的高可扩展性的分布式中间件 根据MyCAT开发出来的增强版。
Meituan Atlas 美团 读写别离、单库分表 现在现已在原厂逐渐下架。
Cobar 阿里(B2B) Cobar 中间件以 Proxy 的方式位于前台运用和实践数据库之间,对前台的敞开的接口是 MySQL 通讯协议 开源版别中数据库只支撑 MySQL,并且不支撑读写别离。
MyCAT 阿里 是一个完成了 MySQL 协议的服务器,前端用户能够把它看作是一个数据库署理,用 MySQL 客户端东西和命令行访问,而其后端能够用MySQL 原生协议与多个 MySQL 服务器通讯 MyCAT 根据阿里开源的 Cobar 产品而研发
Atlas 360 读写别离、静态分表 2015年后现已不在维护
Kingshard 开源项目 由 Go 开发高功用 MySQL Proxy 项目,在满意根本的读写别离的功用上,Kingshard 的功用是直连 MySQL 功用的80%以上。 
TDDL 阿里淘宝 动态数据源、读写别离、分库分表 TDDL 分为两个版别, 一个是带中间件的版别, 一个是直接Java版别
Zebra 美团点评 完成动态数据源、读写别离、分库分表、CAT监控 功用彻底且有监控,接入杂乱、约束多。
MTDDL 美团点评 动态数据源、读写别离、分布式唯一主键生成器、分库分表、连接池及SQL监控 
Vitess 谷歌、Youtube 集群根据ZooKeeper管理,经过RPC方法进行数据处理,整体分为,server,command line,gui监控 3部分 Youtube 很多运用
DRDS 阿里 DRDS(Distributed Relational Database Service)专心于解决单机联系型数据库扩展性问题,具有轻量(无状态)、灵活、稳定、高效等特性,是阿里巴巴集团自主研 
Sharding-proxy apache开源项目 供给MySQL版别,它能够运用任何兼容MySQL协议的访问客户端(如:MySQL Command Client, MySQL Workbench等)操作数据,对DBA愈加友好。向运用程序彻底透明,可直接当做MySQL运用。适用于任何兼容MySQL协议的客户端。 Apache项目,定位为透明化的数据库署理端,供给封装了数据库二进制协议的服务端版别,用于完成对异构言语的支撑。
Sharding jdbc apache开源项目 彻底兼容JDBC和各种ORM结构。适用于任何根据Java的ORM结构,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接运用JDBC。根据任何第三方的数据库连接池,如:DBCP,C3P0, BoneCP, Druid, HikariCP等。支撑任意完成JDBC标准的数据库。现在支撑MySQL,Oracle,SQLServer和PostgreSQL Apache项目,定位为轻量级Java结构,在Java的JDBC层供给的额定服务。 它运用客户端直连数据库,以jar包方式供给服务,无需额定布置和依靠,可理解为增强版的JDBC驱动

对于分库分表的产品方式,又分为两种,中间件方式和客户端方式。

1. 中间件方式其优缺点

中间件方式独立进程,所以能够支撑异构言语,对当时程序没有侵入性,对事务方来说是透明的mysql服务,可是缺点也十分显着,硬件耗费大、运维本钱高(尤其是在本地化施行情况下),同时由于对联系型数据库添加了署理,会造成问题难调试。

2. 客户端方式优缺点

客户端方式的首要缺点是对代码有侵入,所以根本只能支撑单言语,同时由于每个客户端都要对schema树立连接,所以假如数据库实例不多,需求对连接数仔细控制,可是客户端方式的长处也十分显着,首先从架构上它是去中心化的,这样就避免了中间件方式的proxy毛病问题,同时由于没有中间层功用高、灵活可控,而且由于没有proxy层,不需求考虑proxy的高可用和集群,运维本钱也比较低。

sharding-jdbc接入实战

sharding-jdbc其实是这些产品中最为咱们熟知的,也是由于它定位为轻量级 Java 结构,在 Java 的 JDBC 层供给的额定服务。 它运用客户端直连数据库,以 jar 包方式供给服务,无需额定布置和依靠,可理解为增强版的 JDBC 驱动,彻底兼容 JDBC 和各种 ORM 结构。适用于任何根据 JDBC 的 ORM 结构,如:JPA, Hibernate, Mybatis, Spring JDBC Template 或直接运用 JDBC。而且在社区活跃度,代码质量等方面,也是很不错的。接下来,我讲具体讲一下接入细节。

1. 组件集成

<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId> <version> 5.0.0</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.4.0</version>
</dependency> 

2. bean装备

装备sharding jdbc数据源并且加入到动态数据源中,用于数据源路由。

分而治之--浅谈分库分表及实践之路 | 京东云技术团队

修正原装备中心对应服务的mysql数据源装备,对不分库分表的数据源装备为动态数据源默许路由

分而治之--浅谈分库分表及实践之路 | 京东云技术团队

3. sharing JDBC装备

spring.shardingsphere.enabled=true #shardingsphere开关 
spring.shardingsphere.props.sql.show=true 
spring.shardingsphere.mode.type=Standalone #在运用装备中心的情况下,运用standalone方式即可(memery、standalone、cluster三种方式) 
spring.shardingsphere.mode.repository.type=File #standalone方式下运用File,即当时装备文件 
spring.shardingsphere.mode.overwrite=true # 本地装备是否掩盖装备中心装备。假如可掩盖,每次发动都以本地装备为准。 
spring.shardingsphere.datasource.names=ds-0,ds-1 #装备数据源名字,真实数据源 
#装备ds-0数据源 
spring.shardingsphere.datasource.ds-0.jdbc-url=jdbc:mysql://**** 
spring.shardingsphere.datasource.ds-0.type=com.zaxxer.hikari.HikariDataSource 
spring.shardingsphere.datasource.ds-0.driver-class-name=com.mysql.jdbc.Driver 
spring.shardingsphere.datasource.ds-0.username= 
spring.shardingsphere.datasource.ds-0.password= 
#装备ds-1数据源 
spring.shardingsphere.datasource.ds-1.jdbc-url=jdbc:mysql://****
spring.shardingsphere.datasource.ds-1.type=com.zaxxer.hikari.HikariDataSource 
spring.shardingsphere.datasource.ds-1.driver-class-name=com.mysql.jdbc.Driver 
spring.shardingsphere.datasource.ds-1.username= 
spring.shardingsphere.datasource.ds-1.password= 
#装备方式数据库分片键和相关的表 
spring.shardingsphere.rules.sharding.default-database-strategy.standard.sharding-column=user_id 
spring.shardingsphere.rules.sharding.default-database-strategy.standard.sharding-algorithm-name=database-inline 
spring.shardingsphere.rules.sharding.binding-tables[0]=t_order,t_order_item 
spring.shardingsphere.rules.sharding.broadcast-tables=t_address #装备广播表,即一切库中都会同步增删的表 

以上是一些根本装备,还有一些事务场景装备,咱们能够参考开源社区文档: shardingsphere.apache.org/document/4.…

总结

对于具体事务场景,咱们首先是根据DDD的思维区分事务单元,最开端先做好笔直分库。接着是针对一些特定的事务添加量巨大的表,进行水平的分库处理,比方产品子域中的产品池表,订单子域中的订单表等等。

而在分表维度,事务初期,就要最好笔直分表的规划。比方产品池规划中,只需求存储联系信息,而产品概况的信息单独存储在一个底表之中。

作者:京东物流 赵勇萍

来源:京东云开发者社区