百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

分库分表常见中间件介绍和ShardingSphere极速认知+实战内容

mhr18 2024-12-24 12:21 13 浏览 0 评论

大话业界常见数据库分库分表中间件介绍

Cobar(已经被淘汰)

TDDL: 淘宝根据自己的业务特点开发了TDDL(Taobao Distributed Data Layer),它是基于JDBC规范,没有Server,以client-jar的形式存储,引入项目即可使用。开源的功能比较少,阿里内部使用为主。

MyCat: Java语言编写的Mysql数据网络协议开源的中间件,它的前身是Cobar,遵守Mysql原生的协议,跨语言,跨平台,跨数据库的通用中间件代理。Mycat是基于Proxy,它腹泻了MySQL协议,将Mycat Server伪装成一个MySQL数据库,它和ShardingShere下的Sharding-proxy作用类似,需要单独的部署。

官网地址:www.mycat.org.cn/

Sharding-JDBC: 基于jdbc驱动,不用额外的proxy,支持任意实现JDBC规范的数据库,它使用客户端直连数据库,以jar包形式提供服务,无需额外的部署和依赖。可以理解为加强版的JDBC驱动,兼容JDBC和各类ORM框架

面试官最爱问的Mycat与ShardingJdbc区别

1、两者的设计理念是相同的,主流程都是SQL解析->SQL路由->SQL改写->结果并归

2、sharding-jdbc是基于jdbc驱动,不用额外的proxy,在本地应用层重写Jdbc原生的方法,实现数据库分片形式。sharding-jdbc是基于JDBC接口的扩展,是以jar包的形式提供轻量级服务的,性能高,代码有入侵性。

3、Mycat是基于Proxy,它复写了MySQL协议,将Mycat Server伪装成一个MySQL数据库,客户端所有的jdbc请求都必须要先交给MyCat,再有MyCat转发到具体的真实服务器,缺点效率偏低,中间包装类一层,代码无侵入性。

ShardingSphere的三大构成

ShardingSphere-Sidecar(规划中): 定位为Kubernetes的云原生数据库代理,以Sidecar的形式代理所有对数据库的访问,通过无中心、零侵入的方案提供与数据库交互的啮合层,就是Database Mesh,又被称为数据库网格。

ShardingSphere-JDBC: 它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可以理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架。适用于任何基础JDBC的ORM框架,比如JPA,Hibernate,Mybatis或者直接使用JDBC。支持任何第三方的数据库俩啮齿,比如DBCP,C3P0,BoneCP,HikariCP等等。还支持任意实现JDBC规范的数据库,目前支持MySQL、PostgreSQL、Oracle、SQLServer以及任何可使用 JDBC访问的数据库。采用无中心化架构,与应用程序共享资源,适用于Java开发的高性能轻量级OLTP应用。

ShardingSphere-Proxy: 数据库代理端,提供封装了数据库二进制协议的服务端版本,用于完成对异构语言的支持,向应用程序完全透明,可以直接当做MySQL/PostgreSQL。它可以使用任何兼容MySQL/PostgreSQL协议的访问客户端(比如像:MySQL Command Client,MySQL Workbench,Navicat等)操作数据。

三个组件的对比


ShardingSphere-Sidecar

ShardingSphere-JDBC

ShardingSphere-Proxy

数据库

MySQL/PostgreSQL

任意

MySQL/PostgreSQL

连接消耗数

异构语言

任意

仅Java

任意

性能

损耗低

损耗低

损耗略高

无中心化

静态入口

Sharding-JDBC常见概念术语

数据节点Node:数据分片的最小单元,由数据源名称和数据表组成,如:ds_0.product_order_0

真实表:在分片的数据库中真实存在的物理表,比如订单表:product_order_0、product_order_1、product_order_2。

逻辑表:水平拆分的数据库(表)的相同逻辑和数据结构表的总称,如:订单表 product_order_0、product_order_1、product_order_2,逻辑表就是product_order

绑定表:指的是分片规则一致的主表和子表,如:product_order表和product_order_item表,均按照order_id分片,则此两张表互为绑定表关系。绑定表之间的多表关联查询不会出现笛卡尔积关联,关联查询效率将大大提升

广播表:指所有的分片数据源中都存在的表,表结构和表中的数据在每个数据库中均完全一致,适用于数据量不大且需要与海量数据的表进行关联查询的场景。例如:字典表、配置表

分库分表和Sharding-jdbc常见分片算法

数据库表分片(水平库、表): 包含了分片键与分片策略

分片键: 用于分片的数据库字段,是把数据库(表)水平拆分除了对单分片字段的支持,ShardingSphere也支持根据多个字段进行分片的关键字段,如prouduct_order订单表,根据订单号 out_trade_no做哈希取模,则out_trade_no是分片键.。

分片策略

行表达式分片策略InlineShardingStrategy(必备): 只支持【单片分键】使用的Groovy的表达式,提供SQL语句中的=和IN的分片操作支持,可以通过简单的配置使用,无需自定义分片算法,从而避免繁琐的Java代码开发。

prouduct_order_$->{user_id % 8}` 表示订单表根据user_id模8,而分成8张表,
表名称为`prouduct_order_0`到`prouduct_order_7

标准分片策略StandardShardingStrategy: 只支持【单分片键】,提供PreciseShardingAlgorithm和RangeShardingAlgorithm两个分片算法,PreciseShardingAlgorithm 精准分片 是必选的,用于处理=和IN的分片而RangeShardingAlgorithm 范围分配 是可选的,用于处理BETWEEN AND分片,如果不配置RangeShardingAlgorithm,如果SQL中用了BETWEEN AND语法,则将按照全库路由处理,性能下降。

复合分片策略ComplexShardingStrategy: 支持【多分片键】,多分片键之间的关系复杂,由开发者自己实现,提供最大的灵活度,提供对SQL语句中的=, IN和BETWEEN AND的分片操作支持。

Hint分片策略HintShardingStrategy: 这种分片策略无需配置分片健,分片健值也不再从 SQL中解析,外部手动指定分片健或分片库,让 SQL在指定的分库、分表中执行,用于处理使用Hint行分片的场景,通过Hint而非SQL解析的方式分片的策略,Hint策略会绕过SQL解析的,对于这些比较复杂的需要分片的查询,Hint分片策略性能可能会更好。

ShardingSphere实战

SQL脚本

CREATE TABLE `product_order_0` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `out_trade_no` varchar(64) DEFAULT NULL COMMENT '订单唯一标识',
  `state` varchar(11) DEFAULT NULL COMMENT 'NEW 未支付订单,PAY已经支付订单,CANCEL超时取消订单',
  `create_time` datetime DEFAULT NULL COMMENT '订单生成时间',
  `pay_amount` decimal(16,2) DEFAULT NULL COMMENT '订单实际支付价格',
  `nickname` varchar(64) DEFAULT NULL COMMENT '昵称',
  `user_id` bigint DEFAULT NULL COMMENT '用户id',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

实体类(用的mybatiplus)

@Data
@EqualsAndHashCode(callSuper = false)
@TableName("product_order")
public class ProductOrderDO {

    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    private String outTradeNo;

    private String state;

    private Date createTime;

    private Double payAmount;

    private String nickname;

    private Long userId;

}

//数据库实体类
public interface ProductOrderMapper extends BaseMapper<ProductOrderDO> {

}

配置文件

server.port=8080
spring.application.name=xdclass-jdbc

logging.level.root=INFO
# 打印执行的数据库以及语句
spring.shardingsphere.props.sql.show=true

# 数据源 db0
spring.shardingsphere.datasource.names=ds0
# 第一个数据库
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://120.25.217.15:3306/shop_order_0?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=xdclass.net168



# 指定product_order表的数据分布情况,配置数据节点,行表达式标识符使用 ${...} 或 $->{...},但前者与 Spring 本身的文件占位符冲突,所以在 Spring 环境中建议使用 $->{...}
spring.shardingsphere.sharding.tables.product_order.actual-data-nodes=ds0.product_order_$->{0..1}
# 指定product_order表的分片策略,分片策略包括【分片键和分片算法】 
spring.shardingsphere.sharding.tables.product_order.table-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.product_order.table-strategy.inline.algorithm-expression=product_order_$->{user_id % 2}

单元测试

@RunWith(SpringRunner.class)  //底层用junit  SpringJUnit4ClassRunner
@SpringBootTest(classes = DemoApplication.class)
@Slf4j
public class DbTest {

    @Autowired
    private ProductOrderMapper productOrderMapper;

    @Test
    public void testSaveProductOrder(){

        for(int i=0;i<10;i++){
            ProductOrder productOrder = new ProductOrder();
            productOrder.setCreateTime(new Date());
            productOrder.setNickname("程序员小三i="+i);
            productOrder.setOutTradeNo(UUID.randomUUID().toString().substring(0,32));
            productOrder.setPayAmount(100.00);
            productOrder.setState("PAY");
            productOrder.setUserId(Long.valueOf(i+""));
            productOrderMapper.insert(productOrder);
        }
    }
}

控制台SQL

Login SQL:逻辑SQL,没具体到哪一个数据节点

Actual SQL:真实SQL,具体到每一个数据节点的SQL

作者:零零后程序员小三
链接:https://juejin.cn/post/7061854754644688932

相关推荐

Team IDE 集成管理工具

Team·IDE工具简介TeamIDE工具集成SSH、FTP、MySql、Redis、Zookeeper、Kafka、Elasticsearch等管理工具Team·IDE功能模块目录结...

MySQL大数据表处理策略,原来一直都用错了……

场景当我们业务数据库表中的数据越来越多,如果你也和我遇到了以下类似场景,那让我们一起来解决这个问题。数据的插入,查询时长较长后续业务需求的扩展,在表中新增字段,影响较大表中的数据并不是所有的都为有效数...

Java程序员你真的甘心只做增删改查吗

各位志同道合的朋友们大家好,我是一个一直在一线互联网踩坑十余年的编码爱好者,现在将我们的各种经验以及架构实战分享出来,如果大家喜欢,就关注我,一起将技术学深学透,我会每一篇分享结束都会预告下一专题最近...

Java后端开发除了增删改查还有什么?

后端的追求:接口稳定、架构合理、业务逻辑清晰、模块拆分合理、支持高并发等。软件本身归根到底都是由算法+数据结构构成的,进一步细化之后,其实就是通过一系列的增删改查操作,构成算法,对数据结构进行操作,赋...

基于shiro实现session持久化和分布式共享

前言本文写下session持久化和分布式共享基于shiro框架对session的管理机制来实现必要性一直处于登陆状态:你登陆微信不可能三天两头就让你重新登陆吧?而是一直处于登陆状态除非主动退出...

为啥工作那么多年,你还是只会增删改查?

你以为没有这样的感觉,工作中领导和同事都非常认可你的能力,但是你想更进一步,却不被认可。想出去看看,跳槽面试,却也是屡屡碰壁。面试的过程中,面试官问技术方案,明明心里很清楚,或者说印象还行,可就是说不...

Java程序员除了做增删改查还能干嘛?

就以Java后端开发为例,说说不同级别程序员干的事情。1初级开发,大概是有3年Java开发经验。22年底,上海,这批程序员如果学历是本科,薪资一般是8k到2w,当然如果能进好公司或互联网大厂,薪资能...

Java面试题及答案总结(2025版持续更新)

大家好,我是Java面试分享面对Java后端岗位的激烈竞争,掌握系统化的知识体系至关重要。本文整理了覆盖主流技术栈的高频面试题,助你高效备战,内容包含:Java基础、并发编程、Spring生态、数据库...

微服务架构之API网关——在微服务项目中的技术框架和用法实践

API网关技术实战在介绍了API网关的相关理论之后,大家可以了解到API网关的作用和优缺点,接下来将为大家介绍API网关在微服务项目中的技术框架和用法实践。Zuul网关其实API网关并不是很难的技术,...

带小白黑客入门,你也可以跟我们一起成为黑客大牛

小编这几天一直在做关于ssrf的实验,这篇文章可以带纯小白黑客入门。靶机ip地址:192.168.2.138查看靶机运行的redis服务。攻击机为ip192.168.2.112.用客户端redis-c...

Python最常见的170道面试题全解析答案(二)

60.请写一个Python逻辑,计算一个文件中的大写字母数量答:withopen(‘A.txt’)asfs:count=0foriinfs.read():ifi.isupper...

Spring Boot项目集成Redis,原来这么简单!

在现代软件开发的“快车道”上,SpringBoot无疑是许多开发者手中的“神兵利器”。它以其“约定大于配置”的理念,大大简化了Java应用的开发和部署过程,让开发者能够将更多精力聚焦于业务逻辑本身。...

Apache Commons Pool——优化你的java内存

大家好,我是吉森。我会持续分享一些开发技巧、经验和技术,如果你也热爱各种开发技术,欢迎关注我。今天我们继续介绍ApacheCommons工具包,今天的主角是:CommonsPool。简单地说,它是...

码农成长系列-基于WebSocket的后台消息提醒

场景描述当用户对app有某些业务操作时,需要将该操作友好地提醒给,有接收提醒权限的后台管理者。技术场景分析经分析,要实现上述业务,业务拆解后可能需要解决如下业务①.触发提醒待推送数据的监听②.提醒时接...

百度直播消息系统的实践和演进

导读:直播业务的核心功能有两个,一个是实时音视频推拉流,另一个是直播间消息流的收发。本文主要介绍百度直播服务内的消息服务系统的设计实践和演化。一、背景直播间内用户聊天互动,形式上是常见的IM消息流;...

取消回复欢迎 发表评论: