美文网首页分布式服务
分库分表第二篇之使用Sharding-Jdbc

分库分表第二篇之使用Sharding-Jdbc

作者: 小螺丝钉cici | 来源:发表于2020-05-27 18:09 被阅读0次

一.Java使用Sharding-Jdbc
二.Yaml使用Sharding-Jdbc 【普遍用这种】

一.Java使用Sharding-Jdbc
  1. 通过Druid构建数据源.
  2. 通过ShardingDataSourceFactory 构建分片数据源.
  • 创建一个方法获取getShardingDataSource
  • 定义数据源集合数据源集合:dataSourceMap
  • 定义表规则
  • 定义分片规则

/**
 * 1. 通过Druid构建数据源.
 * 2. 通过ShardingDataSourceFactory 构建分片数据源.
 * 3. 编写测试例子: 通过DataSource获取到Connection.
 * @author linxiangxian
 *
 */
public class Demo1 {

    /**
     * 1. 通过Druid构建数据源.
     * @return
     */
    public DataSource createDataSource(String url, String username, String password) {
        DruidDataSource ds = new DruidDataSource();
        /*
         * driver : 数据库驱动.
         * url: 数据库地址
         * username/pwd : 账号和密码.
         */
        ds.setDriverClassName(Driver.class.getName());
        ds.setUrl(url);
        ds.setUsername(username);
        ds.setPassword(password);

        return ds;
    }

    /**
     * 2. 通过ShardingDataSourceFactory 构建分片数据源.
     * @return
     * @throws SQLException
     */
    public DataSource getShardingDataSource() throws SQLException {
        /*
         * 1. 数据源集合:dataSourceMap
         *
         * 2. 分片规则:shardingRuleConfig
         *
         */

        //1. 数据源集合:dataSourceMap
        Map<String,DataSource> dataSourceMap = new HashMap<String, DataSource>();
        //添加数据源.两个数据源ds_0和ds_1
        dataSourceMap.put("ds_0", createDataSource("jdbc:mysql://localhost:3306/ds_0", "root", "123456"));
        dataSourceMap.put("ds_1", createDataSource("jdbc:mysql://localhost:3306/ds_1", "root", "123456"));
        //说明:这里定义了多个数据源集合,最终是设置到ShardingDataSourceFactory进行统一管理。

        /*
         * 需要构建表规则
         * 1. 指定逻辑表.
         * 2. 配置实际节点》
         * 3. 指定主键字段.
         * 4. 分库和分表的规则》
         */
        /*
         * 这里配置了表:t_order
         * ds_0和ds_1
         * t_order_0 和 t_order_1 构成
         *
         * (order_id,user_id,status)
         *
         * 表的分片策略 order_id
         * 库的分片策略 user_id
         */
        TableRuleConfiguration orderTableRuleConfiguration = new TableRuleConfiguration();
        orderTableRuleConfiguration.setLogicTable("t_order");
        //ds_0.t_order_0 , ds_0.t_order_1, ds_1.t_order_0 , ds_1.t_order_1
        orderTableRuleConfiguration.setActualDataNodes("ds_${0..1}.t_order_${0..1}");
        orderTableRuleConfiguration.setKeyGeneratorColumnName("order_id");

        //表的分片策略.t_order_0,t_order_1
        orderTableRuleConfiguration.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("order_id", "t_order_${order_id%2}") );
        orderTableRuleConfiguration.setDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("user_id", "ds_${user_id%2}") );

        //分片规则:shardingRuleConfig
        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
        shardingRuleConfig.getTableRuleConfigs().add(orderTableRuleConfiguration);
        //shardingRuleConfig.setDefaultDatabaseShardingStrategyConfig(defaultDatabaseShardingStrategyConfig);

        DataSource ds = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, new HashMap<String, Object>(), new Properties());
        return ds;
    }

    /**
     * 3. 编写测试例子: 通过DataSource获取到Connection.
     * @param args
     * @throws SQLException
     */
    public static void main( String[] args ) throws SQLException {

        /*
         * 1. 需要到DataSource
         * 2. 通过DataSource获取Connection
         * 3. 定义一条SQL语句.
         * 4. 通过Connection获取到PreparedStament.
         * 5. 执行SQL语句.
         * 6. 关闭连接.
         */
        Demo1 app = new Demo1();

//      * 1. 需要到DataSource
        DataSource dataSource = app.getShardingDataSource();

//       * 2. 通过DataSource获取Connection
        Connection connection = dataSource.getConnection();
//       * 3. 定义一条SQL语句.
        String sql = "insert into t_order(user_id,status) values(1000,'insert')";
        //String sql = "insert into t_order(order_id,user_id,status) values(10,1000,'insert')";

//       * 4. 通过Connection获取到PreparedStament.
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

//       * 5. 执行SQL语句.
        preparedStatement.execute();

        //user_id =1000 的话,会被添加到ds0  ,1001 -->ds1
        connection = dataSource.getConnection();
        sql = "insert into t_order(user_id,status) values(1001,'insert')";
        //String sql = "insert into t_order(order_id,user_id,status) values(11,1000,'insert')";
        preparedStatement = connection.prepareStatement(sql);
        preparedStatement.execute();

//       * 6. 关闭连接.
        preparedStatement.close();
        connection.close();
    }

pom.xml

 <!--数据源-->
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>druid</artifactId>
             <version>1.0.26</version>
         </dependency>

         <dependency>
             <groupId>io.shardingjdbc</groupId>
             <artifactId>sharding-jdbc-core</artifactId>
             <version>2.0.3</version>
         </dependency>

二.Yaml使用Sharding-Jdbc 【普遍用这种】

sharding.yaml

# 数据源配置
dataSources:
  #可配置多个: !!数据库连接池实现类
  ds_0: !!com.alibaba.druid.pool.DruidDataSource
    #数据库驱动类名
    driverClassName: com.mysql.jdbc.Driver
    #数据库url连接
    url: jdbc:mysql://localhost:3306/ds_0
    #数据库用户名
    username: root
    #数据库密码
    password: 123456
  ds_1: !!com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/ds_1
    username: root
    password: 123456
    
 #分库分表配置,可配置多个logic_table_name
shardingRule:
  tables:
    t_order:
      keyGeneratorColumnName: order_id
      actualDataNodes: ds_${0..1}.t_order_${0..1}
      databaseStrategy: 
        inline:
          shardingColumn: user_id
          algorithmExpression: ds_${user_id % 2}
      tableStrategy: 
        inline:
          shardingColumn: order_id
          algorithmExpression: t_order_${order_id % 2}
          
  #属性配置(可选)
  props:
    #是否开启SQL显示,默认值: false
    sql.show: true
    #executor.size: 工作线程数量,默认值: CPU核数   

使用Java的方式,现在几乎没有使用了。硬编码太多
一般本地采用yaml文件方式。正式环境都是appllo配置

自增主键策略为什么是不连续的,且尾数大多为偶数?

Sharding-Sphere采用snowflake算法作为默认的分布式分布式自增主键策略,用于保证分布式的情况下可以无中心化的生成不重复的自增序列。因此自增主键可以保证递增,但无法保证连续。
而snowflake算法的最后4位是在同一毫秒内的访问递增值。因此,如果毫秒内并发度不高,最后4位为零的几率则很大。因此并发度不高的应用生成偶数主键的几率会更高。

相关文章

网友评论

    本文标题:分库分表第二篇之使用Sharding-Jdbc

    本文链接:https://www.haomeiwen.com/subject/lpbwahtx.html