ai又教会我一个算法:双重redis检测
程序在处理请求读取非实时数据时,通常会先从 Redis 缓存中获取数据。如果缓存失效或过期,程序会转而从数据库读取最新数据,然后将结果写回 Redis。听起来没问题,对吧?确实,这是标准的缓存更新流程,我最初也没觉得有什么不对。
但问题来了:在高并发场景下,事情就没那么简单了。假设缓存恰好失效,从缓存过期到新数据写入 Redis 的这段时间,哪怕只有几十毫秒就可能有无数个请求同时涌入。这些请求发现缓存没了,都会去查数据库、更新 Redis,轻则系统负荷升高,重则引起缓存混乱系统失效。我脑子不好使没转过弯,想不出啥好办法解决。后来一问ai,才发现,哎,这早就是个成熟的算法了,简单又巧妙,赶紧写下来备忘!
var dupMu sync.Mutex //互斥锁,用来锁定缓存失效请求
func heavyLoadFunc() {
err:=LoadFromRds(keyname, param, &list) //读redis
if err==nil && list!=nil { //缓存命中直接返回数据
....
return list
}
dupMu.Lock() //双重缓存锁。缓存未命中,锁定,只允许一个个排队进入
defer dupMu.Unlock()
err:=LoadFromRds(keyname, param, &list) //第二次读取redis。即,排队的未命中请求,第一个请求会缓存再次失败进入数据库更新redis数据,但在第一个完成后,其余请求即可从redis获得数据,防止再次更新。太巧妙和简单了。
if err==nil && list!=nil {
....
return list
}
list,err=getDataFromDb() //从数据库更新
return list
}