ShardingJDBC分庫分表+讀寫分離

ShardingJDBC分庫分表+讀寫分離

準備工作

共四臺Mysql,每臺Mysql有一個user數據庫,每個user庫有3張表(user_tb_0,user_tb_1,user_tb_2),共4*3=12張表,表結構都是一樣的。

兩臺master,兩臺slave。如下圖。slave和master實時同步備份,master是主數據庫(寫操作),slave是從數據庫(讀操作)。
在這裏插入圖片描述
在這裏插入圖片描述

表結構如下:

在這裏插入圖片描述

CREATE TABLE `user_tb_0` (
  `id` bigint(20) NOT NULL,
  `username` varchar(40) NOT NULL COMMENT '用戶名',
  `password` varchar(200) NOT NULL COMMENT '密碼',
  `nickname` varchar(100) DEFAULT NULL COMMENT '暱稱',
  `money` decimal(16,4) NOT NULL DEFAULT '0.0000' COMMENT '金額',
  `is_deleted` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否刪除',
  `create_date` datetime NOT NULL COMMENT '創建時間',
  `modify_date` datetime NOT NULL COMMENT '更新時間',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

pom.xml 添加以下依賴

        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
            <version>4.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-namespace</artifactId>
            <version>4.0.1</version>
        </dependency>
        <!--阿里數據庫連接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.16</version>
        </dependency>
        <!--分頁-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.2.10</version>
        </dependency>

application.yml配置如下

server:
  port: 8001

spring:
#  main:
#    allow-bean-definition-overriding: true
  application:
    name: sharding-jdbc-example
  shardingsphere:
    props:
      sql:
        show: true
    # 數據源配置,可配置多個
    datasource:
      names: master0,master1,slave0,slave1
      master0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3310/user?useUnicode=true&useSSL=false
        username: root
        password: '123456'
      slave0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3311/user?useUnicode=true&useSSL=false
        username: root
        password: '123456'
      master1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3312/user?useUnicode=true&useSSL=false
        username: root
        password: '123456'
      slave1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3313/user?useUnicode=true&useSSL=false
        username: root
        password: '123456'

    sharding:
      master-slave-rules:
        ms0:
          master-data-source-name: master0
          slave-data-source-names: slave0
        ms1:
          master-data-source-name: master1
          slave-data-source-names: slave1
      tables:
        user:
          key-generator:
            column: id
            type: SNOWFLAKE
          actual-data-nodes: ms$->{0..1}.user_tb_$->{0..2}
          database-strategy:
            inline:
              sharding-column: id
              algorithm-expression: ms$->{(id / 10).toBigInteger() % 2}
#              algorithm-expression: ms$->{id % 2}
          table-strategy:
            inline:
              sharding-column: id
              algorithm-expression: user_tb_$->{id % 3}
mybatis:
  type-aliases-package: com.cunzaizhe.entity
  mapper-locations: classpath:mapper/*Mapper.xml

pagehelper:
  helper-dialect: mysql
  support-methods-arguments: true
  params: count=countSql
  reasonable: false
  • 分庫分表原理:先根據id的十位上的數%2被平均分到master0和master1數據庫上,然後再根據id個位上的數%3被平均分到user_tb_0,user_tb_1,user_tb_2上。
  • master0,master1,slave0,slave1四個數據源
  • 根據用戶id來分庫分表
  • 分庫規則 ms$->{(id / 10).toBigInteger() % 2} 十位上的數模2
  • 分表規則 user_tb_$->{id % 3} 個位上的數模3

測試一下效果

共插入了300萬條數據 平均每張表50萬條左右
在這裏插入圖片描述

根據id查詢一條記錄 是770毫秒
在這裏插入圖片描述
在這裏插入圖片描述

用戶名模糊查詢 並按照時間排序,分頁取前十條 是1894毫
在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

ps:是在一臺電腦,docker部署的4臺mysql

實際情況根據業務發展趨勢和預估在前期設計好數據庫,分庫分表怎麼分,如果是財大氣粗可以直接上TiDB,但對服務器配置要求比較高。TiDB是分佈式數據庫,兼容MySQL,讓數據庫就做它自己的事情。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章