Mysql主从集群搭建+分库分表+ShardingSphere(实战)

news2024/12/26 2:25:11

什么是 ShardingSphere

介绍

Apache ShardingSphere 是一款分布式的数据库生态系统, 可以将任意数据库转换为分布式数据库,并通过数据分片、弹性伸缩、加密等能力对原有数据库进行增强。

Apache ShardingSphere 设计哲学为 Database Plus,旨在构建异构数据库上层的标准和生态。 它关注如何充分合理地利用数据库的计算和存储能力,而并非实现一个全新的数据库。 它站在数据库的上层视角,关注它们之间的协作多于数据库自身。

主要功能

一、数据库增强与分布式能力

  1. 数据分片:ShardingSphere可以将数据库表拆分成多个部分,每个部分称为分片,通过分片实现数据的分布和负载均衡。这能够极大地提升数据库集群的性能和可扩展性,解决单机数据库在存储和计算方面的瓶颈。
  2. 分布式事务:ShardingSphere提供在独立数据库上的分布式事务功能,基于XA和BASE的混合事务引擎,保证跨数据源的数据一致性,是保障数据库完整、安全的关键技术。
  3. 数据迁移与扩容:ShardingSphere提供跨数据源的数据迁移能力,并可支持重分片扩展,从而简化数据库迁移或扩容的过程。

二、数据治理与安全性

  1. 读写分离:基于对SQL语义理解及对底层数据库拓扑感知能力,ShardingSphere提供灵活的读写流量拆分和读流量负载均衡,能够进一步提升数据库系统的读性能。
  2. 数据加密:ShardingSphere提供完整、透明、安全、低成本的数据加密及脱敏解决方案,确保数据的安全性。
  3. 影子库:在全链路压测场景下,ShardingSphere支持不同工作负载下的数据隔离,避免测试数据污染生产环境。

三、兼容性与易用性

  1. 兼容性:ShardingSphere可以兼容所有符合SQL-92标准语法的数据库,包括MySQL、PostgreSQL、SQL Server和Oracle等,用户可根据需求选择最适合的数据库。
  2. 易用性:ShardingSphere提供了标准化的基于数据库作为存储节点的增量功能,可适用于如Java同构、异构语言、云原生等各种多样化的应用场景。同时,ShardingSphere-JDBC作为轻量级Java框架,在Java的JDBC层提供额外服务,无需额外部署和依赖;ShardingSphere-Proxy则定位为透明化的数据库代理端,通过实现数据库二进制协议,对异构语言提供支持。

四、云原生与多云架构支持

ShardingSphere天然支持云原生及多云架构,在构建分布式数据库架构的过程中能够轻松利用云计算的强大功能,实现性能、弹性以及适应力的最大化。

主从复制

原理复习
主从集群有啥好处?
  • ①在主机宕机或故障的情况下,从节点能自动升级成主机,从而继续对外提供服务。
  • ②提供数据备份的功能,当主节点的数据发生损坏时,从节点中依旧保存着完整数据。
  • ③可以实现读写分离,主节点负责处理写请求,从节点处理读请求,进一步提升性能。
  • ④可以实现多主多写,数据库系统可以由多个节点组成,共同对外提供读写处理的能力。
同步原理

主要采用主推从拉思想

  • 写入请求由主节点先执行,写入后记录bin-log二进制日志。
  • 主节点的log dump线程监听到bin-log日志变化,通知从节点拉取数据。
  • 从节点有专门I/O线程等待主节点通知,收到主机的数据后,写入relay-log中级日志。
  • 从节点监听到relay-log日志变更,然后读取解析日志写入自己磁盘。
搭建主从集群,几种架构可选
  • 一主一从:做读写分离,适用读大于写
  • 双主/多主:各节点间互为主从,各节点都具备读写能力,读写参半
  • 多主一从:一个从节点同步多个主节点,适用写大于读。
  • 级联复杂:方案一改进,一个节点同步主机数据,适用写大于多。

主从复制的搭建

我们搭建主库3306,从库3307、3308。

主库(3306)
  • 修改配置:进入容器修改 MySQL 配置文件 my.cnf,启用二进制日志和设置 server-id
  • 授权:进入 MySQL 命令行,授权从库用户。
  • 重启容器:使配置生效。
从库(3307 和 3308)
  • 修改配置:进入容器,修改 my.cnf 配置文件,设置不同的 server-id
  • 配置主从复制:进入 MySQL 命令行,设置主库信息并启动复制。
  • 重启容器:使配置生效。
一 搭建主节点3306
   1.创建容器(可以不做)
      docker run -d \
      --name=mysql \
      --env-file=/usr/local/software/nacos-docker/env/mysql.env \
      -p 3306:3306 \
      -v /usr/local/software/mysql/3306:/var/lib/mysql \
      nacos/nacos-mysql:5.7
   2.进入容器
      docker exec -it mysql /bin/bash
   3.修改my.cnf
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
[mysqld]
log-bin=mysql-bin
server-id=3306
binlog_format=STATEMENT
   4.授权
      grant replication slave on *.* to 'copy'@'%' identified by 'root';
      show master status;
      reset master;
   5.重启容器
      docker cp my.cnf mysql:/etc/mysql/my.cnf
      docker restart mysql
二 搭建从节点3307
   1.创建容器
docker run -d \
--name=slave3307 \
--env-file=/usr/local/software/nacos-docker/env/mysql.env \
-p 3307:3306 \
-v /usr/local/software/mysql/3307:/var/lib/mysql \
nacos/nacos-mysql:5.7
   2.修改配置文件(docker exec -it slave3307 /bin/bash)
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
[mysqld]
# 从库在主从集群中的唯一标识
server-id=3307
   3.执行命令
docker cp my.cnf slave3307:/etc/mysql/my.cnf
docker restart slave3307
(从这里开始换一台机器)
show slave status;
stop slave;    
reset slave;
change master to master_host='10.211.55.6',master_user='copy',
master_port=3306,master_password='root',
master_log_file='mysql-bin.000001',master_log_pos=154;
start slave;
show slave status;


三 搭建从节点3308
   1.创建容器
docker run -d \
--name=slave3308 \
--env-file=/usr/local/software/nacos-docker/env/mysql.env \
-p 3308:3306 \
-v /usr/local/software/mysql/3308:/var/lib/mysql \
nacos/nacos-mysql:5.7
   2.修改配置文件(docker exec -it slave3308 /bin/bash)
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
[mysqld]
server-id=3308
   3.执行命令
docker cp my.cnf slave3308:/etc/mysql/my.cnf
docker restart slave3308
show slave status;
stop slave;
reset slave;
change master to master_host='10.211.55.6',master_user='copy',
master_port=3306,master_password='root',
master_log_file='mysql-bin.000001',master_log_pos=154;
start slave;
show slave status

docker logs --tail=1000 slave3309  

创建三个数据库

创建3306/3307/3308

db_order_1/db_order_2/db_order_3 最终数据库效果

1.1.1. 效果展示

在其中必须要看到Slave_IO_Running、Slave_SQL_Running两个线程的状态都为Yes时,这才意味着主从集群搭建完成。

读写分离(项目中使用)

需求分析

对品牌实现读写分离

官网配置方式

https://shardingsphere.apache.org/document/5.2.1/cn/user-manual/shardingsphere-jdbc/spring-boot-starter/

实现步骤

a. 编排数据库

b.添加依赖

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
    <version>${shardingsphere.version}</version>
</dependency>

a. 利用逆向工程生成代码

b. 配置文件

https://shardingsphere.apache.org/document/5.2.1/cn/user-manual/shardingsphere-jdbc/spring-boot-starter/

shardingsphere:
  mode:
    type: Standalone
    repository:
      type: JDBC
  datasource:
    names: write-node,read-node1,read-node2
    write-node:
      type: com.zaxxer.hikari.HikariDataSource
      driver-class-name: com.mysql.jdbc.Driver
      jdbc-url: jdbc:mysql://192.168.121.128:3306/db_order_1?characterEncoding=utf-8&useSSL=false
      username: root
      password: root
    read-node1:
      type: com.zaxxer.hikari.HikariDataSource
      driver-class-name: com.mysql.jdbc.Driver
      jdbc-url: jdbc:mysql://192.168.121.128:3306/db_order_2?characterEncoding=utf-8&useSSL=false
      username: root
      password: root
    read-node2:
      type: com.zaxxer.hikari.HikariDataSource
      driver-class-name: com.mysql.jdbc.Driver
      jdbc-url: jdbc:mysql://192.168.121.128:3306/db_order_3?characterEncoding=utf-8&useSSL=false
      username: root
      password: root
  rules:
    readwrite-splitting:
      data-sources:
      #读写分离多个数据源逻辑名称
        readwrite-node:
          static-strategy:
            write-data-source-name: write-node
            read-data-source-names:
              - read-node1
              - read-node2
          load-balancer-name: read-lb
      load-balancers:
        read-lb:
          type: ROUND_ROBIN
  #打印SQL语句
  props:
    sql-show: true

出现的问题

问题描述

启动时:

Command line is too long. Shorten command

解决方案

效果验证

127.0.0.1:8504/api/sharding/getAllBrand

读数据是从db_order_2和db_order_3中读

写数据往db_order_1中写

单表分库分表

规则分析

分库 order_id%3=1,2,3

分表order_id%4=1,2,3,4

如果按照order_id分库分表,会遇到跨库问题

采用规则方式

采用user_id进行分库分表,同一个用户的数据会放到同一个库同一张表里面

分库 user_id%3=1,2,3

分表 user_id%4=1,2,3,4

10%3=1+1=2

10%4=2+1=3

具体步骤

a.修改实体类

select * from db_order_{变量}.t_order_{变量}

a.修改yml文件

https://shardingsphere.apache.org/document/current/cn/user-manual/shardingsphere-jdbc/yaml-config/rules/sharding/

shardingsphere:

  datasource:

    names: ds-1,ds-2,ds-3

    ds-1:

      type: com.zaxxer.hikari.HikariDataSource

      driver-class-name: com.mysql.jdbc.Driver

      url: jdbc:mysql://192.168.121.128:3306/db_order_1?characterEncoding=utf-8&useSSL=false

      username: root

      password: root

    ds-2:

      type: com.zaxxer.hikari.HikariDataSource

      driver-class-name: com.mysql.jdbc.Driver

      url: jdbc:mysql://192.168.121.128:3306/db_order_2?characterEncoding=utf-8&useSSL=false

      username: root

      password: root

    ds-3:

      type: com.zaxxer.hikari.HikariDataSource

      driver-class-name: com.mysql.jdbc.Driver

      url: jdbc:mysql://192.168.121.128:3306/db_order_3?characterEncoding=utf-8&useSSL=false

      username: root

      password: root

  rules:

    sharding:

      #配置分库算法

      default-database-strategy:

        standard:

          sharding-algorithm-name: sharding-db-by-user-id

          sharding-column: user_id

      #具体算法如何做

      sharding-algorithms:

        #具体分库算法如何实现

        sharding-db-by-user-id:

          type: INLINE

          props:

            #ds-1,ds-2,ds-3

            algorithm-expression: ds-$->{user_id%3+1}

        #具体分表算法如何实现

        sharding-table-order-by-user-id:

          type: INLINE

          props:

            #t_order_1,t_order_2,t_order_3,t_order_4

            algorithm-expression: t_order_$->{user_id%4+1}

      #真实SQL如何实现的

      tables:

        t_order:

          actual-data-nodes: ds-$->{1..3}.t_order_$->{1..4}

          #表的分表策略

          table-strategy:

            standard:

              sharding-algorithm-name: sharding-table-order-by-user-id

              sharding-column: user_id

  #打印SQL语句

  props:

    sql-show: true

编写保存订单分库分表测试

//1.保存订单利用分库分表
@GetMapping("test01/{loopNum}")
public void test01(@PathVariable Integer loopNum){
    for (int i = 0; i <loopNum; i++) {
        TOrder tOrder = new TOrder();
        tOrder.setOrderPrice(99);
        String uuid = UUID.randomUUID().toString();
        tOrder.setTradeNo(uuid);
        tOrder.setOrderStatus("未支付");
        //设置分库分表字段
        int userId = new Random().nextInt(20);
        tOrder.setUserId(Long.parseLong(userId+""));
        System.out.println("用户id"+userId);
        order1Service.save(tOrder);
    }
}

两张表实现保存分库分表

配置文件

TRUNCATE TABLE t_order_1;
TRUNCATE TABLE t_order_2;
TRUNCATE TABLE t_order_3;
TRUNCATE TABLE t_order_4;
TRUNCATE TABLE t_order_detail_1;
TRUNCATE TABLE t_order_detail_2;
TRUNCATE TABLE t_order_detail_3;
TRUNCATE TABLE t_order_detail_4;
shardingsphere:
  datasource:
    names: ds-1,ds-2,ds-3
    ds-1:
      type: com.zaxxer.hikari.HikariDataSource
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://192.168.121.128:3306/db_order_1?characterEncoding=utf-8&useSSL=false
      username: root
      password: root
    ds-2:
      type: com.zaxxer.hikari.HikariDataSource
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://192.168.121.128:3306/db_order_2?characterEncoding=utf-8&useSSL=false
      username: root
      password: root
    ds-3:
      type: com.zaxxer.hikari.HikariDataSource
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://192.168.121.128:3306/db_order_3?characterEncoding=utf-8&useSSL=false
      username: root
      password: root
  rules:
    sharding:
      #配置分库算法
      default-database-strategy:
        standard:
          sharding-algorithm-name: sharding-db-by-user-id
          sharding-column: user_id
      #具体算法如何做
      sharding-algorithms:
        #具体分库算法如何实现
        sharding-db-by-user-id:
          type: INLINE
          props:
            #ds-1,ds-2,ds-3
            algorithm-expression: ds-$->{user_id%3+1}
        #具体分表算法如何实现
        sharding-table-order-by-user-id:
          type: INLINE
          props:
            #t_order_1,t_order_2,t_order_3,t_order_4
            algorithm-expression: t_order_$->{user_id%4+1}
        sharding-table-detail-by-user-id:
          type: INLINE
          props:
            #t_order_detail_1,t_order_detail_2,t_order_detail_3,t_order_detail_4
            algorithm-expression: t_order_detail_$->{user_id%4+1}
      #真实SQL如何实现的
      tables:
        t_order:
          actual-data-nodes: ds-$->{1..3}.t_order_$->{1..4}
          #表的分表策略
          table-strategy:
            standard:
              sharding-algorithm-name: sharding-table-order-by-user-id
              sharding-column: user_id
        t_order_detail:
          actual-data-nodes: ds-$->{1..3}.t_order_detail_$->{1..4}
          #表的分表策略
          table-strategy:
            standard:
              sharding-algorithm-name: sharding-table-detail-by-user-id
              sharding-column: user_id
      binding-tables:
        - t_order,t_order_detail
  #打印SQL语句
  props:
    sql-show: true

代码

//2.保存订单与订单详情分库分表
@GetMapping("test02/{userId}")
public void saveOrderInfo(@PathVariable Long userId){
    TOrder tOrder = new TOrder();
    tOrder.setTradeNo("enjoy6288");
    tOrder.setOrderPrice(9900);
    tOrder.setUserId(userId);//ds-1,table_4
    order1Service.save(tOrder);

    TOrderDetail iphone13 = new TOrderDetail();
    iphone13.setOrderId(tOrder.getId());
    iphone13.setSkuName("Iphone13");
    iphone13.setSkuNum(1);
    iphone13.setSkuPrice(6000);
    iphone13.setUserId(userId);
    detail1Service.save(iphone13);

    TOrderDetail sanxin = new TOrderDetail();
    sanxin.setOrderId(tOrder.getId());
    sanxin.setSkuName("三星");
    sanxin.setSkuNum(2);
    sanxin.setSkuPrice(3900);
    sanxin.setUserId(userId); //要进行分片计算
    detail1Service.save(sanxin);
    System.out.println("执行完成");

效果

两张表实现分库分表查询

Controller(待)

//3.查询订单与订单详情
@GetMapping("test03/{userId}")
public void test03(@PathVariable Long userId){
    List<TOrder> orderList=order1Mapper.queryOrderAndDetail(userId,null);
    //根据订单的id查询订单(全库查询) 没有使用分片的键 速度相当慢
    //List<TOrder> orderList=order1Mapper.queryOrderAndDetail(null,1624253671124619266L);
    System.out.println(orderList);
}

配置文件

shardingsphere:
  datasource:
    #真实物理数据库数据源的名称
    names: ds-1,ds-2,ds-3
    ds-1:
      type: com.zaxxer.hikari.HikariDataSource
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://10.211.55.25:3306/db_order_1?characterEncoding=utf-8&useSSL=false
      username: root
      password: root
    ds-2:
      type: com.zaxxer.hikari.HikariDataSource
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://10.211.55.25:3306/db_order_2?characterEncoding=utf-8&useSSL=false
      username: root
      password: root
    ds-3:
      type: com.zaxxer.hikari.HikariDataSource
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://10.211.55.25:3306/db_order_3?characterEncoding=utf-8&useSSL=false
      username: root
      password: root
  #分库分表的策略
  rules:
    sharding:
      #配置一个分库算法
      default-database-strategy:
        standard:
          sharding-column: user_id
          sharding-algorithm-name: sharding-db-by-user-id
      #配置一个具体的分表分表算法
      sharding-algorithms:
        #分库具体算法
        sharding-db-by-user-id:
          type: INLINE
          props:
            #ds-1,ds-2,ds-3
            algorithm-expression: ds-$->{user_id%3+1}
        #分表的具体算法
        sharding-table-order-by-user-id:
          type: INLINE
          props:
            #t_order_1,t_order_2,t_order_3,t_order_4
            algorithm-expression: t_order_$->{user_id%4+1}
        sharding-table-detail-by-user-id:
          type: INLINE
          props:
            #t_order_detail_1,t_order_detail_2,t_order_detail_3,t_order_detail_4
            algorithm-expression: t_order_detail_$->{user_id%4+1}
      #真实SQL语句查询
      tables:
        t_order:
          actual-data-nodes: ds-$->{1..3}.t_order_$->{1..4}
          #表的分表策略
          table-strategy:
            standard:
              sharding-column: user_id
              sharding-algorithm-name: sharding-table-order-by-user-id
        t_order_detail:
          actual-data-nodes: ds-$->{1..3}.t_order_detail_$->{1..4}
          #表的分表策略
          table-strategy:
            standard:
              sharding-column: user_id
              sharding-algorithm-name: sharding-table-detail-by-user-id

出现的问题

解决方案

对商品详情表也添加一个user_id的字段

对两张表进行绑定

mapper代码

<resultMap id="orderMap" type="com.atguigu.entity.TOrder" autoMapping="true">
    <id property="id" column="id"></id>
    <collection property="orderDetailList" ofType="com.atguigu.entity.TOrderDetail" autoMapping="true">
        <id property="id" column="order_detail_id"></id>
    </collection>
</resultMap>

<select id="queryOrderAndDetail" resultMap="orderMap">
    SELECT
        a.*,
        b.id order_detail_id,
        b.user_id,
        b.sku_num,
        b.sku_name,
        b.sku_price,
        b.user_id,
        b.order_id
    FROM
        t_order a
            LEFT JOIN t_order_detail b ON a.id = b.order_id
    <where>
        <if test="userId!=null">
            a.user_id = #{userId}
        </if>
        <if test="orderId!=null">
            a.id = #{orderId}
        </if>
    </where>
</select>

根据订单id查询订单信息

mapper代码

<resultMap id="orderMap" type="com.atguigu.entity.TOrder" autoMapping="true">
    <id property="id" column="id"></id>
    <collection property="orderDetailList" ofType="com.atguigu.entity.TOrderDetail" autoMapping="true">
        <id property="id" column="order_detail_id"></id>
    </collection>
</resultMap>

<select id="queryOrderAndDetail" resultMap="orderMap">
    SELECT
        a.*,
        b.id order_detail_id,
        b.user_id,
        b.sku_num,
        b.sku_name,
        b.sku_price,
        b.user_id,
        b.order_id
    FROM
        t_order a
            LEFT JOIN t_order_detail b ON a.id = b.order_id
    <where>
        <if test="userId!=null">
            a.user_id = #{userId}
        </if>
        <if test="orderId!=null">
            a.id = #{orderId}
        </if>
    </where>
</select>

出现的问题

全库查询-----没有使用分片的键速度相当慢

读写分离+主从复制+分库分表

查Controller

//3.查询订单与订单详情
@GetMapping("test03/{userId}")
public void test03(@PathVariable Long userId){
    List<TOrder> orderList=order1Mapper.queryOrderAndDetail(userId,null);
    //根据订单的id查询订单(全库查询) 没有使用分片的键 速度相当慢
    //List<TOrder> orderList=order1Mapper.queryOrderAndDetail(null,1624253671124619266L);
    System.out.println(orderList);
}

写数据

配置文件

shardingsphere:
  datasource:
    names: ds-1,ds-1-read1,ds-1-read2,ds-2,ds-2-read1,ds-2-read2,ds-3,ds-3-read1,ds-3-read2
    #一号组
    ds-1:
      type: com.zaxxer.hikari.HikariDataSource
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://192.168.121.128:3306/db_order_1?characterEncoding=utf-8&useSSL=false
      username: root
      password: root
    ds-1-read1:
      type: com.zaxxer.hikari.HikariDataSource
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://192.168.121.128:3307/db_order_1?characterEncoding=utf-8&useSSL=false
      username: root
      password: root
    ds-1-read2:
      type: com.zaxxer.hikari.HikariDataSource
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://192.168.121.128:3308/db_order_1?characterEncoding=utf-8&useSSL=false
      username: root
      password: root
    #二号组
    ds-2:
      type: com.zaxxer.hikari.HikariDataSource
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://192.168.121.128:3306/db_order_2?characterEncoding=utf-8&useSSL=false
      username: root
      password: root
    ds-2-read1:
      type: com.zaxxer.hikari.HikariDataSource
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://192.168.121.128:3307/db_order_2?characterEncoding=utf-8&useSSL=false
      username: root
      password: root
    ds-2-read2:
      type: com.zaxxer.hikari.HikariDataSource
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://192.168.121.128:3308/db_order_2?characterEncoding=utf-8&useSSL=false
      username: root
      password: root
    #三号组
    ds-3:
      type: com.zaxxer.hikari.HikariDataSource
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://192.168.121.128:3306/db_order_3?characterEncoding=utf-8&useSSL=false
      username: root
      password: root
    ds-3-read1:
      type: com.zaxxer.hikari.HikariDataSource
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://192.168.121.128:3307/db_order_3?characterEncoding=utf-8&useSSL=false
      username: root
      password: root
    ds-3-read2:
      type: com.zaxxer.hikari.HikariDataSource
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://192.168.121.128:3308/db_order_3?characterEncoding=utf-8&useSSL=false
      username: root
      password: root
  #配置读写分离策略
  rules:
    readwrite-splitting:
      data-sources:
        #读写分离多个数据源逻辑名称
        order-rw-1:
          static-strategy:
            write-data-source-name: ds-1
            read-data-source-names: ds-1-read1,ds-1-read2
          loadBalancerName:  read-lb
        order-rw-2:
          static-strategy:
            write-data-source-name: ds-2
            read-data-source-names: ds-2-read1,ds-2-read2
          loadBalancerName:  read-lb
        order-rw-3:
          static-strategy:
            write-data-source-name: ds-3
            read-data-source-names: ds-3-read1,ds-3-read2
          loadBalancerName:  read-lb
      loadBalancers:
        read-lb:
          type: ROUND_ROBIN
    sharding:
      #配置分库算法
      default-database-strategy:
        standard:
          sharding-algorithm-name: sharding-db-by-user-id
          sharding-column: user_id
      #具体算法如何做
      sharding-algorithms:
        #具体分库算法如何实现
        sharding-db-by-user-id:
          type: INLINE
          props:
            #ds-1,ds-2,ds-3
            algorithm-expression: order-rw-$->{user_id%3+1}
        #具体分表算法如何实现
        sharding-table-order-by-user-id:
          type: INLINE
          props:
            #t_order_1,t_order_2,t_order_3,t_order_4
            algorithm-expression: t_order_$->{user_id%4+1}
        sharding-table-detail-by-user-id:
          type: INLINE
          props:
            #t_order_detail_1,t_order_detail_2,t_order_detail_3,t_order_detail_4
            algorithm-expression: t_order_detail_$->{user_id%4+1}
      #真实SQL如何实现的
      tables:
        t_order:
          actual-data-nodes: order-rw-$->{1..3}.t_order_$->{1..4}
          #表的分表策略
          table-strategy:
            standard:
              sharding-algorithm-name: sharding-table-order-by-user-id
              sharding-column: user_id
        t_order_detail:
          actual-data-nodes: order-rw-$->{1..3}.t_order_detail_$->{1..4}
          #表的分表策略
          table-strategy:
            standard:
              sharding-algorithm-name: sharding-table-detail-by-user-id
              sharding-column: user_id
      binding-tables:
        - t_order,t_order_detail
  #打印SQL语句
  props:
    sql-show: true

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CRMEB标准版Mysql修改sql_mode

数据库配置 1.宝塔控制面板-软件商店-MySql-设置 2.点击配置修改&#xff0c;查找sql-mode或sql_mode &#xff08;可使用CtrlF快捷查找&#xff09; 3.复制 NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION 然后替换粘贴&#xff0c;保存 注&#xff1a;MySQL8.0版本的 第三步用…

Redis --- 第四讲 --- 常用数据结构 --- string类型

一、认识数据类型和编码方式 有序集合&#xff0c;相当于除了存储member之外&#xff0c;还需要存储一个score&#xff08;权重&#xff0c;分数&#xff09; Redis底层在实现上述数据结构的时候&#xff0c;会在源码层面&#xff0c;针对上述实现进行特定的优化&#xff0c;来…

文生图:Stable Diffusion、Midjourny

前言 Stable Diffusion&#xff08;SD&#xff09;和Midjourney&#xff08;MJ&#xff09;是当前流行的两款AI图像生成工具&#xff0c;它们各有特点和优势&#xff1a; **- Stable Diffusion是完全开源的&#xff0c;**这意味着用户可以免费使用&#xff0c;并且有技术能力…

excel如何把年龄转换为日期

总体的思路 我们从一个核心的日期函数出发 我们首先需要年月日 我的数据大概是这样的。 获取年份 第一步&#xff1a;提取岁前面的数字 left(目标单元格&#xff0c;“从左到右获取第几个字符”)第二步:替换掉数字后面的岁 第三步:新增一个单元格 在里面填入年 第四步:用…

Android系統Audio hal

一.Android系統Audio hal简介 Android系统的音频硬件抽象层(HAL)是系统与硬件之间的桥梁,允许音频应用和服务访问底层音频硬件,而无需直接与硬件交互。 主要组件: 音频 HAL 接口:定义了应用和服务如何调用音频硬件的规范。典型的音频操作包括播放、录制、音量控制等。 …

N1060A 50/85GHz精密型波形分析模块

N1060A 50/85GHz精密型波形分析模块 苏州新利通 概述 Keysight N1060A 精密型波形分析仪是一款数字通信分析仪&#xff08;DCA&#xff09;模块&#xff0c;可与 Keysight N1000A 主机兼容。 与是德科技的所有其他 DCA 模块一样&#xff0c;N1060A 提供了广泛的配置和性能选…

【C语言】数组函数冒泡排序bubble sort

数组&#xff1a;对于n个数字进行排序&#xff0c;就必须定义n个变量来存储。那么为了统一处理&#xff0c;选择数组就十分便捷了。 函数&#xff1a;将排序算法写到函数中&#xff0c;后续遇到所有的排序需求&#xff0c;都可以直接进行调用。 冒泡排序&#xff1a;受气泡在水…

HDFS详细分析

目录 一、HDFS架构 &#xff08;1&#xff09;Block - 数据块 &#xff08;2&#xff09;MetaData - 元数据 &#xff08;3&#xff09;NameNode - 主结点 &#xff08;4&#xff09;DataNode - 从结点 &#xff08;5&#xff09;SecondaryNameNode 二、HDFS的特点 &…

【19楼-注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

2024年下软考——信息系统运行管理员考前30天冲刺学习指南!!!

2024下半年软考已经迫在眉睫了&#xff0c;还没有开始备考的小伙伴赶紧行动起来。为了帮助大家更好的冲刺学习&#xff0c;特此提供一份信息系统运行管理员考前30天学习指南。本指南包括考情分析、学习规划、冲刺攻略三个部分&#xff0c;可以参考此指南进行最后的复习要领&…

javaWeb项目-Springboot+vue-校园论坛系统功能介绍

本项目源码&#xff08;点击下方链接下载&#xff09;&#xff1a;java-springbootvue-xx学校校园论坛信息系统实现源码(项目源码-说明文档)资源-CSDN文库 项目关键技术 开发工具&#xff1a;IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7 框架&#xff1a;ssm、Springboot…

鼠标移入盒子,盒子跟随鼠标移动

demo效果&#xff1a; 鼠标移入盒子&#xff0c;按下鼠标,开启移动跟随移动模式,再次按下关闭移动模式 涉及主要属性 在元素上单击鼠标按钮时输出鼠标指针的坐标&#xff1a; var x event.pageX; // 获取水平坐标 var y event.pageY; // 获取垂直坐标元素offsetL…

【含开题报告+文档+PPT+源码】基于SSM的景行天下旅游网站的设计与实现

开题报告 随着互联网的快速发展&#xff0c;旅游业也逐渐进入了数字化时代。作为一个旅游目的地&#xff0c;云浮市意识到了互联网在促进旅游业发展方面的巨大潜力。为了更好地推广云浮的旅游资源&#xff0c;提高旅游服务质量&#xff0c;云浮市决定开发一个专门的旅游网站。…

【python】用tk做一个简单的商品搜索更新展示的桌面应用

import tkinter as tk from tkinter import ttk import pandas as pddata_list [{id:1,name: 苹果, price: 6.5,tag:水果},{id:2,name: 香蕉, price: 2.5,tag:水果},{id:3,name: 葡萄, price: 8.5,tag:水果},{id:4,name: 橘子, price: 4.5,tag:水果}, ]df pd.DataFrame(data_…

SwiftUI 如何取得 @Environment 中 @Observable 对象的绑定?

概述 从 SwiftUI 5.0&#xff08;iOS 17&#xff09;开始&#xff0c;苹果推出了全新的 Observation 框架。它作为下一代内容改变响应者全面参与到数据流和事件流的系统中。 有了 Observation 框架的加持&#xff0c;原本需要多种状态类型的 SwiftUI 视图现在只需要 3 种即可大…

海康NVR管理平台EasyNVR多品牌NVR管理工具实现智能化视频管理介入现代化工厂

一、方案背景 在当今这个日新月异的时代&#xff0c;制造业作为国民经济的支柱之一&#xff0c;正经历着前所未有的变革。随着信息技术的飞速发展&#xff0c;工厂的现代化管理手段准确性也越来越高&#xff0c;越来越丰富&#xff0c;各种先进的技术手段比如视频监控系统&…

R语言医学数据分析实践-R编程环境的搭建

【图书推荐】《R语言医学数据分析实践》-CSDN博客 《R语言医学数据分析实践 李丹 宋立桓 蔡伟祺 清华大学出版社9787302673484》【摘要 书评 试读】- 京东图书 (jd.com) R语言编程_夏天又到了的博客-CSDN博客 R语言对编程环境的要求不高&#xff0c;可以在多种操作系统平台上…

对于SOCKS协议的一些认知误区有哪些?

代理协议在设备与代理服务器之间的数据交换中起到了关键作用。在这方面&#xff0c;SOCKS代理协议是常见的选择之一&#xff0c;被广泛应用于下载、传输和上传网络数据的场景。然而&#xff0c;关于SOCKS代理协议存在一些常见的误解&#xff0c;让我们来逐一了解。 一、使用SO…

nRF54L15—蓝牙低功耗双核系统级芯片(SoC)

nRF54L15 是 nRF54L 系列的首款系统级芯片 (SoC)。它是一款超低功耗蓝牙 5.4 SoC&#xff0c;具有同类最佳的新型多协议无线电和先进的安全功能。nRF54L 系列以更紧凑的封装将广受欢迎的 nRF52 系列提升到新的水平&#xff0c;具有出色的处理能力和效率、扩展的内存和新型外设。…

开发 - develop-codescan-zwcz53

开发 - develop-codescan-zwcz53 1. 开发 - CodeScan2. 前言3. CodeScan3.1. 工具概述3.2. 编译3.3. 功能3.4. 使用3.5. 高级用法3.5.1. 高扩展性3.5.2. 扫描位置3.5.3. 过滤字符串(只写了JSP PHP)3.5.4. 静态分析依赖情况 3.6. TODO3.7. 支持项目3.8. 详细使用文章(内附案例)…