Apache ShardingSphere Proxy5.5.0实现MySQL分库分表与读写分离

1. 前提准备

1.1 主机IP:192.168.186.77        

version: '3.8'

services:
  mysql-master:
    image: mysql:latest
    container_name: mysql-master
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_USER: master
      MYSQL_PASSWORD: 123456
      MYSQL_DATABASE: db1  
    ports:
      - "3306:3306"
    volumes:
      - mysql-master-data:/var/lib/mysql
    command: --server-id=1 --log-bin=mysql-bin --binlog-format=ROW
    cap_add:
      - SYS_NICE
    security_opt:
      - seccomp:unconfined

  mysql-slave:
    image: mysql:latest
    container_name: mysql-slave
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_USER: slave
      MYSQL_PASSWORD: 123456
      MYSQL_DATABASE: db1
    ports:
      - "3307:3306"
    volumes:
      - mysql-slave-data:/var/lib/mysql
    command: --server-id=2 --log-bin=mysql-bin --binlog-format=ROW --relay-log=relay-bin --relay-log-index=relay-bin.index
    depends_on:
      - mysql-master
    cap_add:
      - SYS_NICE
    security_opt:
      - seccomp:unconfined

volumes:
  mysql-master-data:
  mysql-slave-data:

注:3306端口扮演master数据库角色,3307端口扮演salve数据库角色。 

1.2 主机IP:192.168.186.216

version: '3.8'

services:
  mysql-master:
    image: mysql:latest
    container_name: mysql-master
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_USER: master
      MYSQL_PASSWORD: 123456
      MYSQL_DATABASE: db2  
    ports:
      - "3306:3306"
    volumes:
      - mysql-master-data:/var/lib/mysql
    command: --server-id=3 --log-bin=mysql-bin --binlog-format=ROW
    cap_add:
      - SYS_NICE
    security_opt:
      - seccomp:unconfined

  mysql-slave:
    image: mysql:latest
    container_name: mysql-slave
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_USER: slave
      MYSQL_PASSWORD: 123456
      MYSQL_DATABASE: db2  
    ports:
      - "3307:3306"
    volumes:
      - mysql-slave-data:/var/lib/mysql
    command: --server-id=4 --log-bin=mysql-bin --binlog-format=ROW --relay-log=relay-bin --relay-log-index=relay-bin.index
    depends_on:
      - mysql-master
    cap_add:
      - SYS_NICE
    security_opt:
      - seccomp:unconfined

volumes:
  mysql-master-data:
  mysql-slave-data:

 1.3 主机IP:192.168.186.216

version: '3.8'

services:
  mysql-master:
    image: mysql:latest
    container_name: mysql-master
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_USER: master
      MYSQL_PASSWORD: 123456
      MYSQL_DATABASE: db3  
    ports:
      - "3306:3306"
    volumes:
      - mysql-master-data:/var/lib/mysql
    command: --server-id=5 --log-bin=mysql-bin --binlog-format=ROW
    cap_add:
      - SYS_NICE
    security_opt:
      - seccomp:unconfined

  mysql-slave:
    image: mysql:latest
    container_name: mysql-slave
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_USER: slave
      MYSQL_PASSWORD: 123456
      MYSQL_DATABASE: db3 
    ports:
      - "3307:3306"
    volumes:
      - mysql-slave-data:/var/lib/mysql
    command: --server-id=6 --log-bin=mysql-bin --binlog-format=ROW --relay-log=relay-bin --relay-log-index=relay-bin.index
    depends_on:
      - mysql-master
    cap_add:
      - SYS_NICE
    security_opt:
      - seccomp:unconfined

volumes:
  mysql-master-data:
  mysql-slave-data:

注:每个 MySQL 实例必须有一个唯一的 server-id。这是必要的,因为在主从复制设置中,主服务器和从服务器需要能够互相识别,并避免循环复制和冲突。       

1.4 简单主从搭建过程

1.4.1 连接主服务器

1.4.2 连接从服务器 

1.4.3 配置主服务器
# 创建一个具有复制权限的用户
CREATE USER 'master_slave'@'%' IDENTIFIED BY '123456' REQUIRE SSL;
GRANT REPLICATION SLAVE ON *.* TO 'master_slave'@'%';
FLUSH PRIVILEGES;
SHOW MASTER STATUS;

1.4.4 配置从服务器
CHANGE MASTER TO
    MASTER_HOST ='192.168.186.216', # 主服务器的 IP 地址
    MASTER_USER ='master_slave', # 主服务器上配置的复制用户
    MASTER_PASSWORD ='123456', # 复制用户的密码
    MASTER_LOG_FILE ='mysql-bin.000003', # 主服务器的日志文件名
    MASTER_LOG_POS =920, # 日志文件的位置
    MASTER_SSL=1;
START SLAVE;
SHOW SLAVE STATUS;

        其余两台使用同样的方式进行配置。 

2. 安装 Apache ShardingSphere Proxy

2.1 安装合适的JDK版本

sudo apt install openjdk-8-jdk -y

2.2 验证JDK版本

java -version

liber@liber-VMware-Virtual-Platform:/home/sp$ java -version
openjdk version "1.8.0_412"
OpenJDK Runtime Environment (build 1.8.0_412-8u412-ga-1~24.04.2-b08)
OpenJDK 64-Bit Server VM (build 25.412-b08, mixed mode)

2.3 使用wget下载Apache ShardingSphere Proxy

sudo wget https://dlcdn.apache.org/shardingsphere/5.5.0/apache-shardingsphere-5.5.0-shardingsphere-proxy-bin.tar.gz

2.4 解压Apache ShardingSphere Proxy文件

 sudo tar -zxvf apache-shardingsphere-5.5.0-shardingsphere-proxy-bin.tar.gz

2.5 进入Apache ShardingSphere Proxy解压后的目录 

cd apache-shardingsphere-5.5.0-shardingsphere-proxy-bin

2.5 查看MySQL的版本 

        找台主服务器或者从服务器输入查看数据库的版本。

SELECT VERSION();

2.6 下载并安装MySQL Connector/J 8.0.27

sudo wget https://downloads.mysql.com/archives/get/p/3/file/mysql-connector-java-8.0.27.tar.gz

 

2.7 解压MySQL文件

sudo tar -zxvf mysql-connector-java-8.0.27.tar.gz

2.8 进入解压后的MySQL目录

cd mysql-connector-java-8.0.27

 2.9 将 JAR 文件放置到合适的位置

 需要将JAR文件复制到Apache ShardingSphere-Proxy解压目录的lib 目录中,因为我在Apache ShardingSphere-Proxy的解压目录中下载的MySQL压缩包,解压后只需要将JAR文件移动到上一级的lib目录即可。

sudo mv mysql-connector-java-8.0.27.jar  ../lib

  2.10 global.yaml

# 回退上一级目录
cd ..

# 进入conf目录
cd conf

# 编辑global.yaml文件
sudo nano global.yaml

      global.yaml 内容如下:

# 释放注解
authority:
  users:
    - user: root@%
      password: 123456
    - user: sharding
      password: 123456
  privilege:
    type: ALL_PERMITTED
sqlParser:
  sqlStatementCache:
    initialCapacity: 2000
    maximumSize: 65535
  parseTreeCache:
    initialCapacity: 128
    maximumSize: 1024
props:
  proxy-default-port: 3308 #修改端口,因为被占用了3307所以我修改了3308
  sql-show: true

2.11 创建物理表

use db1; # 每个主服务器都需要创建,只需要把db1,改db2,db3即可。

CREATE TABLE t_order_0
(
    order_id   INT PRIMARY KEY,
    user_id    INT,
    order_date DATE,
    status     VARCHAR(15)
);

CREATE TABLE t_order_1
(
    order_id   INT PRIMARY KEY,
    user_id    INT,
    order_date DATE,
    status     VARCHAR(15)
);

注: 每个主服务器的数据库都需要建立结构相同的物理表,只是库不一样db1,db2,db3。

2.12 database-sharding.yaml

sudo nano database-sharding.yaml
2.1.1 配置数据库源
dataSources:
  # 主库配置
  ds_77_master:
    url: jdbc:mysql://192.168.186.77:3306/db1?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
    username: root  # 数据库用户名
    password: 123456  # 数据库密码
    connectionTimeoutMilliseconds: 30000  # 连接超时时间,单位毫秒
    idleTimeoutMilliseconds: 60000  # 空闲连接超时时间,单位毫秒
    maxLifetimeMilliseconds: 1800000  # 连接最大生命周期,单位毫秒
    maxPoolSize: 50  # 连接池最大连接数
    minPoolSize: 1  # 连接池最小连接数

  # 从库配置
  ds_77_slave:
    url: jdbc:mysql://192.168.186.77:3307/db1?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
    username: slave  # 数据库用户名
    password: 123456  # 数据库密码
    connectionTimeoutMilliseconds: 30000  # 连接超时时间,单位毫秒
    idleTimeoutMilliseconds: 60000  # 空闲连接超时时间,单位毫秒
    maxLifetimeMilliseconds: 1800000  # 连接最大生命周期,单位毫秒
    maxPoolSize: 50  # 连接池最大连接数
    minPoolSize: 1  # 连接池最小连接数

  ds_216_master:
    url: jdbc:mysql://192.168.186.216:3306/db2?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
    username: root
    password: 123456
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1

  ds_216_slave:
    url: jdbc:mysql://192.168.186.216:3307/db2?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
    username: slave
    password: 123456
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1

  ds_18_master:
    url: jdbc:mysql://192.168.186.18:3306/db3?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
    username: root
    password: 123456
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1

  ds_18_slave:
    url: jdbc:mysql://192.168.186.18:3307/db3?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
    username: slave
    password: 123456
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1

# 设置逻辑数据库名称
databaseName: my_database
2.1.2 读写分离规则
rules:
  - !READWRITE_SPLITTING
    # 定义用于读写分离的数据源配置
    dataSources:
      # 第一组读写分离规则,命名为 "readwrite_77"
      readwrite_77:
        writeDataSourceName: ds_77_master  # 指定写操作的数据源为 ds_77_master(主库)
        readDataSourceNames:
          - ds_77_slave  # 指定读操作的数据源列表,这里只包括 ds_77_slave(从库)
        transactionalReadQueryStrategy: PRIMARY  # 事务中的读查询策略设为 PRIMARY,即事务中所有读操作都将指向主库
        loadBalancerName: random  # 使用随机策略从可用的从库中选择

      readwrite_216:
        writeDataSourceName: ds_216_master  
        readDataSourceNames:
          - ds_216_slave  
        transactionalReadQueryStrategy: PRIMARY 
        loadBalancerName: random  

      readwrite_18:
        writeDataSourceName: ds_18_master  # 主库
        readDataSourceNames:
          - ds_18_slave  
        transactionalReadQueryStrategy: PRIMARY  
        loadBalancerName: random  

    # 定义负载均衡器的配置
    loadBalancers:
      random:
        type: RANDOM  # 指定负载均衡器的类型为 RANDOM,随机选择读库
2.1.3 分库分表规则
- !SHARDING
  # 分片表的配置
  tables:
    t_order:
      # 定义分片表t_order在各个数据源的具体分布
      actualDataNodes: readwrite_77.t_order_${0..1}, readwrite_216.t_order_${0..1}, readwrite_18.t_order_${0..1}
      # 表的分片策略配置
      tableStrategy:
        standard:
          shardingColumn: order_id  # 使用订单ID作为分片键
          shardingAlgorithmName: t_order_inline  # 分片算法名称,指向后面定义的内联算法
      # 主键生成策略,用于插入操作时自动生成主键
      keyGenerateStrategy:
        column: order_id  # 主键列
        keyGeneratorName: snowflake  # 使用雪花算法生成主键

  # 默认数据库分片策略
  defaultDatabaseStrategy:
    standard:
      shardingColumn: user_id  # 使用用户ID作为分片键
      shardingAlgorithmName: database_inline  # 数据库分片使用的算法名称,指向后面定义的内联算法

  # 默认的表分片策略,此处未定义分片策略
  defaultTableStrategy:
    none:

  # 绑定表组,确保相互关联的表在同一数据库分片中
  bindingTables:
    - t_order  # 把t_order表标记为绑定表

  # 定义使用的分片算法
  shardingAlgorithms:
    # 定义数据库分片的内联算法
    database_inline:
      type: INLINE
      props:
        algorithm-expression: "readwrite_${(user_id % 3 == 0) ? '77' : ((user_id % 3 == 1) ? '216' : '18')}"
        # 根据用户ID的值进行模3运算来决定数据分配到哪个数据源

    # 定义表分片的内联算法
    t_order_inline:
      type: INLINE
      props:
        algorithm-expression: "t_order_${order_id % 2}"
        # 根据订单ID的值进行模2运算来决定数据存储在哪个分表

  # 主键生成器配置,指定使用雪花算法生成主键
  keyGenerators:
    snowflake:
      type: SNOWFLAKE
      props:
        worker-id: 123  # 设置雪花算法的工作节点ID
2.1.4 完整配置信息 
dataSources:
  ds_77_master:
    url: jdbc:mysql://192.168.186.77:3306/db1?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
    username: root
    password: 123456
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1
  ds_77_slave:
    url: jdbc:mysql://192.168.186.77:3307/db1?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
    username: slave
    password: 123456
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1
  ds_216_master:
    url: jdbc:mysql://192.168.186.216:3306/db2?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
    username: root
    password: 123456
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1
  ds_216_slave:
    url: jdbc:mysql://192.168.186.216:3307/db2?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
    username: slave
    password: 123456
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1
  ds_18_master:
    url: jdbc:mysql://192.168.186.18:3306/db3?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
    username: root
    password: 123456
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1
  ds_18_slave:
    url: jdbc:mysql://192.168.186.18:3307/db3?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
    username: slave
    password: 123456
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1
databaseName: my_database
rules:
  - !READWRITE_SPLITTING
    dataSources:
      readwrite_77:
        writeDataSourceName: ds_77_master
        readDataSourceNames:
          - ds_77_slave
        transactionalReadQueryStrategy: PRIMARY
        loadBalancerName: random
      readwrite_216:
        writeDataSourceName: ds_216_master
        readDataSourceNames:
          - ds_216_slave
        transactionalReadQueryStrategy: PRIMARY
        loadBalancerName: random
      readwrite_18:
        writeDataSourceName: ds_18_master
        readDataSourceNames:
          - ds_18_slave
        transactionalReadQueryStrategy: PRIMARY
        loadBalancerName: random
    loadBalancers:
      random:
        type: RANDOM
  - !SHARDING
    tables:
      t_order:
        actualDataNodes: readwrite_77.t_order_${0..1}, readwrite_216.t_order_${0..1}, readwrite_18.t_order_${0..1}
        tableStrategy:
          standard:
            shardingColumn: order_id
            shardingAlgorithmName: t_order_inline
        keyGenerateStrategy:
          column: order_id
          keyGeneratorName: snowflake
    defaultDatabaseStrategy:
      standard:
        shardingColumn: user_id
        shardingAlgorithmName: database_inline
    defaultTableStrategy:
      none:
    bindingTables:
      - t_order
    shardingAlgorithms:
      database_inline:
        type: INLINE
        props:
          algorithm-expression: "readwrite_${(user_id % 3 == 0) ? '77' : ((user_id % 3 == 1) ? '216' : '18')}"
      t_order_inline:
        type: INLINE
        props:
          algorithm-expression: "t_order_${order_id % 2}"
    keyGenerators:
      snowflake:
        type: SNOWFLAKE
        props:
          worker-id: 123

注:分片规则根据 user_id 的值对3取模,决定将数据分片到哪个数据库, 根据 order_id 的值对2取模,决定将数据分片到哪个表。

2.1.5 参考教程文献

 数据分片 :: ShardingSphere

 读写分离 :: ShardingSphere

 混合规则 :: ShardingSphere

2.13 启动程序

# 回退上一级
cd ..
# 进入bin目录
cd bin
# 启动程序
sudo ./start.sh

liber@liber-VMware-Virtual-Platform:/home/sp/apache-shardingsphere-5.5.0-shardingsphere-proxy-bin/conf$ cd ..
liber@liber-VMware-Virtual-Platform:/home/sp/apache-shardingsphere-5.5.0-shardingsphere-proxy-bin$ cd bin
liber@liber-VMware-Virtual-Platform:/home/sp/apache-shardingsphere-5.5.0-shardingsphere-proxy-bin/bin$ sudo ./start.sh
/usr/bin/java
we find java version: java8, full_version=1.8.0_412, full_path=/usr/bin/java
The classpath is /home/sp/apache-shardingsphere-5.5.0-shardingsphere-proxy-bin/conf:/home/sp/apache-shardingsphere-5.5.0-shardingsphere-proxy-bin/conf:.:/home/sp/apache-shardingsphere-5.5.0-shardingsphere-proxy-bin/lib/*:/home/sp/apache-shardingsphere-5.5.0-shardingsphere-proxy-bin/ext-lib/*
main class org.apache.shardingsphere.proxy.Bootstrap -1 /home/sp/apache-shardingsphere-5.5.0-shardingsphere-proxy-bin/conf 0.0.0.0 false
Starting the ShardingSphere-Proxy ... PID: 128452
Please check the STDOUT file: /home/sp/apache-shardingsphere-5.5.0-shardingsphere-proxy-bin/logs/stdout.log #日志路径可以通过cat进行查看
liber@liber-VMware-Virtual-Platform:/home/sp/apache-shardingsphere-5.5.0-shardingsphere-proxy-bin/bin$ 

 2.15 查看日志

cat /home/sp/apache-shardingsphere-5.5.0-shardingsphere-proxy-bin/logs/stdout.log
#显示该信息代表成功
[INFO ] 2024-07-25 15:39:09.724 [main] o.a.s.d.p.c.l.PipelineContextManagerLifecycleListener - mode type is not Cluster, mode type='Standalone', ignore
[INFO ] 2024-07-25 15:39:09.933 [main] o.a.s.p.v.ShardingSphereProxyVersion - Database type is `MySQL`, version is `8.0.27`, database name is `my_database`
[INFO ] 2024-07-25 15:39:09.966 [main] o.a.s.p.frontend.ssl.ProxySSLContext - Proxy frontend SSL/TLS is not enabled.
[INFO ] 2024-07-25 15:39:12.683 [main] o.a.s.p.frontend.ShardingSphereProxy - ShardingSphere-Proxy Standalone mode started successfully

2.16 测试连接 

2.17 分库分表验证 

        在ShardingSphere-Proxy连接的客户端进行操作,因为t_order是ShardingSphere-Proxy创建的逻辑表,所以实际上通过第三方连接工具是看不到存在的实体表,比如我使用的是IDEA自带的MySQL的连接管理工具。

use my_database;

INSERT INTO t_order (order_id, user_id, order_date, status) VALUES (1, 10, '2023-07-01', 'NEW');
INSERT INTO t_order (order_id, user_id, order_date, status) VALUES (2, 20, '2023-07-02', 'SHIPPED');
INSERT INTO t_order (order_id, user_id, order_date, status) VALUES (3, 30, '2023-07-03', 'DELIVERED');
INSERT INTO t_order (order_id, user_id, order_date, status) VALUES (14, 40, '2023-07-04', 'RETURNED');

运行日志:

[INFO ] 2024-07-25 15:43:21.874 [ShardingSphere-Command-1] ShardingSphere-SQL - Logic SQL: /* ApplicationName=IntelliJ IDEA 2024.1 */ INSERT INTO t_order (order_id, user_id, order_date, status) VALUES (1, 10, '2023-07-01', 'NEW')
[INFO ] 2024-07-25 15:43:21.874 [ShardingSphere-Command-1] ShardingSphere-SQL - Actual SQL: ds_216_master ::: /* ApplicationName=IntelliJ IDEA 2024.1 */ INSERT INTO t_order_1 (order_id, user_id, order_date, status) VALUES (1, 10, '2023-07-01', 'NEW')
解释:分片规则根据 user_id 的值对3取模,决定将数据分片到哪个数据库, 根据 order_id 的值对2取模,决定将数据分片到哪个表。数据库取模顺序:77=>0,216=>1,18=>2
user_id: 10%3=1,order_id: 1%2=1,所以分片到第2个数据库ds_216_master,t_order_1表。 

[INFO ] 2024-07-25 15:43:21.976 [ShardingSphere-Command-1] ShardingSphere-SQL - Logic SQL: /* ApplicationName=IntelliJ IDEA 2024.1 */ INSERT INTO t_order (order_id, user_id, order_date, status) VALUES (2, 20, '2023-07-02', 'SHIPPED')
[INFO ] 2024-07-25 15:43:21.976 [ShardingSphere-Command-1] ShardingSphere-SQL - Actual SQL: ds_18_master ::: /* ApplicationName=IntelliJ IDEA 2024.1 */ INSERT INTO t_order_0 (order_id, user_id, order_date, status) VALUES (2, 20, '2023-07-02', 'SHIPPED')
解释:分片规则根据 user_id 的值对3取模,决定将数据分片到哪个数据库, 根据 order_id 的值对2取模,决定将数据分片到哪个表。数据库取模顺序:77=>0,216=>1,18=>2
user_id: 20%3=2,order_id: 2%2=0,所以分片到第3个数据库ds_18_master,t_order_0表。
[INFO ] 2024-07-25 15:43:22.108 [ShardingSphere-Command-1] ShardingSphere-SQL - Logic SQL: /* ApplicationName=IntelliJ IDEA 2024.1 */ INSERT INTO t_order (order_id, user_id, order_date, status) VALUES (3, 30, '2023-07-03', 'DELIVERED')
[INFO ] 2024-07-25 15:43:22.108 [ShardingSphere-Command-1] ShardingSphere-SQL - Actual SQL: ds_77_master ::: /* ApplicationName=IntelliJ IDEA 2024.1 */ INSERT INTO t_order_1 (order_id, user_id, order_date, status) VALUES (3, 30, '2023-07-03', 'DELIVERED')
解释:分片规则根据 user_id 的值对3取模,决定将数据分片到哪个数据库, 根据 order_id 的值对2取模,决定将数据分片到哪个表。数据库取模顺序:77=>0,216=>1,18=>2
user_id: 30%3=0,order_id: 3%2=1,所以分片到第1个数据库ds_77_master,t_order_1表。

[INFO ] 2024-07-25 15:43:22.248 [ShardingSphere-Command-1] ShardingSphere-SQL - Logic SQL: /* ApplicationName=IntelliJ IDEA 2024.1 */ INSERT INTO t_order (order_id, user_id, order_date, status) VALUES (14, 40, '2023-07-04', 'RETURNED')
[INFO ] 2024-07-25 15:43:22.248 [ShardingSphere-Command-1] ShardingSphere-SQL - Actual SQL: ds_216_master ::: /* ApplicationName=IntelliJ IDEA 2024.1 */ INSERT INTO t_order_0 (order_id, user_id, order_date, status) VALUES (14, 40, '2023-07-04', 'RETURNED')
解释:分片规则根据 user_id 的值对3取模,决定将数据分片到哪个数据库, 根据 order_id 的值对2取模,决定将数据分片到哪个表。数据库取模顺序:77=>0,216=>1,18=>2
user_id: 40%3=1,order_id: 14%2=0,所以分片到第2个数据库ds_216_master,t_order_0表。

2.18 读写分离验证 

select *from t_order;
运行日志:
[INFO ] 2024-07-25 15:57:22.968 [ShardingSphere-Command-2] ShardingSphere-SQL - Logic SQL: /* ApplicationName=IntelliJ IDEA 2024.1 */ select *from t_order
[INFO ] 2024-07-25 15:57:22.969 [ShardingSphere-Command-2] ShardingSphere-SQL - Actual SQL: ds_77_slave ::: /* ApplicationName=IntelliJ IDEA 2024.1 */ select *from t_order_0 UNION ALL /* ApplicationName=IntelliJ IDEA 2024.1 */ select *from t_order_1
[INFO ] 2024-07-25 15:57:22.969 [ShardingSphere-Command-2] ShardingSphere-SQL - Actual SQL: ds_216_slave ::: /* ApplicationName=IntelliJ IDEA 2024.1 */ select *from t_order_0 UNION ALL /* ApplicationName=IntelliJ IDEA 2024.1 */ select *from t_order_1
[INFO ] 2024-07-25 15:57:22.973 [ShardingSphere-Command-2] ShardingSphere-SQL - Actual SQL: ds_18_slave ::: /* ApplicationName=IntelliJ IDEA 2024.1 */ select *from t_order_0 UNION ALL /* ApplicationName=IntelliJ IDEA 2024.1 */ select *from t_order_1

 

3. 总结 

        Ubtun24.04 TLS,JDK8,shardingsphere proxy/5.5.0,MySQL Connector/J 8.0.27,仅供学习交流使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/870002.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SearchGPT 搜索引擎发布:让信息检索变得简单

如今的互联网时代,我们每天都在与海量数据搏斗。无论是学习、工作还是生活,我们都需要快速准确地获取所需信息。然而,传统搜索引擎往往让人感到力不从心:关键词需要精准,结果泛滥成灾,有用信息如大海捞针。…

内网对抗-隧道技术篇防火墙组策略HTTP反向SSH转发出网穿透CrossC2解决方案

知识点: 1、C2/C2上线-CrossC2插件-多系统平台支持 2、隧道技术篇-应用层-SSH协议-判断&封装&建立&穿透 3、隧道技术篇-应用层-HTTP协议-判断&封装&建立&穿透隧道技术主要解决网络通讯问题:遇到防火墙就用隧道技术,…

vue elementui 在table里使用el-switch

<el-table-columnprop"operationStatus"label"状态"header-align"center"align"center"><template slot-scope"scope"><el-switch active-value"ENABLE" inactive-value"DISABLE" v-mod…

麦歌恩MT6521-第三代汽车磁性角度传感器芯片

磁性编码芯片 -在线编程角度位置IC 描述&#xff1a; MT6521是麦歌恩微电子推出的新一代基于水平霍尔及聚磁片(IMC)技术原理的磁性角度和位置检测传感器芯片。该芯片内部包含了两对互成90放置的水平霍尔阵列及聚磁片&#xff0c;能够根据不同的型号配置来实现对XY&#xff0…

Idea2024 创建Meaven项目没有src文件夹

1、直接创建 新建maven项目&#xff0c;发现没有src/main/java 直接新建文件夹&#xff1a;右击项目名->new->Directory 可以看到idea给出了快捷创建文件夹的选项&#xff0c;可以根据需要创建&#xff0c;这里点击src/main/java 回车&#xff0c;可以看到文件夹已经创建…

OSPF概述

OSPF OSPF属于内部网关路由协议【IGP】 用于单一自治系统【Autonomous System-AS】内决策路由 自治系统【AS】 执行统一路由策略的一组网络设备的组合 OSPF概述 为了适应大型的网络&#xff0c;OSPF在AS内划分多个区域 每个OSPF路由器只维护所在区域的完整的链路状态信息 …

基于PaddleClas的人物年龄分类项目

目录 一、任务概述 二、算法研发 2.1 下载数据集 2.2 数据集预处理 2.3 安装PaddleClas套件 2.4 算法训练 2.5 静态图导出 2.6 静态图推理 三、小结 一、任务概述 最近遇到个需求&#xff0c;需要将图像中的人物区分为成人和小孩&#xff0c;这是一个典型的二分类问题…

【数据结构】手把手教你单链表(c语言)(附源码)

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;数据结构 目录 前言 1.单链表的概念与结构 2.单链表的结构定义 3.单链表的实现 3.1 单链表的方法声明 3.2 单链表方法实现 3.2.1 打印链表 3.2.2 创建新…

C++ | Leetcode C++题解之第275题H指数II

题目&#xff1a; 题解&#xff1a; class Solution { public:int hIndex(vector<int>& citations) {int n citations.size();int left 0, right n - 1;while (left < right) {int mid left (right - left) / 2;if (citations[mid] > n - mid) {right m…

使用Diffusion Models进行街景视频生成

Diffusion Models专栏文章汇总:入门与实战 前言:街景图生成相当有挑战性,目前的文本到视频的方法仅限于生成有限范围的场景的短视频,文本到3D的方法可以生成单独的对象但不是整个城市。除此之外街景图对一致性的要求相当高,这篇博客介绍如何用Diffusion Models执行街景图生…

JAW:一款针对客户端JavaScript的图形化安全分析框架

关于JAW JAW是一款针对客户端JavaScript的图形化安全分析框架&#xff0c;该工具基于esprima解析器和EsTree SpiderMonkey Spec实现其功能&#xff0c;广大研究人员可以使用该工具分析Web应用程序和基于JavaScript的客户端程序的安全性。 工具特性 1、动态可扩展的框架&#x…

Unity UGUI 之 图集

本文仅作学习笔记与交流&#xff0c;不作任何商业用途 本文包括但不限于unity官方手册&#xff0c;唐老狮&#xff0c;麦扣教程知识&#xff0c;引用会标记&#xff0c;如有不足还请斧正 本文在发布时间选用unity 2022.3.8稳定版本&#xff0c;请注意分别 1.什么是图集 精灵图…

C语言玩一下标准输出——颜色、闪烁、加粗、下划线属性

文章目录 C语言玩一下标准输出——颜色、闪烁、加粗、下划线属性转换Tip切换内容介绍显示方式字体色背景色 常用光标控制附示例和运行结果 C语言玩一下标准输出——颜色、闪烁、加粗、下划线属性 标准输出格式其属性可控制&#xff0c;控制由一系列的控制码指定。标准输出函数可…

一个C++模板工厂的编译问题的解决。针对第三方库的构造函数以及追加了的对象构造函数。牵扯到重载、特化等

一窥模板的替换和匹配方式&#xff1a;偏特化的参数比泛化版本的还要多&#xff1a;判断是不是std::pair&#xff1c;,&#xff1e;。_stdpair模板参数太多-CSDN博客 简介 在一个项目里&#xff0c;调用了第三封的库&#xff0c;这个库里面有个类用的很多&#xff0c;而且其构…

Godot入门 03世界构建1.0版

在game场景&#xff0c;删除StaticBody2D节点&#xff0c;添加TileMap节点 添加TileSet图块集 添加TileSet源 拖动图片到图块&#xff0c;自动创建图块 使用橡皮擦擦除。取消橡皮擦后按住Shift创建大型图块。 进入选择模式&#xff0c;TileMap选择绘制&#xff0c;选中图块后在…

zookeeper开启SASL权限认证

目录 一、SASL介绍 二、使用 SASL 进行身份验证 2.1 服务器到服务器的身份验证 2.2 客户端到服务器身份验证 三、验证功能 一、SASL介绍 默认情况下&#xff0c;ZooKeeper 不使用任何形式的身份验证并允许匿名连接。但是&#xff0c;它支持 Java 身份验证与授权服务(JAAS)…

单元测试的最佳实践

整体架构 合适的架构可以提升可测试性。比如菱形对称架构的模块化和解耦特性使得系统各个部分可以独立进行单元测试。这不仅提高了测试的效率&#xff0c;还能够减少测试的依赖性&#xff0c;提高测试准确性。 代码设计 代码设计和可测试性有密切关联。强烈建议一个方法的代码行…

使用法国云手机进行面向法国的社媒营销

在当今数字化和全球化的时代&#xff0c;社交媒体已经成为企业营销和拓展市场的重要工具。对于想进入法国市场的企业来说&#xff0c;如何在海外社媒营销中脱颖而出、抓住更多的市场份额&#xff0c;成为了一个关键问题。法国云手机正为企业提供全新的营销工具&#xff0c;助力…

Flink源码学习资料

Flink系列文档脑图 由于源码分析系列文档较多&#xff0c;本人绘制了Flink文档脑图。和下面的文档目录对应。各位读者可以选择自己感兴趣的模块阅读并参与讨论。 此脑图不定期更新中…… 文章目录 以下是本人Flink 源码分析系列文档目录&#xff0c;欢迎大家查阅和参与讨论。…

iPhone 17系列取消17 Plus版本?新一代苹果手机迎来新变革

随着科技的飞速发展&#xff0c;苹果公司再次准备刷新我们的期待&#xff0c;即将推出的iPhone 17系列携带着一系列令人兴奋的升级。今年&#xff0c;苹果打破了常规&#xff0c;将四款新机型带入市场——iPhone 17、17 Pro、17 Pro Max&#xff0c;以及一款全新的成员&#xf…