为什么会选择阅读ShardingSphere的源码呢?其实可以说机缘巧合下,在之前报的课程中有人带,并且是一个小团体进行阅读还有分享的,并且以前没有源码阅读经验,这次参与刚好作为一次开始,大家互相监督可以坚持下去这是最重要的。
引用老师说的一句话:“一个人可以走很快,一群人却可以走很远”,坚持努力总不会错的,共勉!
想学习一样新的东西,无非就是以下五步,前四步就够,第五步就是看个人的了
ShardingSphere有JDBC,Proxy和UI三部分,分别看看
ShardingSphere的demo发现了五种不同的类型:
实例化代码如下:
public static DataSource newInstance(final ShardingType shardingType) throws SQLException { switch (shardingType) { case SHARDING_DATABASES: return new ShardingDatabasesConfigurationPrecise().getDataSource(); case SHARDING_TABLES: return new ShardingTablesConfigurationPrecise().getDataSource(); case SHARDING_DATABASES_AND_TABLES: return new ShardingDatabasesAndTablesConfigurationPrecise().getDataSource(); case READWRITE_SPLITTING: return new ReadwriteSplittingConfiguration().getDataSource(); case SHARDING_READWRITE_SPLITTING: return new ShardingReadwriteSplittingConfigurationPrecise().getDataSource(); default: throw new UnsupportedOperationException(shardingType.name()); } }
根据不同的shardingType去选择实例化数据源,里面处理实例化数据源之外,还需要分库分表,读写分离等规则,这些规则决定了如何实现相应的功能,选择分库分表作为解析,代码如下:
private ShardingRuleConfiguration createShardingRuleConfiguration() { ShardingRuleConfiguration result = new ShardingRuleConfiguration(); //不同表的分表规则,第一个是order表 result.getTables().add(getOrderTableRuleConfiguration()); //这个是order_item表 result.getTables().add(getOrderItemTableRuleConfiguration()); //分表的所有logic表放到这个组中 result.getBindingTableGroups().add("t_order, t_order_item"); result.getBroadcastTables().add("t_address"); result.setDefaultDatabaseShardingStrategy(new StandardShardingStrategyConfiguration("user_id", "inline")); result.setDefaultTableShardingStrategy(new StandardShardingStrategyConfiguration("order_id", "standard_test_tbl")); Properties props = new Properties(); //分库算法,具体基于哪个字段作为分库标志 props.setProperty("algorithm-expression", "demo_ds_${user_id % 2}"); result.getShardingAlgorithms().put("inline", new ShardingSphereAlgorithmConfiguration("INLINE", props)); result.getShardingAlgorithms().put("standard_test_tbl", new ShardingSphereAlgorithmConfiguration("STANDARD_TEST_TBL", new Properties())); //自动key生成使用什么算法,这里使用雪花算法 result.getKeyGenerators().put("snowflake", new ShardingSphereAlgorithmConfiguration("SNOWFLAKE", getProperties())); return result; } private static ShardingTableRuleConfiguration getOrderTableRuleConfiguration() { ShardingTableRuleConfiguration result = new ShardingTableRuleConfiguration("t_order", "demo_ds_${0..1}.t_order_${[0, 1]}"); result.setKeyGenerateStrategy(new KeyGenerateStrategyConfiguration("order_id", "snowflake")); return result; } private static ShardingTableRuleConfiguration getOrderItemTableRuleConfiguration() { ShardingTableRuleConfiguration result = new ShardingTableRuleConfiguration("t_order_item", "demo_ds_${0..1}.t_order_item_${[0, 1]}"); result.setKeyGenerateStrategy(new KeyGenerateStrategyConfiguration("order_item_id", "snowflake")); return result; } private static Map<String, DataSource> createDataSourceMap() { //具体需要绑定多少个数据源,每个数据源都需要写入map Map<String, DataSource> result = new HashMap<>(); result.put("demo_ds_0", DataSourceUtil.createDataSource("demo_ds_0")); result.put("demo_ds_1", DataSourceUtil.createDataSource("demo_ds_1")); return result; } private static Properties getProperties() { Properties result = new Properties(); result.setProperty("worker-id", "123"); return result; }
其实上述的参数在官网都能找到,也有教如何配置,这个就是ShardingSphere-JDBC的API接口实现,根据官网参数和修改参数去多跑几次Demo,可以更清晰每一个有用的参数,其它的shardingType基本都是大同小异
配置文件主要就是yaml(可以写成yml)文件,用配置文件写好数据源和规则,加载配置文件就可以,这些配置属性在ShardingSphere官网也是有的,可以参考官方文档
dataSources: ds_0: dataSourceClassName: com.zaxxer.hikari.HikariDataSource driverClassName: com.mysql.jdbc.Driver jdbcUrl: jdbc:mysql://localhost:3306/demo_ds_0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8 username: root password: ds_1: dataSourceClassName: com.zaxxer.hikari.HikariDataSource driverClassName: com.mysql.jdbc.Driver jdbcUrl: jdbc:mysql://localhost:3306/demo_ds_1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8 username: root password: rules: # 重点:这个就是控制这个yaml文件实现那个功能的,-!SHARDING 就是分库分表规则 - !SHARDING tables: t_order: actualDataNodes: ds_${0..1}.t_order_${0..1} tableStrategy: standard: shardingColumn: order_id shardingAlgorithmName: t_order_inline keyGenerateStrategy: column: order_id keyGeneratorName: snowflake t_order_item: actualDataNodes: ds_${0..1}.t_order_item_${0..1} tableStrategy: standard: shardingColumn: order_id shardingAlgorithmName: t_order_item_inline keyGenerateStrategy: column: order_item_id keyGeneratorName: snowflake bindingTables: - t_order,t_order_item broadcastTables: - t_address defaultDatabaseStrategy: standard: shardingColumn: user_id shardingAlgorithmName: database_inline defaultTableStrategy: none: shardingAlgorithms: database_inline: type: INLINE props: algorithm-expression: ds_${user_id % 2} t_order_inline: type: INLINE props: algorithm-expression: t_order_${order_id % 2} t_order_item_inline: type: INLINE props: algorithm-expression: t_order_item_${order_id % 2} keyGenerators: snowflake: type: SNOWFLAKE props: worker-id: 123 props: sql-show: false
至于加密Encrypt_Databases其实和其他区别不大,只不过需要注意支持的加密算法,和配置算法的规则,这些在官方文档都可以查到,不展开来讲了
由于ShardingSphere-JDBC每次修改都需要重新package jar包,才能生效,在维护方面不是很便利,所以就出现了ShardingSphere-Proxy,proxy是一个中间件,需要单独启动一个服务才能使用,也是使用配置文件yaml实现功能的,一共需要两份及以上的配置文件
#mode: # type: Cluster # repository: # type: ZooKeeper # props: # namespace: governance_ds # serverLists: localhost:2181 # retryIntervalMilliseconds: 500 # timeToLiveSeconds: 60 # maxRetries: 3 # operationTimeoutMilliseconds: 500 # overwrite: false rules: #重点,这个是proxy的logic表,可以连接的,用这个表关联实体表,统一从这里进行操作就可以了 - !AUTHORITY users: - root@:root - sharding@:sharding provider: type: NATIVE props: max-connections-size-per-query: 1 executor-size: 16 # Infinite by default. proxy-frontend-flush-threshold: 128 # The default value is 128. # LOCAL: Proxy will run with LOCAL transaction. # XA: Proxy will run with XA transaction. # BASE: Proxy will run with B.A.S.E transaction. proxy-transaction-type: LOCAL proxy-opentracing-enabled: false proxy-hint-enabled: false sql-show: false check-table-metadata-enabled: false
从上面配置看到一大段给注释的配置,看得出是有关集群的,还是使用ZooKeeper进行服务注册发现的
这些配置就是关于分库分表,读写分离等的规则的配置文件,可以直接复用ShardingSphere—JDBC配置文件,其实是一致的,如果有修改需要重启
启动proxy前,把所有配置都完成后,直接启动,然后业务代码那边的数据源,配置为proxy的server.yaml的logic库表就可以和正常数据库一样使用了
在ShardingSphere-Proxy中提到两个点,一是proxy是独立运行的中间件服务,二是留了一个注释的配置,是关于集群的。
有关第一点,单个服务就会有不可用的时候,那么当proxy服务不可用时,业务也不可用了,所以就需要高可用,引入第二点,搭配ZooKeeper实现集群达到高可用,而ShardingSphere-UI就是用可视化界面对上述的进行管理,并且是实时更新配置文件的,刷新后即可用,这是ShardingSphere-JDBC和ShardingSphere-Proxy所不能达到的,具体如下图
先要阅读源码,首先去跑一下官方的Demo,目的是对ShardingSphere有一定的熟悉后,才能开展后续,当然有ShardingSphere的开发使用经验的人可以省略此步,在这个过程中把思考一下怎么实现的,为什么这样实现的,然后记录这些问题,带到后面源码阅读中去查找答案,会发现阅读起来才会有感觉,不然根本不知道如何下手,怎么去阅读,那么就很难坚持下去,而我因为有小组鞭策,并且交流方法,并且找到适合自己阅读源码方式,坚持下了,后面就是关于源码阅读的文章了。带着问题去阅读总不会比其他办法更加差了。