ShardingSphere JDBC 入门

314 阅读5分钟

版本号:ShardingSphere-5.0.0-beta

准备(源码下载)

# 结局 git clone 文件名太长
git config --global core.longpaths true

# 克隆
git clone git@github.com:apache/shardingsphere.git

# tag 代码的基础上做修改
git checkout -b beta_test 5.0.0-beta

概念

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

  • 适用于任何基于JDBC的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC。
  • 支持任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP等。
  • 支持任意实现JDBC规范的数据库。目前支持MySQL,Oracle,SQLServer,PostgreSQL以及任何遵循SQL92标准的数据库。

sharding-jdbc-brief.png

分库分表

背景

数据分片指按照某个维度将存放在单一数据库中的数据分散地存放至多个数据库或表中以达到提升性能瓶颈以及可用性的效果。数据分片的有效手段是对关系型数据库进行分库和分表。

辨析

  1. 分库和分表均可以有效的避免由数据量超过可承受阈值而产生的查询瓶颈
  2. 分库能够用于有效的分散对数据库单点的访问量
  3. 分布式事务涉及到跨库的更新操作往往变得复杂
  4. 分表无法缓解数据库压力,但却能够提供尽量将分布式事务转化为本地事务的可能

拆分方式

垂直分片

按照业务拆分的方式称为垂直分片,又称为纵向拆分,它的核心理念是专库专用。 在拆分之前,一个数据库由多个数据表构成,每个表对应着不同的业务。而拆分之后,则是按照业务将表进行归类,分布到不同的数据库中,从而将压力分散至不同的数据库。

根据业务需要,将用户表和订单表垂直分片到不同的数据库

image.png

衍生的问题

  • 垂直分片往往需要对架构和设计进行调整。通常来讲,是来不及应对互联网业务需求快速变化的;
  • 无法真正的解决单点瓶颈。垂直拆分可以缓解数据量和访问量带来的问题,但无法根治

水平分片

水平分片又称为横向拆分。相对于垂直分片,它不再将数据根据业务逻辑分类,而是通过某个字段(或某几个字段),根据某种规则将数据分散至多个库或表中,每个分片仅包含数据的一部分

主键分片

根据主键分片,偶数主键的记录放入 0 库(或表),奇数主键的记录放入 1 库(或表)

image.png

优点

从理论上突破了单机数据量处理的瓶颈,并且扩展相对自由,是分库分表的标准解决方案

读写分离

定义

将数据库拆分为主库和从库,主库负责处理事务性的增删改操作,从库负责处理查询操作。读写分离根据SQL语义的分析,将读操作和写操作分别路由至主库与从库。

用户表读写分离

image.png

对比水平分片

  • 读写分离的数据节点中的数据内容是一致的
  • 水平分片的每个数据节点的数据内容并不相同
  • 将水平分片和读写分离联合使用,能够更加有效的提升系统性能

挑战

  1. 数据不一致的
    • 多个主库之间的数据一致性
    • 主库与从库之间的数据一致性的问题
  2. 对数据库的操作和运维变得更加复杂,分库分表与读写分离一同使用时,应用程序与数据库集群之间的复杂拓扑关系如下:

image.png

数据加密

定义

数据加密是指对某些敏感信息通过加密规则进行数据的变形,实现敏感隐私数据的可靠保护。 涉及客户安全数据或者一些商业性敏感数据,如身份证号、手机号、卡号、客户号等个人信息按照相关部门规定,都需要进行数据加密。

业务场景

  1. 新业务上线,安全部门规定需将涉及用户敏感信息,例如银行、手机号码等进行加密后存储到数据库,在使用的时候再进行解密处理。因为是全新系统,因而没有存量数据清洗问题,所以实现相对简单。
  2. 已上线业务,之前一直将明文存储在数据库中。相关部门突然需要对已上线业务进行加密整改。这种场景一般需要处理 3 个问题:
    • 历史数据需要如何进行加密处理,即洗数。
    • 如何能在不改动业务SQL和逻辑情况下,将新增数据进行加密处理,并存储到数据库;在使用时,再进行解密取出。
    • 如何较为安全、无缝、透明化地实现业务系统在明文与密文数据间的迁移。

挑战

  • 加密场景发生改变时,自行维护的加密系统需要重构或修改
  • 对于已经上线的业务,在不修改业务逻辑和 SQL 的情况下,难以透明化、安全低风险地实现无缝进行加密改造

示例运行

分库分表 & 读写分离

spring.shardingsphere.datasource.names=ds

spring.shardingsphere.datasource.ds.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds.jdbc-url=jdbc:mysql://localhost:3306/demo_ds?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.datasource.ds.username=root
spring.shardingsphere.datasource.ds.password=

spring.shardingsphere.rules.sharding.tables.t_order.actual-data-nodes=ds.t_order_$->{0..1}
spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.standard.sharding-column=order_id
spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.standard.sharding-algorithm-name=t-order-inline

spring.shardingsphere.rules.sharding.tables.t_order.key-generate-strategy.column=order_id
spring.shardingsphere.rules.sharding.tables.t_order.key-generate-strategy.key-generator-name=snowflake

spring.shardingsphere.rules.sharding.tables.t_order_item.actual-data-nodes=ds.t_order_item_$->{0..1}
spring.shardingsphere.rules.sharding.tables.t_order_item.table-strategy.standard.sharding-column=order_id
spring.shardingsphere.rules.sharding.tables.t_order_item.table-strategy.standard.sharding-algorithm-name=t-order-item-inline

spring.shardingsphere.rules.sharding.tables.t_order_item.key-generate-strategy.column=order_item_id
spring.shardingsphere.rules.sharding.tables.t_order_item.key-generate-strategy.key-generator-name=snowflake

spring.shardingsphere.rules.sharding.binding-tables=t_order,t_order_item
spring.shardingsphere.rules.sharding.broadcast-tables=t_address

spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.type=INLINE
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.algorithm-expression=t_order_$->{order_id % 2}
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-item-inline.type=INLINE
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-item-inline.props.algorithm-expression=t_order_item_$->{order_id % 2}

spring.shardingsphere.rules.sharding.key-generators.snowflake.type=SNOWFLAKE
spring.shardingsphere.rules.sharding.key-generators.snowflake.props.worker-id=123

数据加密

spring.shardingsphere.datasource.names=ds

spring.shardingsphere.datasource.ds.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds.jdbc-url=jdbc:mysql://localhost:3306/demo_ds?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.datasource.ds.username=root
spring.shardingsphere.datasource.ds.password=

spring.shardingsphere.rules.encrypt.encryptors.name-encryptor.type=AES
spring.shardingsphere.rules.encrypt.encryptors.name-encryptor.props.aes-key-value=123456abc
spring.shardingsphere.rules.encrypt.encryptors.pwd-encryptor.type=AES
spring.shardingsphere.rules.encrypt.encryptors.pwd-encryptor.props.aes-key-value=123456abc

spring.shardingsphere.rules.encrypt.tables.t_user.columns.user_name.cipher-column=user_name
spring.shardingsphere.rules.encrypt.tables.t_user.columns.user_name.encryptor-name=name-encryptor
spring.shardingsphere.rules.encrypt.tables.t_user.columns.pwd.cipher-column=pwd
spring.shardingsphere.rules.encrypt.tables.t_user.columns.pwd.encryptor-name=pwd-encryptor

spring.shardingsphere.props.query-with-cipher-comlum=true
spring.shardingsphere.props.sql-show=true

TODO

  1. 在两台服务器上建立4个数据库,2主2从
  2. docker建立
  3. 建库建表,自行实现demo