shardingsphere简要介绍

可以做什么

分布式数据库 数据安全 数据库网关 全链路压测
数据分片 数据加密 异构数据库支持 影子库
读写分离 行级权限(TODO) SQL 方言转换(TODO) 可观测性
分布式事务 SQL 审计(TODO)
弹性伸缩 SQL 防火墙(TODO)
高可用

ShardingSphere-JDBC

本文基于当时最新版本5.1.0

定位为轻量级 Java 框架,在 Java 的 JDBC 层提供的额外服务。 它使用客户端直连数据库,以 jar 包形式提供服务,无需额外部署和依赖,可理解为增强版的 JDBC 驱动,完全兼容 JDBC 和各种 ORM 框架。

  1. 适用于任何基于 JDBC 的 ORM 框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template 或直接使用 JDBC;
  2. 支持任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, HikariCP 等;
  3. 支持任意实现 JDBC 规范的数据库,目前支持 MySQL,PostgreSQL,Oracle,SQLServer 以及任何可使用 JDBC 访问的数据库。
shardingsphere logo

分布式数据库漫谈

现在是互联网的时代,网络乘几何增长,随之而来的数据更是如此.铺天盖地的请求到来的是时候,首先是应用抗压,应用抗压以后,压力马上会到数据库,所以,对于数据库来说,
无论如何都是承受压力的点

所以,诞生了以下需求

  1. 高可用
  2. 高并发
  3. 海量数据

诞生了以下概念

  1. olap
  2. oltp
  3. htap(Hybrid transaction/analytical processing),上面两种混合,就是全能的意思

OLTP(on-line transaction processing)翻译为联机事务处理, OLAP(On-Line Analytical Processing)翻译为联机分析处理,从字面上来看OLTP是做事务处理,
OLAP是做分析处理。从对数据库操作来看,OLTP主要是对数据的增删改,OLAP是对数据的查询,olap的解决方案之一就是大数据

  1. 传统的关系型数据库都是单机的,当数据量大的时候,使用分库分表既可以简单的满足需求,这是其中的一种方案,典型的就是shardingsphere
  2. Greenplum把传统的关系型数据库集合到一起,提供统一的接口,自动形成分布式数据库
  3. tidb等,架构上就是分布式数据库,而不是传统的单机数据库通过调度实现分布式数据库

上面三种,第一种,实在应用层实现分布式数据库,具体的实现由中间件实现,剩下的两种都是本身就是分布式数据库,但是实现的方式不太一样,

我们了解到了,我们需要一个强大的数据库,来支撑应用,支撑业务

ShardingSphere-jdbc在应用层,以中间件的方式,让大家将几个数据库当成一个用,实现了分布式数据库,不过,一般称之为分库分表

快速入门

安装

项目我已经发布到gitee了 shardingsphere-demo

  1. maven添加依赖
    1
    2
    3
    4
    5
    <dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>shardingsphere-jdbc-core</artifactId>
    <version>5.1.0</version>
    </dependency>
  2. 规则配置,使用yaml配置
    1
    2
    props:
    sql-show: true # 可以显示sql,显示的格式很不错
  3. 创建数据源,注入数据源
  4. 接下来就是使用jdbc框架,如mybatis-plus
  5. 构造一些简单查询,就可以开始了

初探

简单分库查询

1
2
3
4
INFO  ShardingSphere-SQL - Logic SQL: SELECT id,teacherId,name FROM student WHERE id=? 
INFO ShardingSphere-SQL - SQLStatement: MySQLSelectStatement(table=Optional.empty, limit=Optional.empty, lock=Optional.empty, window=Optional.empty)
INFO ShardingSphere-SQL - Actual SQL: ds0 ::: SELECT id,teacherId,name FROM student WHERE id=? ::: [706168069961023488]
INFO ShardingSphere-SQL - Actual SQL: ds1 ::: SELECT id,teacherId,name FROM student WHERE id=? ::: [706168069961023488]

可以看到,一条sql自动分成了两个真实的sql,没错,该框架,就是通过改写sql实现了分库分表,这是它的基本思路

数据分片

虽然ShardingSphere支持很多功能,但是最重要的功能就是数据分片.

尽量透明化分库分表所带来的影响,让使用方尽量像使用一个数据库一样使用水平分片之后的数据库集群,是 Apache ShardingSphere 数据分片模块的主要设计目标。

逻辑表

相同结构的水平拆分数据库(表)的逻辑名称,是 SQL 中表的逻辑标识。 例:订单数据根据主键尾数拆分为 10 张表,分别是 t_order_0 到 t_order_9,他们的逻辑表名为 t_order。

真实表

在水平拆分的数据库中真实存在的物理表。 即上个示例中的 t_order_0 到 t_order_9。

绑定表

指分片规则一致的主表和子表。 使用绑定表进行多表关联查询时,必须使用分片键进行关联,否则会出现笛卡尔积关联或跨库关联,从而影响查询效率。

广播表

指所有的分片数据源中都存在的表,表结构及其数据在每个数据库中均完全一致。 适用于数据量不大且需要与海量数据的表进行关联查询的场景,例如:字典表。

单表

指所有的分片数据源中仅唯一存在的表。 适用于数据量不大且无需分片的表。

分片

分片算法

  1. 自动化分片算法
  2. 自定义分片算法

分片策略
包含分片键和分片算法,由于分片算法的独立性,将其独立抽离。 真正可用于分片操作的是分片键 + 分片算法,也就是分片策略。

强制分片路由
对于分片字段并非由 SQL 而是其他外置条件决定的场景,可使用 SQL Hint 注入分片值。

内置分片算法

其实分片,就是尽量把数据均匀的分散开来,越平均越好

自动分片算法
  1. 取模分片算法 针对整形
  2. 哈希取模分片算法 针对字符串类型
  3. 基于分片容量的范围分片算法 需要针对一个个真实表设置,比较麻烦,暂时没有想到场景
  4. 基于分片边界的范围分片算法 没看懂
  5. 自动时间段分片算法 特别适合对时间敏感的业务,比如当前月的数据经常使用,但是除了当月的以前的数据,基本就是存档,然后所有的查询都加上分片,相当于数据自动归档了,非常方便
标准分片算法
  1. 行表达式分片算法 如t_user_$->{u_id % 8}
  2. 时间范围分片算法 适合时间敏感的业务
复合分片算法

多个列一起分片,功能强大,但是尽量少用,越简单满足业务一般越好

Hint 分片算法

使用行表达式进行分片

自定义类分片算法

自己写代码定义,然后配置

较佳实践

垂直还是水平

shardingsphere,功能非常强大,垂直和水平直接都支持,而且还非常方便,所以,我们使用的时候,直接使用即可,
比如,需要两个库,一个库放系统数据,比如用户表,权限表之类的,一个库放业务数据,比如订单,商品等等,就可以垂直分库,
如果一个表比较大,那么水平拆分成多个小表即可

分库还是分表

分库
数据库应用应该是io和计算都很密集,一方面,需要io查找数据,另一方面需要在内存中计算数据,所以,相对来说,很吃cpu,
所以,一般,数据库应用本身,再高并发场景下,都是一台机器部署一个数据库,所以,分库可以吃多个机器的资源,可以更好的支持并发
分表
因为数据库本身的设计原因和机器资源的原因,单表数据量大到一定程度以后,性能会不断下降,数据量越大,越不可忍受,所以,
出现了分表的需求,分表就是在资源不变的情况下,通过减少单表的数据量,增加数据库的查询性能
总结
如果你的并发要求不是很高,而且你的业务对时间敏感,老的数据放到老的表,不影响新的数据查询,那么分表就是很好的选择,
如果你的并发要求很高,分表以后,一个机器的计算资源还是不能满足你的业务,那么就妥妥的需要分库,所以,分库比分表更能提高并发,但是
分表也能更好的发挥单机的价值,不是冲突的,而是相辅相成的,不是意味着,我分库了,就不需要分表了,而是分库以后,也需要分表,相辅相成

数据分片的选择

分片选择原则

  1. 简单性,能一个列分片,就一个列分片,用最简单的方式满足业务,差不多就是最好的方式
  2. 内置性,尽量使用shardingsphere内置的算法,或许有优化吧,不过,这得看代码了

对于大多应用来说,使用时间分片都是一个非常不错的选择,大多数系统只关心最近的数据,以往的数据只是存档使用,这样的话,非常适合时间分片,
如果一个库不够的话,数字类型就用取模分片分库,字符串类型就用hash分片分库

分页优化

众所周知,数据量大的时候分页,性能非常差,主要原因就是查1一亿条,排序完,最后只用10条,显然很慢,所以说,不能把那一亿条查出来,
理想的方案是记录上次的id,然后只查10条数据,如下所示

1
SELECT * FROM t_order WHERE id > 100000 LIMIT 10

总结

shardingSphere最重要的功能是数据分片,数据分片最重要的功能是分片算法,只要这两个吃透,差不多shardingSphere你就掌握了60%了