百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

高并发技巧-redis热key问题处理技巧

mhr18 2024-12-07 21:52 21 浏览 0 评论

这篇文章我将介绍工作中处理热key问题的常用手段,可能介绍得不是很全,毕竟不同的业务场景可能有不同的解决方案,但是相信通过这部分的介绍能提供一个热key问题的思路。

热key问题,简单来说就是对某一资源的访问量过高问题,再简单一点来说就是对某个资源访问的qps过高,而解决访问量高的问题通常我们使用分布式缓存,最常见的就是redis,这个资源对应redis的一个key简称热key。热key在开发中是非常常见的,比如各种app的榜单,活动页面上的一些资源。

虽然redis号称单节点能扛住10Wqps,但是开发中肯定不能这样去估计,毕竟安全第一,比如5000似乎就可能就可以作为上限。如果超过5000该怎么处理呢?下面将提供几种常见的解决方案。

冗余写/随机读

假设在做活动,活动总金额为amount,用户每次完成任务会得到一笔奖金,每天结算一次,在页面会展示剩余金额restAmount。我们将剩余金额存到redis中,{key: pool, value: restAmount}

由于每天统一结算,所以的qps不会很高,毕竟我们能自己控制流量,比如用户完成后发个延迟结算消息到mq,然后由消费者来处理计算剩余金额最后更新到redis中。

但是在页面的的qps是很高的。显然奖池pool就是个热key。

既然单节点扛不住,那么显然可以将数据写到N个节点上,也就是将奖池存到多个节点,在页面读取的时候随机选一个节点去读。假如有10W的qps,N=10,那么每个节点的流量就成了1W的qps。

大key问题与分shard处理

上门介绍的奖池问题显然不是大key问题,工作中常见的大key问题通常涉及到批量用户存储在set或者map中。举个不恰当的例子(之所以说不恰当是因为大量数据判存完全可以使用布隆过滤器)。假如同时存在若干个活动,对于每个活动,如果用户完成了,需要记录下用户完成情况,在后续页面进行对应的完成情况展示。这里可以使用map来处理,{key:activityId, value:{field:userId, value:完成情况}}

那么这显然是一个大key问题,同时也是个热点问题。但是用上面介绍的办法能解决热key问题,解决不了大key问题。

解决这个问题其实也可以采用分而治之的思路,就是将大key拆分为若干小key,并且尽量让若干小key存在不同的redis节点中。

比如对于一个活动id我可以分为10个shard,{shard_1,...,shard_10},使用userId%10得到归属的shard。

这样每次判断取出用户完成情况,就先找到对应活动的shard然后拿出该用户即可。如果要拿出活动下的所有用户来做榜单,则只需要将所有shard都拿出来排序即可;

由于不同的shard在不同的redis节点,这样就又解决了热点问题。

本地缓存

如果条件允许的话,也就是本地缓存够用,或者说数据量不是很大,同时能够接受一定的延迟的话,那么可以直接使用本地缓存。这里就以guava的LoadingCache为例。

以奖池的例子来说,数据量小的忽略不计,因为结算时同一结算并更新奖池,也就是说一天中23个多小时数据都不会变,变动的时间也很短,所以我们可以接受一定的延迟,只要记得讲本地缓存过期时间设置短一点,比如10分钟。

此外需要有个地方供过期后的本地缓存读取,可以使用db或者redis,这样每次更新数据的时候就得更新db或者redis。为了防止击穿,记得使用load-miss方法。

LoadingCache<String, String> cache = CacheBuilder.newBuilder()
                .maximumSize(1000L)
                .expireAfterAccess(Duration.ofSeconds(600L))
                .expireAfterWrite(Duration.ofSeconds(600L))
                .build(new CacheLoader<String, String>() {
                    @Override
                    public String load(String key) throws Exception {
                        // load from db
                    }
                });
String restAmount = cache.get("pool");
复制代码

使用Memcached

这在公司基础架构用得会更多一点,为什么可以使用memcached,看下面两段话的介绍就知道了.

  1. Redis是单线程请求,所有命令串行执行,并发情况下不需要考虑数据一致性问题;性能受限于CPU,单实例QPS在4-6w。Memcached是多线程,可以利用多核优势,单实例在正常情况下,可以达到写入60-80w qps,读80-100w qps。
  2. Redis的big key与热key类操作,如果qps较高则容易造成redis阻塞,影响整体请求。Memcached因为是多线程,与redis相比,在big key与热key类操作上支持较好。


作者:可以回家加班吗
链接:https://juejin.cn/post/7159809554674122759
来源:稀土掘金

相关推荐

Spring Boot3 连接 Redis 竟有这么多实用方式

各位互联网大厂的后端开发精英们,在日常开发中,想必大家都面临过系统性能优化的挑战。当系统数据量逐渐增大、并发请求不断增多时,如何提升系统的响应速度和稳定性,成为了我们必须攻克的难题。而Redis,这...

隧道 ssh -L 命令总结 和 windows端口转发配置

摘要:隧道ssh-L命令总结和windows端口转发配置关键词:隧道、ssh-L、端口转发、网络映射整体说明最近在项目中,因为内网的安全密级比较高,只能有一台机器连接内网数据库,推送...

火爆BOOS直聘的13个大厂Java社招面经(5年经验)助你狂拿offer

火爆BOOS直聘的13个大厂Java社招面经(5年经验)助你狂拿offer综上所述,面试遇到的所有问题,整理成了一份文档,希望大家能够喜欢!!Java面试题分享(Java中高级核心知识全面解析)一、J...

「第五期」游服务器一二三面 秋招 米哈游

一面下午2点,35分钟golang内存模型golang并发模型golanggc原理过程channel用途,原理redis数据结构,底层实现跳跃表查询插入复杂度进程,线程,协程kill原理除了kil...

RMQ——支持合并和优先级的消息队列

业务背景在一个项目中需要实现一个功能,商品价格发生变化时将商品价格打印在商品主图上面,那么需要在价格发生变动的时候触发合成一张带价格的图片,每一次触发合图时计算价格都是获取当前最新的价格。上游价格变化...

Redis 中的 zset 为什么要用跳跃表,而不是B+ Tree 呢?

Redis中的有序集合使用的是一种叫做跳跃表(SkipList)的数据结构来实现,而不是使用B+Tree。本文将介绍为什么Redis中使用跳跃表来实现有序集合,而不是B+Tree,并且探讨跳跃表...

一文让你彻底搞懂 WebSocket 的原理

作者:木木匠转发链接:https://juejin.im/post/5c693a4f51882561fb1db0ff一、概述上一篇文章《图文深入http三次握手核心问题【思维导图】》我们分析了简单的一...

Redis与Java整合的最佳实践

Redis与Java整合的最佳实践在这个数字化时代,数据处理速度决定了企业的竞争力。Redis作为一款高性能的内存数据库,以其卓越的速度和丰富的数据结构,成为Java开发者的重要伙伴。本文将带你深入了...

Docker与Redis:轻松部署和管理你的Redis实例

在高速发展的云计算时代,应用程序的部署和管理变得越来越复杂。面对各种操作系统、依赖库和环境差异,开发者常常陷入“在我机器上能跑”的泥潭。然而,容器化技术的兴起,尤其是Docker的普及,彻底改变了这一...

Java开发中的缓存策略:让程序飞得更快

Java开发中的缓存策略:让程序飞得更快缓存是什么?首先,让我们来聊聊什么是缓存。简单来说,缓存是一种存储机制,它将数据保存在更快速的存储介质中,以便后续使用时能够更快地访问。比如,当你打开一个网页时...

国庆临近,字节后端开发3+4面,终于拿到秋招第一个offer

字节跳动,先面了data部门,3面技术面之后hr说需要实习转正,拒绝,之后另一个部门捞起,四面技术面,已oc分享面经,希望对大家有所帮助,秋招顺利在文末分享了我为金九银十准备的备战资源库,包含了源码笔...

“快”就一个字!Redis凭什么能让你的APP快到飞起?

咱们今天就来聊一个字——“快”!在这个信息爆炸、耐心越来越稀缺的时代,谁不希望自己手机里的APP点一下“嗖”就打开,刷一下“唰”就更新?谁要是敢让咱用户盯着个小圈圈干等,那简直就是在“劝退”!而说到让...

双十一秒杀,为何总能抢到?Redis功不可没!

一年一度的双十一“剁手节”,那场面,简直比春运抢票还刺激!零点的钟声一敲响,亿万个手指头在屏幕上疯狂戳戳戳,眼睛瞪得像铜铃,就为了抢到那个心心念念的半价商品、限量版宝贝。你有没有发现一个奇怪的现象?明...

后端开发必看!为什么说Redis是天然的幂等性?

你在做后端开发的时候,有没有遇到过这样的困扰:高并发场景下,同一个操作重复执行多次,导致数据混乱、业务逻辑出错?别担心,很多同行都踩过这个坑。某电商平台就曾因订单创建接口在高并发时不具备幂等性,用户多...

开发一个app需要哪些技术和工具

APP开发需要一系列技术和工具的支持,以下是对这些技术的清晰归纳和分点表示:一、前端开发技术HTML用于构建页面结构。CSS用于样式设计和布局。JavaScript用于页面交互和逻辑处理。React...

取消回复欢迎 发表评论: