ShardingSphere源码分析(一) ShardingJDBC使用


环境准备

这次的分享偏使用, 不探索 ShardingSphere 的代码过程 ( 实际是我还没编译通过… )

主要准备是 MySQL 主从环境, 我这里直接在 windows 上安装 mysql 5.7, 并拷贝了一份当做从库, 链接如下: https://blog.csdn.net/a345203172/article/details/106911270

更加方便的方式是启动 docker 来做一主多从的环境.


读写分离

在 ShardingSphere-5.0.0-alpha 中我是使用这样一段代码来实现读写分离:

@Bean(name = "dataSource")
public DataSource getDataSource() throws SQLException {
    // 创建主从库数据源连接池
    Map<String, DataSource> dataSourceMap = new HashMap<>();
    dataSourceMap.put("master", DataSourceUtil.createDataSource(url_master));
    dataSourceMap.put("slave", DataSourceUtil.createDataSource(url_slave));

    // 创建主从配置信息类
    ReplicaQueryDataSourceRuleConfiguration dataSourceConfig = new ReplicaQueryDataSourceRuleConfiguration(
        "master_slave_datasource", "master",
        Arrays.asList("slave"), null);
    // 创建规则配置类
    ReplicaQueryRuleConfiguration ruleConfig = new ReplicaQueryRuleConfiguration(
        Collections.singleton(dataSourceConfig), Collections.emptyMap());

    // 工厂获得数据源
    return ShardingSphereDataSourceFactory.createDataSource(dataSourceMap, Collections.singleton(ruleConfig), new Properties());
}

这里的核心是 ReplicaQueryRuleConfiguration 类, 可以配置主从的查询规则 (一主N从), 也可以配置从库的负载均衡策略 (我这里的代码是传入空集合, 使用默认的轮训策略).

然而在 5.0.0-beta 版中, 这块的内容是有所变化, 改后的代码如下:

@Bean(name = "dataSource")
public DataSource getDataSource() throws SQLException {
    // 创建主从库数据源连接池
    Map<String, DataSource> dataSourceMap = new HashMap<>();
    dataSourceMap.put("master", DataSourceUtil.createDataSource(url_master));
    dataSourceMap.put("slave", DataSourceUtil.createDataSource(url_slave));

    // 创建主从配置信息类
    ReadwriteSplittingDataSourceRuleConfiguration dataSourceConfig = new ReadwriteSplittingDataSourceRuleConfiguration(
        "master_slave_datasource", "", "master",
        Arrays.asList("slave"), null);
    // 创建规则配置类
    ReadwriteSplittingRuleConfiguration ruleConfig = new ReadwriteSplittingRuleConfiguration(
        Collections.singleton(dataSourceConfig), Collections.emptyMap());

    // 工厂获得数据源
    return ShardingSphereDataSourceFactory.createDataSource(dataSourceMap, Collections.singleton(ruleConfig), new Properties());
}

ReplicaQueryRuleConfiguration 类被 ReadwriteSplittingRuleConfiguration 取代, ReplicaQueryDataSourceRuleConfiguration类被 ReadwriteSplittingDataSourceRuleConfiguration 取代. 看上去优化点就像把名字写的更加通俗易懂了些.

唯一一个不同点是在主从数据源配置类 ReadwriteSplittingDataSourceRuleConfiguration 中新加入了一个参数 autoAwareDataSourceName, 暂不清楚什么作用, 依照官方例子传入空字符串即可.


分库分表

准备好两个库, 做分库演示.
在这里插入图片描述

根据官方文档的示例, 使用两个字段 user_id 与 order_id 分别来控制 分库与分表 的分片算法依据, 具体代码如下:

@Bean(name = "dataSource")
public DataSource getDataSource() throws SQLException {
    // 创建主从库数据源连接池
    Map<String, DataSource> dataSourceMap = new HashMap<>();
    dataSourceMap.put("ds0", DataSourceUtil.createDataSource(url_ds0));
    dataSourceMap.put("ds1", DataSourceUtil.createDataSource(url_ds1));

    // 配置 t_order 表规则
    ShardingTableRuleConfiguration orderTableRuleConfig = new ShardingTableRuleConfiguration("t_order", "ds${0..1}.t_order${0..1}");
    // 配置分库策略
    orderTableRuleConfig.setDatabaseShardingStrategy(new StandardShardingStrategyConfiguration("user_id", "dbShardingAlgorithm"));
    // 配置分表策略
    orderTableRuleConfig.setTableShardingStrategy(new StandardShardingStrategyConfiguration("order_id", "tableShardingAlgorithm"));

    // 配置分片规则
    ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
    shardingRuleConfig.getTables().add(orderTableRuleConfig);

    // 配置分库算法
    Properties dbShardingAlgorithmrProps = new Properties();
    dbShardingAlgorithmrProps.setProperty("algorithm-expression", "ds${user_id % 2}");
    shardingRuleConfig.getShardingAlgorithms().put("dbShardingAlgorithm", new ShardingSphereAlgorithmConfiguration("INLINE", dbShardingAlgorithmrProps));
    // 配置分表算法
    Properties tableShardingAlgorithmrProps = new Properties();
    tableShardingAlgorithmrProps.setProperty("algorithm-expression", "t_order${order_id % 2}");
    shardingRuleConfig.getShardingAlgorithms().put("tableShardingAlgorithm", new ShardingSphereAlgorithmConfiguration("INLINE", tableShardingAlgorithmrProps));

    // 创建 ShardingSphereDataSource
    DataSource dataSource = ShardingSphereDataSourceFactory.createDataSource(dataSourceMap, Collections.singleton(shardingRuleConfig), new Properties());
    return dataSource;
}

最终创建所使用的仍然是 ShardingSphereDataSourceFactory 工厂的 createDataSource() 方法, 而数据分片与读写分离相同的入参也提醒我们, 分片规则类 ShardingRuleConfiguration 与 读写分离规则类 ReadwriteSplittingRuleConfiguration 是源自同一个接口 RuleConfiguration , 他们在 ShardingSphere 下都属于规则衍生类.


分库的效果是: db0 与 db1 下的 t_order1 都新增一行数据

分表的效果是: db1下的 t_order_0 与 t_order_1 新增一行数据.
在这里插入图片描述


加密

加密这块有两种处理方式, 一种是会在原字段上直接存储密文, 另一种是需要创建一个密文字段, ShardingSphere 会帮你同时存两者.


我这里的演示是选择第二种, 准备数据库表时, 需要准备明文与密文字段:
在这里插入图片描述

代码实现上, 我们同样看到与加密相关的规则类是 EncryptRuleConfiguration, 根据它所需的参数, 一层层配齐即可:

@Bean(name = "dataSource")
public DataSource getDataSource() throws SQLException {
    Map<String, DataSource> dataSourceMap = new HashMap<>();
    dataSourceMap.put("encryption", DataSourceUtil.createDataSource(url_encryption));

    // 	逻辑列名称
    String logicColumn = "pwd";
    // 密文列名称
    String cipherColumn = "pwd_cipher";
    // 原文列名称
    String plainColumn = "pwd";
    // 加密算法名称
    String encryptorName = "aes_encryptor";

    // 加密列规则配置
    EncryptColumnRuleConfiguration encryptColumnRuleConfiguration = new EncryptColumnRuleConfiguration(logicColumn, cipherColumn, "", plainColumn, encryptorName);

    // 加密表规则配置
    EncryptTableRuleConfiguration encryptTableRuleConfiguration = new EncryptTableRuleConfiguration("t_user", Collections.singleton(encryptColumnRuleConfiguration));

    // 加密算法配置
    Properties properties = new Properties();
    properties.setProperty("aes-key-value", "123456ac");
    ShardingSphereAlgorithmConfiguration shardingSphereAlgorithmConfiguration = new ShardingSphereAlgorithmConfiguration("AES", properties);
    Map<String, ShardingSphereAlgorithmConfiguration> shardingSphereAlgorithmConfigurationMap = Collections.singletonMap("aes_encryptor", shardingSphereAlgorithmConfiguration);

    // 配置规则
    EncryptRuleConfiguration encryptRuleConfiguration = new EncryptRuleConfiguration(Collections.singleton(encryptTableRuleConfiguration), shardingSphereAlgorithmConfigurationMap);

    // 创建 ShardingSphereDataSource
    DataSource dataSource = ShardingSphereDataSourceFactory.createDataSource(dataSourceMap, Collections.singleton(encryptRuleConfiguration), new Properties());
    return dataSource;
}

那么在存储时可以看到, ShardingSphere 帮助存储了密文:
在这里插入图片描述

而在读取时, 根据我们所配置的逻辑列, 仍然可以得到明文信息:
在这里插入图片描述


小结

这次是对 ShardingSphere-JDBC 的三个主要功能模块进行实际使用, 且也只是使用的 Java API 方式. 但这样的使用应该是更直观的能感觉到 ShardingSphere-JDBC 的设计, 它将规则进行了统一的抽象, 由工厂类负责装载返回数据源.

我对探究这个工厂类的实现是挺有兴趣的, 之后可以进行源码分析.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值