25人参与 • 2025-08-07 • ar
随着系统数据量和用户量不断增长,传统单体数据库容易遇到瓶颈:
写入/查询压力大:单表千万级数据,索引效率下降。
存储超限:单机磁盘空间和 iops 不堪重负。
水平扩展困难:业务难以横向拓展。
为了解决这些问题,开发者往往采用 分库分表 技术,将一张大表分成多个小表,分布在不同数据库中,实现水平扩展和负载均衡。
apache shardingsphere 是一款开源的 分布式数据库中间件框架,可以帮助开发者轻松实现:
shardingsphere 核心组件包括:
组件 | 说明 |
---|---|
shardingsphere-jdbc | jdbc 封装层,嵌入应用中,适用于微服务架构 |
shardingsphere-proxy | 独立部署的数据库代理,支持多语言访问 |
shardingsphere-sidecar(规划中) | 面向云原生场景,service mesh 结构 |
功能 | 简要说明 |
---|---|
分库分表 | 按字段配置路由策略,自动将 sql 分发到对应的数据库/表 |
读写分离 | 自动区分读写请求,路由到主/从数据库 |
灵活分片策略 | 支持取模、范围、hint、自定义算法等多种策略 |
事务支持 | 支持本地事务和分布式事务(seata/xa) |
透明化使用 | 对开发者来说使用方式与普通 jdbc 几乎一致,只需配置逻辑表名 |
示例:使用 java 原生程序 + shardingsphere-jdbc + h2 内存数据库,模拟一个电商订单系统按 user_id
分库,order_id
分表。
ds0
, ds1
t_order_0
, t_order_1
t_order
<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>
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)); } } } }
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()); }
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")); } } }
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使用内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论