利用ShardingSphere(sharding-proxy)实现分库分表,通过整合ZooKeeper,进行简单配置文件修改轻松实现跨库跨表相关操作,轻量级零侵入整合项目开发

利用ShardingSphere(sharding-proxy)实现分库分表,通过整合ZooKeeper,进行简单配置文件修改轻松实现跨库跨表相关操作,轻量级零侵入整合项目开发

准备工作

下载相关文件:https://download.csdn.net/download/u014374009/11837831

点击下载

Linux和windows都可以使用!

1、解压文件
找到下面的文件夹,并进入。
在这里插入图片描述
在conf目录下进行配置。
在这里插入图片描述
修改下面两个配置文件中的一个配置文件,当然也可以全部都进行配置,第一个配置文件主要是进行主从数据库配置,第二个主要是进行数据库分库分表配置,也是本次主要演示的地方。
在这里插入图片描述
配置文件都很简单,基本上就是数据库连接信息。
在这里插入图片描述
在这里先创建两个数据库,在每个数据库下面分别建立四张表,相关的sql 建表语句在下载的文件中都有。
在这里插入图片描述
然后根据先前的配置文件,修改为自己的数据库连接配置信息。
在这里插入图片描述
接下来,配置server配置文件
在这里插入图片描述
其实主要就是把服务注册到 ZooKeeper 上,注意ZK的默认端口是2181,如果自己修改了,要对应的修改,下面会介绍ZK的安装配置。其次,就是配置用户名和密码,可以根据自己需要修改,这个在后面测试会用到。
在这里插入图片描述
下面是ZK的相关配置
在下载的文件夹中都有相关的文件。
在这里插入图片描述
进入conf目录。
在这里插入图片描述
把 zoo_sample.cfg 复制一份,改名为 zoo.cfg ,然后进行编辑。
在这里插入图片描述
主要配置一下数据和日志存放路径,这儿由于是windows系统,所以用了下面的路径,另外端口号,可以根据自己需要进行修改,一般不修改。
在这里插入图片描述
然后保存之后,到 ZK 的bin目录下,双击 zkServer.cmd 启动 ZK。
在这里插入图片描述
接着到 sharding-proxy-3.0.0 的 bin 目录下,双击 start.bat 启动sharding-proxy服务。
在这里插入图片描述
启动成功之后,会自动到 ZK 上注册服务,并会返回 registered 等信息,同时也会显示绑定的端口号,这个端口号就是后面数据库连接测试的端口号。
在这里插入图片描述
用Navicat进行测试,根据先前的信息,进行填写,端口号就是上面的,帐号密码就是 配置文件中 的 root,root。
在这里插入图片描述
连接成功,此时,环境已经搭建完成了。
在这里插入图片描述

测试工作

用Navicat连接成功后,会发现 数据库名字变为 配置文件中的名字,同时,两个数据库,四张表,变为一个数据库 两张表。
在这里插入图片描述
测试代码,可以根据自己需要修改。

package com.sharding.demo.controller;

import com.sharding.demo.bean.Order;
import com.sharding.demo.bean.OrderItem;
import io.shardingsphere.core.keygen.DefaultKeyGenerator;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.sql.*;

/**
 * @author: Frank
 * @email 1320259466@qq.com
 * @date: 2019/10/9
 * @time: 8:52
 * @fuction: about the role of class.
 */
public class TestSharingDB {
    private static Logger logger = LogManager.getLogger();

    public static void main(String[] args) {
        DefaultKeyGenerator key = new DefaultKeyGenerator();
        int userId = 45;
        Number orderIdKey = key.generateKey();
        Long orderId = orderIdKey.longValue();
        logger.info("分布式主键orderId:" + orderId);
        Number orderItemIdKey = key.generateKey();
        Long orderItemId = orderItemIdKey.longValue();
        logger.info("分布式主键orderItemId:" + orderItemId);
        Order order = new Order();
        order.setUserId(userId);
        order.setStatus("1");
        order.setOrderId(orderId);

        //Long returnOrderId = orderService.insert(order);
        Connection newConn = null;
        Statement newSmt=null;
        try
        {
            Class.forName("com.mysql.jdbc.Driver");
            newConn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3307/sharding_db?serverTimezone=UTC&useSSL=false","root", "root");
            if (newConn != null) {
                newSmt = newConn.createStatement();
                String sql="insert into t_order values ("+order.getOrderId()+","+order.getUserId()+",'"+order.getStatus()+"')";
//                System.out.println(sql);
                newSmt.executeUpdate(sql);//DDL语句返回值为0;
            }
        } catch (SQLException e1) {
            e1.printStackTrace();

        } catch (ClassNotFoundException e) {
            e.printStackTrace();

        } finally {
            try {
                newSmt.close();
                newConn.close();
            } catch(SQLException e) {
                throw new RuntimeException(e);
            }
        }
        //logger.info("插入成功后的returnOrderId:" + returnOrderId);

        OrderItem item = new OrderItem();
//        item.setOrderItemId(orderItemId);
        item.setOrderId(orderId);
        item.setUserId(userId);
        item.setStatus("1");
        //Long returnOrderItemId = orderItemService.insert(item);
        try
        {
            Class.forName("com.mysql.jdbc.Driver");
            newConn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3307/sharding_db?serverTimezone=UTC&useSSL=false","root", "root");
            if (newConn != null) {
                newSmt = newConn.createStatement();
                //String sql="insert into t_order values ('"+item.getOrderId()+"','"+item.getUserId()+"','"+item.getOrderItemId()+"','"+item.getStatus()+"')";
                String sql="insert into t_order_item values ("+item.getOrderId()+","+item.getUserId()+","+item.getOrderItemId()+")";
//                System.out.println(sql);
                newSmt.executeUpdate(sql);//DDL语句返回值为0;
            }
        } catch (SQLException e1) {
            e1.printStackTrace();

        } catch (ClassNotFoundException e) {
            e.printStackTrace();

        } finally {
            try {
                newSmt.close();
                newConn.close();
            } catch(SQLException e) {
                throw new RuntimeException(e);
            }
        }
        //logger.info("插入成功后的returnOrderItemId:" + returnOrderItemId);





        try
        {
            Class.forName("com.mysql.jdbc.Driver");
            newConn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3307/sharding_db?serverTimezone=UTC&useSSL=false","root", "root");
            if (newConn != null) {
                newSmt = newConn.createStatement();
                //String sql="insert into t_order values ('"+item.getOrderId()+"','"+item.getUserId()+"','"+item.getOrderItemId()+"','"+item.getStatus()+"')";
                String sql="select * from t_order join t_order_item on t_order_item.order_id=t_order.order_id";
//                System.out.println(sql);
                ResultSet rs = newSmt.executeQuery(sql);

                while(rs.next()){
                    Long id = rs.getLong(1);
                    Long name = rs.getLong(2);
                    String gender = rs.getString(3);
                    System.out.println("id:"+id+" 姓名:"+name+" 性别:"+gender);
                }

            }
        } catch (SQLException e1) {
            e1.printStackTrace();

        } catch (ClassNotFoundException e) {
            e.printStackTrace();

        } finally {
            try {
                newSmt.close();
                newConn.close();
            } catch(SQLException e) {
                throw new RuntimeException(e);
            }
        }


    }
}

测试结果。
在这里插入图片描述
上面代码多次执行以后,在 sqlyog中发现,数据分配到不同的表中。
在这里插入图片描述
在这里插入图片描述
在Navicat中查看,会发现,表的数据是 每个表的数据的并集,也就是把所有的数据整合在一起了。可以在所有 ORM 框架中(可通过DataSource选择使用原生JDBC开发,或者在JPA、Hibernate或MyBatis中使用),对数据库进行增删查改了。
在这里插入图片描述
分布式主键
传统数据库软件开发中,主键自动生成技术是基本需求。而各个数据库对于该需求也提供了相应的支持,比如MySQL的自增键,Oracle的自增序列等。 数据分片后,不同数据节点生成全局唯一主键是非常棘手的问题。同一个逻辑表内的不同实际表之间的自增键由于无法互相感知而产生重复主键。 虽然可通过约束自增主键初始值和步长的方式避免碰撞,但需引入额外的运维规则,使解决方案缺乏完整性和可扩展性。

Sharding-proxy介绍
Sharding-Proxy是ShardingSphere的第二个产品。 它定位为透明化的数据库代理端,提供封装了数据库二进制协议的服务端版本,用于完成对异构语言的支持。 目前先提供MySQL版本,它可以使用任何兼容MySQL协议的访问客户端(如:MySQL Command Client, MySQL Workbench等)操作数据,对DBA更加友好。

Atlas介绍
Atlas是由 Qihoo 360公司Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基础上,修改了大量bug,添加了很多功能特性。目前该项目在360公司内部得到了广泛应用,很多MySQL业务已经接入了Atlas平台,每天承载的读写请求数达几十亿条。同时,有超过50家公司在生产环境中部署了Atlas,超过800人已加入,并且这些数字还在不断增加。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
Sharding-Proxy 是一个开源的分库分表中间件,它可以帮助应用程序实现无感知的分库分表操作。下面是一个简单的步骤来利用 Sharding-Proxy 进行分库分表: 1. 安装和配置 Sharding-Proxy:首先,你需要下载 Sharding-Proxy 的安装包,并解压到你的服务器上。然后,根据你的需求修改配置文件,配置数据源和分片规则等信息。 2. 创建数据库和表:在进行分库分表之前,你需要创建相应的数据库和表结构。你可以选择手动创建,或者使用 Sharding-Proxy 提供的自动建表功能。 3. 配置分片规则:在 Sharding-Proxy配置文件中,你需要定义分片规则,指定如何将数据分散到不同的数据库和表中。可以使用基于范围、哈希、精确等多种分片算法。 4. 连接到 Sharding-Proxy:在应用程序中,需要修改数据库连接信息,将原来连接数据库的地址改为连接 Sharding-Proxy 的地址。这样应用程序就可以通过 Sharding-Proxy 访问分片后的数据。 5. 进行分库分表操作:现在你可以在应用程序中执行正常的数据库操作,而无需关心具体的分库分表细节。Sharding-Proxy 会根据配置的规则自动将数据路由到正确的库和表中。 需要注意的是,使用 Sharding-Proxy 进行分库分表操作需要仔细考虑数据一致性、事务处理、跨库查询等问题。在配置和使用过程中,建议参考官方文档和示例来确保正确性和性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码讲故事

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值