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

《去哪儿网Redis高并发实战:从问题定位到架构升级》

去哪儿网Redis高并发实战:从问题定位到架构升级

在互联网行业竞争日益激烈的当下,高并发场景下的系统性能优化一直是技术团队面临的重要挑战。对于去哪儿网这类在线旅游平台来说,节假日期间的流量高峰更是对系统架构的严峻考验。本文将深入剖析去哪儿网在五一假期期间,针对Redis高并发问题的实战解决方案,从问题定位、优化策略到架构升级,全方位展现整个优化过程。

一、案例背景:五一假期流量峰值挑战

1.1 业务场景

去哪儿网作为国内领先的在线旅游平台,提供机票预订、酒店预订、旅游攻略等多种服务。在五一假期这样的旅游旺季,平台的业务流量呈现爆发式增长。其中,机票搜索、酒店推荐等核心接口的日请求量突破5亿大关,支撑这些业务的Redis集群QPS(每秒查询率)更是达到了惊人的80万。如此庞大的访问量,对Redis集群的性能和稳定性提出了极高的要求。

在机票搜索业务中,用户频繁查询航线价格日历,这使得与价格日历相关的Redis key访问量极为集中;酒店推荐接口则需要快速获取酒店的各类信息,同样依赖Redis缓存来提升响应速度。Redis作为内存数据库,凭借其高性能、高并发的特点,成为了去哪儿网缓存数据的首选方案,但在极端流量下,也暴露出了一系列问题。

1.2 核心问题

随着流量的持续攀升,Redis集群出现了严重的性能瓶颈。首先,热点航线价格日历key的访问过于集中,导致承载这些key的单节点CPU使用率飙升至90%。过高的CPU负载使得该节点处理请求的能力大幅下降,不仅影响了自身的响应速度,还可能导致整个集群的性能波动。

其次,缓存雪崩问题给系统带来了巨大压力。由于大量缓存数据同时过期,瞬间产生的大量请求无法从Redis获取数据,只能回源到数据库(DB)。DB回源QPS超过4000,远超其正常承载能力,接口响应时间也从正常的几十毫秒延长至500ms以上,用户体验急剧下降。如果不及时解决这些问题,可能会导致用户流失,对业务造成严重影响。

二、问题定位与分析

2.1 热点key识别

为了找出导致单节点CPU过高的原因,技术团队首先进行了热点key的识别。通过使用redis-cli --bigkeys命令,对Redis集群中的key进行扫描分析。该命令能够快速找出占用内存较大的key以及访问频率较高的key。

经过扫描发现,像flight:price:calendar:CN-SHA这样与热点航线价格日历相关的key,其访问占比超过了30%。这些热点key的集中访问,使得负责存储它们的Redis节点负载过重,成为了系统性能的瓶颈。

2.2 慢查询分析

除了热点key问题,慢查询也是影响Redis性能的重要因素。去哪儿网技术团队开启了Redis的慢查询日志功能,对执行时间较长的命令进行分析。分析结果显示,大量的HGETALL操作耗时超过10ms,而Redis是单线程模型,这些耗时较长的操作会阻塞其他请求的执行,导致整体响应速度变慢。

HGETALL命令用于获取哈希表中的所有字段和值,在实际业务中,可能并不需要一次性获取所有数据,这种过度的数据获取方式不仅浪费了资源,还降低了系统的并发处理能力。

三、优化策略与实施

3.1 热key多副本拆分

针对热点key访问集中的问题,去哪儿网采用了热key多副本拆分的策略。以flight:price:calendar:CN-SHA这个热点key为例,将其拆分为10个副本,分别命名为flight:price:calendar:CN-SHA:0flight:price:calendar:CN-SHA:9

在客户端访问时,通过hash(userId) % 10的方式,将用户请求随机分配到这10个副本上。这样一来,原本集中在一个节点上的流量就被分散到了10个节点,有效降低了单个节点的负载压力。通过这种方式,不仅提升了系统的并发处理能力,还增强了系统的稳定性。

客户端请求
计算hash userId % 10
访问flight:price:calendar:CN-SHA:0
访问flight:price:calendar:CN-SHA:1
访问flight:price:calendar:CN-SHA:2
访问flight:price:calendar:CN-SHA:3
访问flight:price:calendar:CN-SHA:4
访问flight:price:calendar:CN-SHA:5
访问flight:price:calendar:CN-SHA:6
访问flight:price:calendar:CN-SHA:7
访问flight:price:calendar:CN-SHA:8
访问flight:price:calendar:CN-SHA:9

3.2 逻辑过期+异步刷新

为了解决缓存雪崩问题,去哪儿网引入了逻辑过期+异步刷新的机制。在缓存数据结构中新增logical_expire_time字段,用于记录数据的逻辑过期时间,同时将物理TTL(生存时间)设置为24小时。

当系统检测到logical_expire_time < now时,并不会立即阻塞请求去更新数据,而是触发一个异步任务来刷新数据。在异步任务刷新数据的过程中,请求仍然可以获取到旧数据,这样就避免了大量请求同时回源到数据库,有效防止了缓存雪崩的发生。通过这种方式,保证了系统在缓存数据更新过程中的高可用性和稳定性。

请求访问缓存
logical_expire_time < now?
触发异步任务刷新数据
返回缓存数据
异步获取新数据
更新缓存数据

3.3 本地缓存前置

为了进一步减少对Redis的访问量,去哪儿网在客户端引入了本地缓存。选用Caffeine作为本地缓存框架,对热门航线数据进行缓存,设置TTL为10分钟。Caffeine具有高性能、低内存占用等特点,非常适合在客户端使用。

通过引入本地缓存,大量对热门航线数据的请求可以直接从本地缓存中获取,命中率达到了85%。这不仅减轻了Redis集群的压力,还显著提升了接口的响应速度,为用户提供了更好的使用体验。

客户端请求
本地缓存是否命中?
返回本地缓存数据
访问Redis
获取数据并更新本地缓存
返回数据

四、架构升级与监控完善

4.1 集群拆分

随着业务的不断发展,Redis集群中的资源竞争问题日益突出。为了解决这一问题,去哪儿网对Redis集群进行了拆分,按照业务维度将其拆分为机票、酒店、攻略3个Cluster集群。

通过集群拆分,不同业务的数据存储在不同的集群中,避免了资源的相互竞争。例如,机票业务的流量不会影响到酒店业务的性能,每个集群可以根据自身业务的特点进行针对性的优化和扩展。这种架构设计不仅提升了系统的性能,还增强了系统的可维护性和扩展性。

4.2 监控体系建设

为了及时发现和解决系统中出现的问题,去哪儿网构建了完善的监控体系,选用Prometheus作为监控工具。Prometheus能够实时采集和存储Redis集群的各项指标数据,并提供强大的查询和告警功能。

监控的关键指标包括QPS、命中率、慢查询数、内存使用率等。通过对这些指标的实时监控,技术团队可以及时了解Redis集群的运行状态。同时,设置了告警规则,当CPU使用率超过80%、命中率低于70%时,系统会自动触发告警,通知相关人员进行处理。这样一来,能够在问题发生的第一时间做出响应,保障系统的稳定运行。

4.3 大key治理

大key不仅会占用大量的内存空间,还会影响Redis的性能。去哪儿网制定了大key治理方案,定期对Redis中的大key进行扫描。对于像粉丝列表等数据量大的key,将其拆分为多个子key,确保每个key的大小不超过1MB。

通过大key治理,减少了内存碎片的产生,提高了内存的利用率,同时也降低了大key对系统性能的影响,进一步提升了Redis集群的整体性能。

五、优化效果对比

经过一系列的优化和架构升级,去哪儿网Redis集群的性能得到了显著提升。以下是优化前后各项指标的对比:

指标优化前优化后
单节点CPU峰值90%35%
缓存命中率68%96.5%
DB回源QPS4200380
接口响应时间320ms65ms

从数据可以看出,单节点CPU峰值从90%下降到35%,有效解决了热点key导致的CPU过高问题;缓存命中率从68%提升到96.5%,大幅减少了对数据库的访问;DB回源QPS从4200降至380,极大减轻了数据库的压力;接口响应时间从320ms缩短至65ms,显著提升了用户体验。

六、总结与展望

去哪儿网在Redis高并发实战中的优化经验,为其他面临类似问题的互联网企业提供了宝贵的参考。通过热点key多副本拆分、逻辑过期+异步刷新、本地缓存前置等优化策略,以及集群拆分、监控体系建设、大key治理等架构升级措施,成功解决了五一假期流量峰值下的性能瓶颈问题。

未来,随着业务的持续增长和用户需求的不断变化,去哪儿网将继续关注Redis技术的发展,探索更多优化方案和架构创新,进一步提升系统的性能和稳定性,为用户提供更加优质的服务。同时,也会将这些实践经验应用到更多的业务场景中,推动整个技术团队的能力提升。

http://www.lryc.cn/news/574336.html

相关文章:

  • 边缘-云协同智能视觉系统:实时计算与云端智能的融合架构
  • C++的前世今生-C++11
  • 《哈希表》K倍区间(解题报告)
  • go channel用法
  • 【android bluetooth 框架分析 04】【bt-framework 层详解 8】【DeviceProperties介绍】
  • Netty内存池分层设计架构
  • 【大厂机试题解法笔记】高效货运
  • 互联网大数据求职面试:从Zookeeper到Flink的技术探讨
  • 跨越十年的C++演进:C++11新特性全解析
  • TCP客户端发送消息失败(NetAssist做客户端)
  • 【C++】第十二节——详解list(上)—(list的介绍和使用、模拟实现)
  • Origin绘制三Y轴柱状图、点线图、柱状点线图
  • el-cascader 设置可以手动输入也可以下拉选择
  • 原生微信小程序网络请求与上传接口封装实战指南
  • 【DeepSeek实战】2、DeepSeek特训:Function Calling与ReAct双引擎驱动大模型智能升级实战指南
  • 《高等数学》(同济大学·第7版)第六章 定积分的应用 第一节定积分的元素法
  • matlab实现大地电磁二维正演
  • 音视频全链路开发实践:基于SmartMediakit的架构设计与应用实战
  • Recent Advances in Speech Language Models: A Survey
  • 通信网络编程3.0——JAVA
  • 【信创-k8s】银河麒麟V10国防版+鲲鹏/飞腾(arm64架构)在线/离线部署k8s1.30+kubesphere
  • fiddler+安卓模拟器,解决无网络、抓不到https问题
  • 网络安全之某cms的漏洞分析
  • 阿里云Elasticsearch生产环境误删数据恢复指南
  • 将RESP.app的备份数据转码成AnotherRedisDesktopManager的格式
  • 越南数学家吴宝珠恶搞式证明朗兰兹纲领
  • 基于SpringBoot + Vue 的网上拍卖系统
  • ESXi 8 相较于 ESXi 7 升级
  • 【C++】哈希表的实现(链地址法)
  • Linux切换中文输入法