redis-如何处理热key问题

2022/2/5 19:15:15

本文主要是介绍redis-如何处理热key问题,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

文章目录

  • 什么是热key
  • 热key导致的问题
  • 如何解决?
    • 如何解决流量过大?
    • 如何解决请求都打到同一个实例上

什么是热key

redis中的某个key访问量过大

热key导致的问题

某个 Key 的数据一定是存储到后端某台服务器的 Redis 单个实例上(只说主实例),如果对这个 Key 突然出现大量的请求操作,会导致流量过大,导致到达这个redis实例的上限,即CPU到达100%,或者是网卡流量达到上限等,进而影响这个key以及这个redis实例上的其他key的请求,严重可能导致实例宕机。即出现超时等情况,影响服务稳定性、可靠性等。如果redis实例挂了,可能导致其他问题,如果redis作为缓存使用,redis实例挂了,可能导致大量请求到数据库上,导致数据库雪崩,拒绝服务等。

如何解决?

先分析原因

  1. 流量过大
  2. 请求都打到同一个实例上
    那么问题确定了,接下来就说明一下如何解决

如何解决流量过大?

核心就是把流量兜在上游。即加缓存,不命中缓存的才到redis下游。可以在上游加本地缓存。这个上游可能是请求的服务本身或者proxy层

如何解决请求都打到同一个实例上

  1. 将key打散,即一个key变成多个key,下面大致写一下
//生成随机数
random := GenRandom(0, M) // M一般为redis实例数量的倍数
//构造备份新 Key
bakHotKey := hotKey + "{" + random + "}" // 不同框架将key打到某redis实例的命名方式不同
data := redis.GET(bakHotKey)
if data == nil {
	data = redis.GET(hotKey)
	if data == NULL {
		data = GetFromDB()
		// 可以利用原子锁来写入数据保证数据一致性
		redis.SET(hotKey, data, expireTime)
		redis.SET(bakHotKey, data, expireTime + GenRandom(0, 5)) // 防止同时过期
	} else {
		redis.SET(bakHotKey, data, expireTime + GenRandom(0, 5))
	}
}
return data
  1. 扩从,注意redis是用gossip协议同步的,从实例不能太多


这篇关于redis-如何处理热key问题的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程