使用go_concurrent_map 管理 并发更新缓存

在后台服务中,为了提速,我在内存还做了一个告诉缓存来管理用户信息,根据更新通知,或者定时去redis中同步信息,那么在加载或者更新某个用户元素时,要防止并发,

当:

1)如果内存缓存没有;

2)去数据库或者redis加载;

3)添加到内存缓存;

这里就有个并发重复的可能性;

所以,这里要做一个加锁的插入或者更新,使用go_concurrent_map就十分方便:

Go 复制代码
// https://github.com/robinfoxnan/go_concurrent_map
// 这里使用一个支持高并发的map来管理会话
type UserCache struct {
	//lock sync.Mutex

	userMap utils.ConcurrentMap[int64, *User]
}

// 如果没有,则从redis中查找,如果redis中没有,则从数据库中查找
func (uc *UserCache) GetUser(uid int64) (*User, bool) {

	user, err := uc.userMap.Get(uid)
	return user, err
}

// 更新时候的回调函数,如果未设置,则
func updateInsertUser(exist bool, oldUser *User, newUser *User) *User {
	if exist == false {
		return newUser
	} else {
		oldUser.MergeUser(newUser)
		return oldUser
	}
}

// 这里可能会有并发冲突,需要解决的就是session列表需要合并
func (uc *UserCache) SetOrUpdateUser(uid int64, user *User) {
	uc.userMap.Upsert(uid, user, updateInsertUser)
}

这个类在插入时候,可以检测是否存在,并通过回调函数来决定是插入还是更新;这个加锁已经放在插入函数中完成了;

详细代码请查看:GitHub - robinfoxnan/BirdTalkServer: An open source IM system

相关推荐
小希与阿树1 小时前
如何解决Redis中的热点key问题
数据库·redis·缓存
lindsayshuo7 小时前
为什么在二维卷积操作中,将宽度(W)维度放在高度(H)之前会破坏空间局部性原则,并影响缓存性能
缓存
代码代码快快显灵10 小时前
Redis 优化秒杀(异步秒杀)
数据库·redis·缓存
代码代码快快显灵12 小时前
Redis之秒杀活动
数据库·redis·缓存·秒杀活动
学是为了不学19 小时前
Eureka缓存机制
java·spring cloud·缓存
huaqianzkh1 天前
Redis的内存预分配策略
数据库·redis·缓存
有馬公生1 天前
有关Redis的相关概述
数据库·redis·缓存
瞳绣1 天前
【redis初阶】初识Redis
数据库·redis·缓存
轻口味2 天前
【每日学点鸿蒙知识】调试、网络、缓存、富文本编辑等
缓存·华为·harmonyos