news 2026/4/15 11:11:20

海量数据高并发读写方案设计:从架构原理到实战策略

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
海量数据高并发读写方案设计:从架构原理到实战策略

一、引言:高并发读写问题分类与挑战

在大型互联网系统中,所有的业务操作最终都归结为读和写两种操作。不同业务场景对读写的要求各不相同,我们需要根据具体业务特点采取不同的优化策略。本章将从读写两个维度深入分析高并发问题的解决方案。

1.1 业务场景分类

根据读写特点的不同,大型系统可以分为三类:

1.1.1 侧重于"高并发读"的系统

场景1:搜索引擎

  • 读写对比

    • 用户规模:读端亿级用户,写端百万级发布者

    • 响应时间:读要求毫秒级,写允许分钟级

    • 频率:读频率远高于写频率

场景2:电商商品搜索

  • 类似搜索引擎,卖家发布商品,买家搜索商品

  • 读写特征与搜索引擎类似

场景3:商品描述、图片和价格

  • C端买家只读,B端卖家可修改

  • 读频率远高于写频率

1.1.2 侧重于"高并发写"的系统

场景:广告扣费系统

  • 每次浏览或点击都需扣减广告主余额

  • 要求实时扣费,避免平台流量损失

  • C端用户行为触发高频写操作

1.1.3 同时有"高并发读"和"高并发写"的系统

场景1:电商库存和秒杀系统

  • 用户同时进行高并发读(查看库存)和写(扣减库存)

  • 数据需实时更新,保证一致性

  • 12306火车票系统是更复杂版本

场景2:支付系统和微信红包

  • 用户实时查看余额(高并发读)

  • 转账扣款(高并发写)

  • 数据一致性要求极高

  • 红包系统涉及一人发多人抢,更复杂

场景3:IM、微博和朋友圈

  • 用户发送和接收消息

  • 发微博/朋友圈和查看内容

  • 读写两端都面临高并发压力

二、高并发读策略:多层次优化方案

2.1 策略1:加缓存/读副本

缓存是以空间换时间的经典策略,通过数据冗余提升读性能。

方案1:本地缓存与集中式缓存

缓存数据结构

  • <k, v>结构:对应数据库单行记录

  • <k, list>结构:列表数据

  • <k, hash>结构:哈希表数据

缓存更新策略

  1. 主动更新:数据库变更时主动删除/更新缓存

  2. 被动更新:查询时缓存过期则重新加载

缓存问题与解决方案

问题描述解决方案
缓存高可用缓存宕机导致数据库压力缓存集群、多级缓存
缓存穿透查询不存在的数据布隆过滤器、空值缓存
缓存击穿热点Key失效瞬间永不过期、互斥锁
缓存雪崩大量Key同时过期随机过期时间、预热

回源策略

  • 不回源:缓存没有直接返回空,需主动更新缓存

  • 回源:缓存没有则查询数据库,需处理缓存问题

方案2:MySQL主从复制

对于复杂业务查询,通过MySQL主从架构分担读压力:

  • Master处理写操作

  • 多个Slave处理读操作

  • 简单有效的读写分离方案

方案3:CDN/静态文件加速/动静分离

静态内容处理

  • 图片、HTML、JS、CSS等静态文件

  • 视频直播内容(内容相同)

  • 使用CDN全网缓存,就近访问

动态内容处理

  • 根据用户信息实时生成

  • 需应用服务器实时计算

技术本质:Redis、MySQL Slave、CDN都是"加副本"策略的变体。

2.2 策略2:并发读

将串行操作改为并行,提升读性能。

方案1:异步RPC

同步调用T = T1 + T2 + T3
异步调用T = Max(T1, T2, T3)

前提条件:多个调用间无依赖关系,可并行执行。

方案2:冗余请求(对冲请求)

问题背景

  • 分布式系统中单节点延迟率低(如1%)

  • 但请求涉及节点多时,整体延迟率高

  • 100个节点,每节点99%成功率,整体成功率:99%¹⁰⁰ ≈ 36.6%

  • 整体延迟率:1 - 36.6% = 63.4%

解决方案

  1. 同时发送多个相同请求,使用最快返回的结果

  2. 对冲请求

    • 先发一个请求

    • 等待内部服务95%请求的响应时间

    • 未收到响应则发送第二个请求

    • 使用最先返回的结果

Google测试数据

  • 仅用2%额外请求

  • 将99.9%请求响应时间从1800ms降低到74ms

2.3 策略3:重写轻读

将计算逻辑从读端转移到写端,读时直接获取预处理结果。

方案1:微博Feeds流实现

原始方案问题

  • 关注关系表和微博发布表分开

  • 查询Feeds流需要两条SQL和聚合操作

  • 无法满足高并发查询

重写轻读方案

  1. 发件箱:用户发布的微博

  2. 收件箱:粉丝接收的微博列表

  3. 写扩散:发布微博后,异步推送到所有粉丝收件箱

  4. 读优化:用户直接读取自己的收件箱,无需实时聚合

关键技术挑战

  1. 收件箱实现:使用Redis的<key, list>结构

  2. 容量限制:最多保存2000条(Twitter限制800条)

  3. 历史数据存储:MySQL分片存储

  4. 分页查询:需要二级索引定位数据位置

推拉结合策略

  • :粉丝数<5000的用户,发布时推送给所有粉丝

  • :粉丝数>5000的用户,只推送给在线粉丝

  • 聚合:读时聚合推送和拉取的数据

方案2:宽表与搜索引擎

多表关联查询问题

  • 分库后无法使用原生join

  • 程序聚合无法支持排序和分页

  • 数据量大时内存计算不可行

解决方案

  1. 宽表:提前计算关联结果,定时或触发更新

  2. 搜索引擎:将join结果做成文档存入ES,支持灵活查询

2.4 总结:读写分离(CQRS架构)

核心特征

  1. 数据结构分离:为读和写设计不同的数据模型

  2. 压力分担:写端通过分库分表应对压力,读端通过缓存/宽表/ES应对压力

  3. 数据同步:定时任务、消息中间件、Binlog监听

  4. 一致性模型:最终一致性,读比写有延迟

业务容忍度

  • 微博:粉丝延迟几秒看到可以接受

  • 库存:读有延迟,但下单时实时扣减库存

  • 账户余额:自己写自己读需要强一致性

三、高并发写方案:提升写入性能的策略

3.1 策略1:数据分片

通过数据拆分实现并行处理。

应用场景

  1. 数据库分库分表:应对高并发写压力

  2. Redis Cluster:分布式存储

  3. ES分布式索引:将大索引拆分为多个小索引并行查询

3.2 策略2:异步化

将同步操作改为异步,提升系统吞吐量。

案例1:短信验证码注册/登录

同步问题

  • 调用第三方短信平台需1-2秒

  • Tomcat线程被阻塞,并发能力有限

异步方案

  1. 请求放入消息队列,立即返回

  2. 后台消费者调用短信平台

  3. 内网通信,不受外网延迟影响

案例2:电商订单拆单

处理流程

  1. 创建订单并支付

  2. 支付成功立即返回

  3. 后台异步拆单(1个订单拆为多个子订单)

  4. 卖家分别发货

案例3:广告计费系统

异步处理流程

  1. 点击请求以日志形式落盘

  2. 立即返回客户端

  3. 流式计算处理后续逻辑

  4. 异步扣费,避免数据库压力

案例4:写内存+Write-Ahead日志

应用场景:高并发扣减库存或余额

实现方案

  1. 在Redis中扣减

  2. 同时写入WAL日志(消息队列或数据库)

  3. Redis宕机后重放日志恢复

  4. 数据库初始化Redis数据

3.3 策略3:批量写

将多次写操作合并为一次,减少I/O次数。

案例1:广告计费系统合并扣费

原始方案:10次点击扣10次钱
批量方案:10次点击合并为1次扣10元

实现方式

  1. 从消息队列批量获取消息

  2. 按广告主ID分组

  3. 累加扣费金额

  4. 一次数据库操作完成扣费

案例2:MySQL小事务合并

数据库优化

  • 10次扣1个库存 → 1次扣10个库存

  • 10个事务合并为1个事务

应用实例:Canal同步代码中的缓存更新

java

// 一个表在一次周期内多次修改,只需处理一次缓存 Set<String> factKeys = new HashSet<>(); for(CanalEntry.Entry entry : message.getEntries()) { // 提取表名 String tableName = entry.getHeader().getTableName(); factKeys.add(tableMapKey.get(tableName)); } // 批量删除缓存 for(String key : factKeys) { if(StringUtils.isNotEmpty(key)) redisOpsExtUtil.delete(key); }

多机房数据同步:事务合并加速数据库复制。

四、实战总结与架构演进

4.1 读写分离架构演进路径

阶段读写策略适用场景
初级阶段缓存(读写同一数据结构)简单查询加速
中级阶段读写分离(不同数据结构)复杂业务场景
高级阶段CQRS架构(完全分离)高并发读写场景

4.2 技术选型建议

  1. 缓存选型

    • 本地缓存:Caffeine、Guava Cache

    • 分布式缓存:Redis、Memcached

    • CDN:静态资源加速

  2. 数据库选型

    • OLTP:MySQL(分库分表)、PostgreSQL

    • OLAP:ClickHouse、HBase

    • 搜索:Elasticsearch、Solr

  3. 消息队列

    • 高吞吐:Kafka、RocketMQ

    • 低延迟:RabbitMQ、Pulsar

4.3 监控与调优

关键监控指标

  1. 缓存:命中率、响应时间、内存使用率

  2. 数据库:QPS、连接数、慢查询

  3. 消息队列:积压量、消费延迟

  4. 系统整体:吞吐量、错误率、响应时间

调优策略

  1. 容量规划:根据业务峰值预留30%余量

  2. 弹性伸缩:基于监控指标自动扩缩容

  3. 故障演练:定期测试降级和熔断策略

  4. 性能测试:定期压测,发现瓶颈点

五、未来发展趋势

5.1 智能化调优

  • 基于机器学习的自动参数调优

  • 智能缓存预热和淘汰策略

  • 自适应流量调度

5.2 云原生架构

  • 容器化部署和弹性伸缩

  • Serverless无服务器架构

  • 多云和混合云部署

5.3 数据湖与实时数仓

  • 批流一体数据处理

  • 实时数据分析和决策

  • 数据湖与业务系统深度融合

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/8 18:14:17

报错解决 OSError: sndfile library not found

解决linux系统下 import soundfile 报错 OSError: sndfile library not found 虚拟环境中包的版本&#xff1a; python3.8.20 soundfile0.10.3.post1 librosa0.8.1 报错&#xff1a; 报错原因&#xff1a;查看soundfile官网手册&#xff0c;发现缺少 libsndfile 安装命令&a…

作者头像 李华
网站建设 2026/4/5 20:55:00

设计心得—单次调用的控制

一、单次调用 开发者很容易混淆单次调用和单实例两种机制&#xff0c;可能觉得二者没有区别。在前面的分析中&#xff0c;对单实例也就是唯一对象的处理进行过实现分析&#xff0c;而且其中的实施也使用了单次调用的方法。单次调用不仅可以用在生成单实例上&#xff0c;也可以用…

作者头像 李华
网站建设 2026/3/29 4:09:09

【小程序毕设全套源码+文档】基于Android的环境保护生活App的设计与实现(丰富项目+远程调试+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/4/10 16:52:43

探索TMS320F28034数字控制LLC谐振开关电源开发板

TMS320F28034数字控制LLC谐振开关电源开发板学习板资料&#xff08;原理图源码&#xff09; CSS02404是基于德州仪器的TMS320F28034PNT设计的数字控制LLC电源模块开发板套件&#xff0c;适合数字控制LLC的入门与提高学习&#xff0c;并提供可靠的LLC设计参考。 开发板原边为传统…

作者头像 李华
网站建设 2026/4/8 10:31:30

用 Unity 从 0 做一个「可以玩的」游戏,需要哪些步骤和流程

很多人学 Unity 学到一半就卡住&#xff1a; 会 API、会拖组件&#xff0c;但就是做不出一个“完整的游戏”。问题通常不在技术点&#xff0c;而在缺少完整的开发流程意识。本文梳理用 Unity 从 0 到 1 做出一个**真正“可以玩的游戏”**所需要的步骤与方法。一、什么叫“可以玩…

作者头像 李华
网站建设 2026/4/4 7:38:23

基于深度学习YOLOv11的风力叶片缺陷识别检测系统(YOLOv11+YOLO数据集+UI界面+登录注册界面+Python项目源码+模型)

一、项目介绍 随着风力发电的快速发展&#xff0c;风力叶片作为核心部件&#xff0c;其表面缺陷的检测对保障机组安全运行至关重要。传统人工检测方法效率低且易受主观因素影响&#xff0c;而基于深度学习的智能检测技术能够显著提升缺陷识别的准确性和效率。本文提出了一种基…

作者头像 李华