it编程 > 游戏开发 > ar

Apache ShardingSphere简介及使用详解

25人参与 2025-08-07 ar

一 什么是 shardingsphere?

1.1 背景:为什么需要分库分表?

随着系统数据量和用户量不断增长,传统单体数据库容易遇到瓶颈:

为了解决这些问题,开发者往往采用 分库分表 技术,将一张大表分成多个小表,分布在不同数据库中,实现水平扩展和负载均衡。

1.2 什么是 apache shardingsphere?

apache shardingsphere 是一款开源的 分布式数据库中间件框架,可以帮助开发者轻松实现:

shardingsphere 核心组件包括:

组件说明
shardingsphere-jdbcjdbc 封装层,嵌入应用中,适用于微服务架构
shardingsphere-proxy独立部署的数据库代理,支持多语言访问
shardingsphere-sidecar(规划中)面向云原生场景,service mesh 结构

1.3 shardingsphere-jdbc 的核心功能

功能简要说明
分库分表按字段配置路由策略,自动将 sql 分发到对应的数据库/表
读写分离自动区分读写请求,路由到主/从数据库
灵活分片策略支持取模、范围、hint、自定义算法等多种策略
事务支持支持本地事务和分布式事务(seata/xa)
透明化使用对开发者来说使用方式与普通 jdbc 几乎一致,只需配置逻辑表名

二、实践部分:java + h2 实现分库分表

示例:使用 java 原生程序 + shardingsphere-jdbc + h2 内存数据库,模拟一个电商订单系统按 user_id 分库,order_id 分表。

2.1 项目结构

2.2 maven 依赖配置

<dependencies>
    <dependency>
        <groupid>org.apache.shardingsphere</groupid>
        <artifactid>shardingsphere-jdbc-core</artifactid>
        <version>5.4.1</version>
    </dependency>
    <dependency>
        <groupid>com.h2database</groupid>
        <artifactid>h2</artifactid>
        <version>2.2.220</version>
    </dependency>
    <dependency>
        <groupid>com.zaxxer</groupid>
        <artifactid>hikaricp</artifactid>
        <version>5.0.1</version>
    </dependency>
</dependencies>

2.3 核心代码结构

1. 创建真实表(物理分表)

public static void createtables() throws sqlexception {
    for (int i = 0; i < 2; i++) {
        string db = "ds" + i;
        try (connection conn = drivermanager.getconnection("jdbc:h2:mem:" + db + ";db_close_delay=-1;mode=mysql", "sa", "")) {
            statement stmt = conn.createstatement();
            for (int j = 0; j < 2; j++) {
                stmt.execute(string.format("""
                    create table if not exists t_order_%d (
                        order_id bigint primary key,
                        user_id int,
                        status varchar(50)
                    )
                """, j));
            }
        }
    }
}

2. 配置分库分表数据源

public static datasource createdatasource() throws sqlexception {
    map<string, datasource> datasourcemap = new hashmap<>();
    for (int i = 0; i < 2; i++) {
        hikaridatasource ds = new hikaridatasource();
        ds.setjdbcurl("jdbc:h2:mem:ds" + i + ";db_close_delay=-1;mode=mysql");
        ds.setusername("sa");
        ds.setpassword("");
        datasourcemap.put("ds" + i, ds);
    }
    shardingtableruleconfiguration ordertablerule = new shardingtableruleconfiguration(
        "t_order", "ds${0..1}.t_order_${0..1}");
    ordertablerule.setdatabaseshardingstrategy(
        new standardshardingstrategyconfiguration("user_id", "dbsharding"));
    ordertablerule.settableshardingstrategy(
        new standardshardingstrategyconfiguration("order_id", "tablesharding"));
    shardingruleconfiguration config = new shardingruleconfiguration();
    config.gettables().add(ordertablerule);
    config.getshardingalgorithms().put("dbsharding",
        new algorithmconfiguration("inline", props("algorithm-expression", "ds${user_id % 2}")));
    config.getshardingalgorithms().put("tablesharding",
        new algorithmconfiguration("inline", props("algorithm-expression", "t_order_${order_id % 2}")));
    return shardingspheredatasourcefactory.createdatasource(datasourcemap, list.of(config), new properties());
}

3. 插入与查询数据

public static void insertorder(datasource ds, long orderid, int userid, string status) throws sqlexception {
    try (connection conn = ds.getconnection()) {
        preparedstatement ps = conn.preparestatement("insert into t_order (order_id, user_id, status) values (?, ?, ?)");
        ps.setlong(1, orderid);
        ps.setint(2, userid);
        ps.setstring(3, status);
        ps.executeupdate();
    }
}
public static void queryorders(datasource ds) throws sqlexception {
    try (connection conn = ds.getconnection()) {
        resultset rs = conn.createstatement().executequery("select * from t_order");
        while (rs.next()) {
            system.out.printf("order_id=%d, user_id=%d, status=%s%n",
                    rs.getlong("order_id"),
                    rs.getint("user_id"),
                    rs.getstring("status"));
        }
    }
}

2.4 程序入口

public static void main(string[] args) throws exception {
    createtables();  // 创建实际分表
    datasource shardingdatasource = createdatasource();
    insertorder(shardingdatasource, 1001, 1, "init");
    insertorder(shardingdatasource, 1002, 2, "paid");
    insertorder(shardingdatasource, 1003, 3, "shipped");
    queryorders(shardingdatasource);
}

输出示例

order_id=1001, user_id=1, status=init
order_id=1002, user_id=2, status=paid
order_id=1003, user_id=3, status=shipped

shardingsphere 已自动根据你配置的策略将数据路由到对应的库和表!

总结

apache shardingsphere 提供了强大、灵活的分库分表能力,通过合理配置可以极大提升系统的性能与扩展性:

无论你是中小项目的快速原型,还是大规模高并发系统,shardingsphere 都是一个值得一试的解决方案。

完整代码

package org.example;
import com.zaxxer.hikari.hikaridatasource;
import org.apache.shardingsphere.driver.api.shardingspheredatasourcefactory;
import org.apache.shardingsphere.infra.config.algorithm.algorithmconfiguration;
import org.apache.shardingsphere.sharding.api.config.shardingruleconfiguration;
import org.apache.shardingsphere.sharding.api.config.rule.shardingtableruleconfiguration;
import org.apache.shardingsphere.sharding.api.config.strategy.sharding.standardshardingstrategyconfiguration;
import javax.sql.datasource;
import java.sql.*;
import java.util.*;
public class shardingh2example {
    public static void main(string[] args) throws exception {
        createtables(); //  注意:用 drivermanager 直连底层 db 建表
        datasource shardingdatasource = createdatasource();
        // 插入测试数据
        insertorder(shardingdatasource, 1001, 1, "init");
        insertorder(shardingdatasource, 1002, 2, "paid");
        insertorder(shardingdatasource, 1003, 3, "shipped");
        // 查询测试数据
        queryorders(shardingdatasource);
    }
    public static datasource createdatasource() throws exception {
        map<string, datasource> datasourcemap = new hashmap<>();
        // 模拟两个库:ds0 和 ds1(分别用两个内存 h2 实例模拟)
        for (int i = 0; i < 2; i++) {
            hikaridatasource ds = new hikaridatasource();
            ds.setjdbcurl("jdbc:h2:mem:ds" + i + ";db_close_delay=-1;mode=mysql");
            ds.setusername("sa");
            ds.setpassword("");
            datasourcemap.put("ds" + i, ds);
        }
        // 分表规则配置
        shardingtableruleconfiguration ordertablerule = new shardingtableruleconfiguration(
                "t_order", "ds${0..1}.t_order_${0..1}");
        // 分库策略(user_id)
        ordertablerule.setdatabaseshardingstrategy(new standardshardingstrategyconfiguration(
                "user_id", "dbsharding"));
        // 分表策略(order_id)
        ordertablerule.settableshardingstrategy(new standardshardingstrategyconfiguration(
                "order_id", "tablesharding"));
        shardingruleconfiguration shardingruleconfig = new shardingruleconfiguration();
        shardingruleconfig.gettables().add(ordertablerule);
        properties dbprops = new properties();
        dbprops.setproperty("algorithm-expression", "ds${user_id % 2}");
        shardingruleconfig.getshardingalgorithms().put("dbsharding",
                new algorithmconfiguration("inline", dbprops));
        properties tableprops = new properties();
        tableprops.setproperty("algorithm-expression", "t_order_${order_id % 2}");
        shardingruleconfig.getshardingalgorithms().put("tablesharding",
                new algorithmconfiguration("inline", tableprops));
        return shardingspheredatasourcefactory.createdatasource(datasourcemap, list.of(shardingruleconfig), new properties());
    }
    public static void createtables() throws sqlexception {
        for (int i = 0; i < 2; i++) {
            string dbname = "ds" + i;
            try (connection conn = drivermanager.getconnection("jdbc:h2:mem:" + dbname + ";db_close_delay=-1;mode=mysql", "sa", "")) {
                statement stmt = conn.createstatement();
                for (int j = 0; j < 2; j++) {
                    string sql = string.format("""
                        create table if not exists t_order_%d (
                            order_id bigint primary key,
                            user_id int,
                            status varchar(50)
                        )
                """, j);
                    stmt.execute(sql);
                }
            }
        }
    }
    // 辅助方法用于手动连接底层 h2 数据源
    private static hikaridatasource geth2datasource(string name) {
        hikaridatasource ds = new hikaridatasource();
        ds.setjdbcurl("jdbc:h2:mem:" + name + ";db_close_delay=-1;mode=mysql");
        ds.setusername("sa");
        ds.setpassword("");
        return ds;
    }
    public static void insertorder(datasource ds, long orderid, int userid, string status) throws sqlexception {
        try (connection conn = ds.getconnection()) {
            preparedstatement ps = conn.preparestatement("insert into t_order (order_id, user_id, status) values (?, ?, ?)");
            ps.setlong(1, orderid);
            ps.setint(2, userid);
            ps.setstring(3, status);
            ps.executeupdate();
        }
    }
    public static void queryorders(datasource ds) throws sqlexception {
        try (connection conn = ds.getconnection()) {
            resultset rs = conn.createstatement().executequery("select * from t_order");
            system.out.println("query results:");
            while (rs.next()) {
                system.out.printf("order_id: %d, user_id: %d, status: %s%n",
                        rs.getlong("order_id"),
                        rs.getint("user_id"),
                        rs.getstring("status"));
            }
        }
    }
}

到此这篇关于apache shardingsphere 初识使用的文章就介绍到这了,更多相关apache shardingsphere使用内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

您想发表意见!!点此发布评论

推荐阅读

Sharding-Proxy分库分表的实现方案

08-07

解决Failed to get nested archive for entry BOOT-INF/lib/xxx.jar问题

08-06

部分经典机器可惜淘汰! 华为鸿蒙HarmonyOS 5.1版本机型推送系统补丁

08-05

新增三机型升级! 华为鸿蒙 HarmonyOS 6.0.0 (20) Developer Beta2版推送

08-05

解决警告:No archetype found in remote catalog. Defaulting to internal catalog.问题

08-12

NGINX 报错 413 Request Entity Too Large的问题解决

08-13

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论