当前位置: 首页 > news >正文

从单表到分片:用ShardingSphere-JDBC实战改造Yudao-Cloud系统日志表(MySQL 8.0环境)

从单表到分片:用ShardingSphere-JDBC实战改造Yudao-Cloud系统日志表(MySQL 8.0环境)

当系统登录日志表的数据量突破千万级时,单表查询性能会以肉眼可见的速度下降。最近在优化Yudao-Cloud项目时,就遇到了这个典型场景——system_login_log表的查询响应时间从最初的200ms逐渐攀升到2秒以上。本文将分享如何在不改动业务代码的前提下,通过ShardingSphere-JDBC实现日志表的水平分片与读写分离,最终使查询性能回归到毫秒级。

1. 分片方案设计

1.1 分片键选择策略

在system_login_log表中,有三个字段适合作为分片键候选:

  • 用户ID:适合用户查询自己历史登录记录的场景
  • 登录时间:适合按时间范围查询的审计需求
  • 记录ID:适合全局唯一性要求高的场景

经过实际业务分析,我们最终选择用户ID作为分片键,原因如下:

-- 原始表结构示例 CREATE TABLE `system_login_log` ( `id` bigint NOT NULL AUTO_INCREMENT, `user_id` bigint NOT NULL, `login_time` datetime NOT NULL, `ip_address` varchar(45) DEFAULT NULL, `user_agent` text, PRIMARY KEY (`id`), KEY `idx_user_id` (`user_id`), KEY `idx_login_time` (`login_time`) ) ENGINE=InnoDB;

提示:选择分片键时需要重点考虑业务查询模式。如果80%的查询都带有user_id条件,那么它比时间戳更适合作为分片键。

1.2 分片算法选型

ShardingSphere提供多种分片算法,针对用户ID这种离散值,我们选择取模分片

算法类型适用场景优缺点
取模分片离散值均匀分布扩容困难但实现简单
范围分片连续值如时间戳易出现热点但扩容方便
哈希分片任意数据类型分布均匀但无法范围查询

最终确定的分片规则是:user_id % 4,将数据均匀分布到4个物理表中。

2. 环境配置实战

2.1 依赖配置关键点

在Yudao-Cloud的yudao-dependencies模块中添加ShardingSphere核心依赖:

<!-- pom.xml关键配置 --> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId> <version>5.4.1</version> </dependency>

特别注意需要排除冲突的连接池依赖:

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, DruidDataSourceAutoConfigure.class }) public class SystemApplication {}

2.2 分片规则配置

创建sharding-sphere-config.yaml配置文件,核心配置如下:

rules: - !SHARDING tables: system_login_log: actualDataNodes: ds.system_login_log_$->{0..3} tableStrategy: standard: shardingColumn: user_id shardingAlgorithmName: user_mod shardingAlgorithms: user_mod: type: MOD props: sharding-count: 4

注意:实际部署时需要预先创建system_login_log_0到system_login_log_3四个物理表,且必须移除原表的自增ID属性。

3. 数据迁移方案

3.1 在线迁移步骤

  1. 双写阶段:配置ShardingSphere同时写入新旧表
  2. 数据同步:使用DataX工具全量迁移历史数据
  3. 校验阶段:对比新旧表数据一致性
  4. 切流阶段:逐步将查询切换到分片表
# DataX迁移任务示例配置 { "job": { "content": [{ "reader": { "name": "mysqlreader", "parameter": {"column": ["*"], "connection": [{ "jdbcUrl": ["jdbc:mysql://old-db:3306/yudao"], "table": ["system_login_log"] }]} }, "writer": { "name": "mysqlwriter", "parameter": {"connection": [{ "jdbcUrl": "jdbc:mysql://new-db:3306/yudao", "table": ["system_login_log_${0..3}"] }]} } }] } }

3.2 灰度发布策略

通过配置多个版本的数据源实现平滑迁移:

# 多版本数据源配置示例 spring: shardingsphere: datasources: v1: # 旧版单表 v2: # 新版分片 rules: sharding: default-data-source-name: v1 tables: system_login_log: actual-data-sources: v2

4. 性能优化实践

4.1 查询优化技巧

分片环境下需要特别注意的查询模式:

// 好的查询 - 带分片键条件 @Select("SELECT * FROM system_login_log WHERE user_id = #{userId}") List<LoginLog> listByUser(@Param("userId") Long userId); // 坏的查询 - 全表扫描 @Select("SELECT * FROM system_login_log WHERE ip_address = #{ip}") List<LoginLog> listByIp(@Param("ip") String ip);

对于必须的全表查询,可以通过绑定表优化:

# 绑定表配置 rules: - !SHARDING bindingTables: - system_login_log, system_operation_log

4.2 监控指标配置

在Prometheus中添加关键监控项:

# application.yml监控配置 management: metrics: export: prometheus: enabled: true tags: application: ${spring.application.name} endpoint: prometheus: enabled: true health: show-details: always

重点关注以下指标:

  • shardingsphere_statements_total:SQL执行总数
  • shardingsphere_statements_latency_millis:查询延迟
  • shardingsphere_connections_active:活跃连接数

5. 异常处理经验

在实际迁移过程中,我们遇到过几个典型问题:

  1. 自增ID冲突:解决方案是改用Snowflake算法生成分布式ID
  2. 跨分片排序性能差:通过添加user_id前缀索引优化
  3. 分布式事务超时:调整shardingsphere.props.max.connections.size.per.query=5

最棘手的还是模糊查询性能问题,最终采用的解决方案是建立Elasticsearch索引,将ip_addressuser_agent字段同步到ES进行检索。

http://www.jsqmd.com/news/562679/

相关文章:

  • 球阀市场增长预测:预计到2032年将增长至1473.1亿元
  • 从WebM到WAV:前端音频格式转换全攻略(含完整代码)
  • OpCore Simplify:零基础也能轻松配置黑苹果的智能工具
  • PVC专用机选购指南:2026年五强服务商深度解析与华维机械首选推荐 - 2026年企业推荐榜
  • 引线框架市场前瞻:预计至2032年将增长至338.8亿元
  • 嵌入式调试实战:工具链与内存问题解决方案
  • RAG效果不好?试试Qwen3-Reranker-0.6B,快速提升问答系统准确率
  • Obsidian Pandoc插件:让笔记一键变身专业文档的终极解决方案
  • 零基础新手漏洞挖掘入门指南:要啥技能、去哪挖、怎么挖?收藏这篇就够了
  • 颠覆式桌面应用开发:.NET Windows Desktop Runtime如何解决企业级部署难题
  • TCP粘包问题解析与解决方案实践
  • 告别命令行!用MongoDB Compass图形化搞定数据库增删改查(Windows/Mac通用)
  • Qwen3-VL-WEBUI环境搭建指南:从系统准备到镜像启动,全程保姆级教学
  • 单片机死循环设计与中断机制解析
  • 2026消防工程塑料波纹管推荐指南:新能源包塑金属软管/新能源塑料波纹管/新能源电缆防水接头/核岛包塑金属软管/选择指南 - 优质品牌商家
  • Gradio Blocks保姆级教程:从Interface到自定义复杂布局,打造你的专属AI工具台
  • OpenClaw配置优化:提升nanobot模型响应速度的5个技巧
  • ”测试开发全日制学徒班7期第1天“-shell基础
  • 终极指南:如何零依赖抓取抖音直播间弹幕数据
  • Nano-Banana Studio模型量化:使用TensorRT加速推理
  • STM32语音导航机器人开发实战与优化
  • 嵌入式C语言全局变量滥用问题与优化实践
  • 家用纺织品市场洞察:预计至2032年将增长至15851亿元
  • BQ25896 I²C电池管理库详解:嵌入式充电控制实战指南
  • Linux 系统编程 - 文件IO
  • Stable-Diffusion-3.5在Keil5嵌入式开发环境中的应用
  • 2026年第一季度北京奔驰大G新车选购指南:专业车商深度测评与推荐 - 2026年企业推荐榜
  • XXL-Job调度中心Docker版升级踩坑记:从2.3.1到最新版,这些配置项你改对了吗?
  • 河北焊接设备优质服务商盘点:旭通商贸何以成为行业信赖之选? - 2026年企业推荐榜
  • 释放Android手机潜能:告别臃肿系统的智能清理方案