Sharding Sphere,Sharding JDBC学习笔记

洪弘壮
2023-12-01

Sharding Sphere,Sharding JDBC学习笔记

1、什么是 ShardingSphere?

  • 一套开源的分布式数据库中间件解决方案

  • 有三个产品:Sharding-JDBC 和 Sharding-Proxy

  • 定位为关系型数据库中间件,合理在分布式环境下使用关系型数据库操作

2、什么是分库分表?

开发中遇到的问题:

​ 数据库数据量不可控的,随着时间和业务发展,造成表里面数据越来越多,如果再去对数

据库表 curd 操作时候,造成性能问题。

**方案一:**从硬件方面,加CPU加服务器等,缺点是成本高,维护麻烦。

**方案二:**进行分库分表处理。

分库分表有两种方式:垂直切分和水平切分

垂直分库、垂直分表:

​ 操作数据库中某张表,把这张表中一部分字段数据存到一张新表里面,再把这张表另一部分字段数据存到另外一张表里面,例如:一张表中有7个字段,将4个字段存到一张表,剩下3个存到另一张表中,这种操作就叫做垂直分表。

​ 将数据库根据业务进行划分,专库专表,这种操作就叫做垂直分库。

水平分库、水平分表:

​ 水平分表就是将创建一个与业务表相同的表,在进行数据操作的时候可以根据某些条件进行判断去操作哪张表,就像是复制出几个相同的表,这样在数据量大的情况下减少了操作数据库的压力。水平分库也是类似于复制。

实际开发中的应用:

  • 在数据库设计时候考虑垂直分库和垂直分表 。

  • 随着数据库数据量增加,不要马上考虑做水平切分,首先考虑缓存处理,读写分离,使

用索引等等方式,如果这些方式不能根本解决问题了,再考虑做水平分库和水平分表 。

分库分表问题:

  • 跨节点连接查询问题(分页、排序)

  • 多数据源管理问题

3、Sharding JDBC实现水平分表(SpringBoot)

一、创建数据库并在数据库中创建两张字段相同的表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9AUYadqE-1670315836922)(C:\Users\52962\AppData\Roaming\Typora\typora-user-images\1670295502651.png)]

二、创建SpringBoot项目并引入相关依赖

	<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.20</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
            <version>4.0.0-RC1</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.0.5</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

三、配置文件

这里使用的是properties类型的配置文件,查看官网目前只有yaml文件类型的配置,这个待尝试。

# shardingjdbc 分片策略
# 配置数据源,给数据源起名称
spring.shardingsphere.datasource.names=master

#解决一个实体类对应两张表
spring.main.allow-bean-definition-overriding=true

# 配置数据源,这里使用阿里的德鲁伊数据源
spring.shardingsphere.datasource.master.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.master.url=jdbc:mysql://121.xx.xx.xxx:3306/course_db?characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.master.username=root
spring.shardingsphere.datasource.master.password=root

#指定 course 表分布情况,配置表在哪个数据库里面,表名称都是什么 master.course_1 ,master.course_2
spring.shardingsphere.sharding.tables.course.actual-data-nodes=master.course_$->{1..2}

# 指定 course 表里面主键 cid 生成策略 SNOWFLAKE,雪花算法
spring.shardingsphere.sharding.tables.course.key-generator.column=cid
spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE

# 指定分片策略 约定 cid 值偶数添加到 course_1 表,如果 cid 是奇数添加到 course_2表
spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=cid
spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{cid % 2 + 1}

# 打开 sql 输出日志
spring.shardingsphere.props.sql.show=true

四、数据表中插入数据

@Test
    void insertCourse() {
        for (int i = 0; i < 10; i++) {
            Course course = new Course();
            course.setCname("测试数据" + i);
            course.setUserId(333445L);
            course.setCstaus("测试状态" + i);
            courseService.save(course);
        }
    }

插入数据效果如下,id为偶数的插入到了1表中,为奇数的插入到了2表中,达到了理想效果。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6V1sm5Kc-1670315836924)(C:\Users\52962\AppData\Roaming\Typora\typora-user-images\1670296529597.png)]

五、遇到的问题

(1)启动时报如下图所示的错误,出现这个问题的原因是因为我们创建了一个实体类,而它对应着两张表,spring提示我们要么重新命名要么进行覆盖配置,我们选择配置。在配置文件中添加:

#解决一个实体类对应两张表
spring.main.allow-bean-definition-overriding=true

报错图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CLKIuvxL-1670315836924)(C:\Users\52962\AppData\Roaming\Typora\typora-user-images\1670294423736.png)]

(2)修改完实体类的问题,启动项目又报了如下错误,原因是因为我们在设置数据源的url时没有配置全面,配置应该如下图所示,其中"characterEncoding=UTF-8"为配置字符集编码,设置"useSSL=false",SSL即为:Secure Sockets Layer 安全套接字协议。如果MySQL的版本是5.7之后的版本必须要加上useSSL=false,mysql5.7以及之前的版本则不用进行添加useSSL=false,会默认为false,一般情况下都是使用useSSL=false,尤其是在将项目部署到linux上时要使用useSSL=false。

  • useSSL=true:就是一般通过证书或者令牌进行安全验证

  • useSSL=false:就是通过账号密码进行连接

"serverTimezone=Asia/Shanghai"为设置时区,MySQL8.0以上版本,url需要添加时区。

以上就是解决问题的方法,具体配置如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5Ju0ISKU-1670315836925)(C:\Users\52962\AppData\Roaming\Typora\typora-user-images\1670294971105.png)]

报错图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V6DTD83d-1670315836925)(C:\Users\52962\AppData\Roaming\Typora\typora-user-images\1670295176183.png)]

4、Sharding JDBC实现水平分库

数据库创建两个数据库db1和db2并且每个都创建两个字段相同的表,代码只需要修改配置文件即可,在上面操作的基础上进行修改。

配置文件如下

spring.shardingsphere.datasource.names=master1,master2

#解决一个实体类对应两张表
spring.main.allow-bean-definition-overriding=true

# 配置数据源,这里使用阿里的德鲁伊数据源
spring.shardingsphere.datasource.master1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.master1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.master1.url=jdbc:mysql://121.4.49.xx:3306/db1?characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.master1.username=root
spring.shardingsphere.datasource.master1.password=root

spring.shardingsphere.datasource.master2.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.master2.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.master2.url=jdbc:mysql://121.4.49.xx:3306/db2?characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.master2.username=root
spring.shardingsphere.datasource.master2.password=root

#指定 course 表分布情况,配置表在哪个数据库里面,表名称都是什么 master.course_1 ,master.course_2
spring.shardingsphere.sharding.tables.course.actual-data-nodes=master$->{1..2}.course_$->{1..2}

# 指定 course 表里面主键 cid 生成策略 SNOWFLAKE,雪花算法
spring.shardingsphere.sharding.tables.course.key-generator.column=cid
spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE

# 指定分片策略 约定 cid 值偶数添加到 course_1 表,如果 cid 是奇数添加到 course_2表
spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=cid
spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{cid % 2 + 1}

# 指定数据库分片策略
spring.shardingsphere.sharding.tables.course.database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.course.database-strategy.inline.algorithm-expression=master$->{user_id % 2 + 1}

# 打开 sql 输出日志
spring.shardingsphere.props.sql.show=true

垂直分库和垂直分表也都是进行类似的配置,可以参考官方文档:

https://shardingsphere.apache.org/document/current/cn/overview/

5、Sharding-JDBC实现读写分离

什么是读写分离?

​ 读写分离就是让主数据库进行事务性操作,增、删、改操作,让从数据库进行查询操作。数据库将主数据库中的事务性操作数据同步到其他从数据库当中。原理是从库监听binlog日志,将对进行的增删改操作进行同步。

表也都是进行类似的配置,可以参考官方文档:

https://shardingsphere.apache.org/document/current/cn/overview/

5、Sharding-JDBC实现读写分离

什么是读写分离?

​ 读写分离就是让主数据库进行事务性操作,增、删、改操作,让从数据库进行查询操作。数据库将主数据库中的事务性操作数据同步到其他从数据库当中。原理是从库监听binlog日志,将对进行的增删改操作进行同步。

 类似资料: