Golang Go语言中高并发情况下,用锁还是用redis会比较合适?

目前是用 golang 开发的一个系统,有个需求是用户进来了, 1 分钟内不再发送进房提醒 我就把用户 id 以及上次发送进房提醒的时间,存在一个 map[string]int 里面,然后用锁,来防止并发读写出错,后续跑个 go routinue ,在 1 分钟时间到达后,销毁存的值

leader review 了代码下,跟我说,要避免用锁用 redis 的 expire 会比较合适,

这个有点疑惑,在 golang 中用 map ,然后高并发,会比用 redis 慢吗,毕竟用 redis 要维护一个连接,然后 redis 里面也需要锁吧?尤其是redis需要跨进程通信。


Golang Go语言中高并发情况下,用锁还是用redis会比较合适?
14 回复

redis 是单线程的,不需要锁, redis 的 expire 其实很多时候就用来做锁的事情了。所以我觉得是可以的。但跨进程通信的代价还是要考虑下, IO 的确不是个省油的灯

更多关于Golang Go语言中高并发情况下,用锁还是用redis会比较合适?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你的系统会多实际部署吗?会的话, map 怎么在进程间通信?

s/实际 /实例 /g

会多实例部署,但是是长连接,同一个用户近连接同一个实例

卤煮其实不光要考虑高并发, 还需要考虑到分布式部署的问题, 如果你在进程内用锁搞定了, 那么多个进程跑的时候怎么办? 多台主机跑呢? 最后还是要归结到要用 io 来解决问题的思路上, 最后大多数人都用回了 redis, 或者你自己写一个分布式锁服务, 那不又绕回来了, DIY 啊亲, 有现成的干嘛自己撸啊, 有这个美国时间干点什么不好, 除非你觉得自己能撸得比 redis 更加优秀

其实我觉得更重要的是,你还要记住 1 分钟后销毁,不销毁又会浪费内存
用 Redis 的话你就不用再记着这件事了, Redis 到时间一定会给你清掉(有时会有少许延迟,所以还是要保存时间值,自己再做比较。不过看你的需求,时间略微长一点应该也没啥

更重要,如果爆了个 exception ,你是不是还要记得擦屁股?
少一个屁股少一个烦………

同一个用户重复进入有考虑吗?如果不是下次进入的时候不是同一个服务节点呢? golang 的 map 本身不是线程安全的。在高并发下如果不需要保证线程安全的话是可以保证效率的。

嗯, 谢谢

5 楼正解

5 楼正解+1
楼主多大的并发,每次操作耗时多少?
最简单满足需求就好。
如果是一个 int 的加减,每秒 2 3 百万的操作都不用加锁,当然不是 100% 保险。

如果不是精确到毫秒级别, 肯定 redis 比自己写 map 来的方便.

检查超时用一个全局的 timer wheel 做。保护 map 用 RWMutex ,开销才那几十 ns , TCP 通讯的开销比锁大多了好吗……
按 uid 分流到不同进程或者机器,就可以避免进程间同步 map 了。再说 go 用单机单进程足够了。
1 分钟内才有效的数据,也不用做持久化,完全没有用 redis 的必要,太重了。

不过看你 leader 的水平,还是用 redis 吧,免得实现出来他觉得 hold 不住又要你改。
用 go 做主力开发语言了,还用 redis ,只能有一个原因:能力不足。

在Golang的高并发场景下,选择使用锁还是Redis,取决于具体的应用场景和需求。

锁是Golang中常见的并发控制方法,包括互斥锁(mutex)、读写锁(RWMutex)等,它们能够确保同一时刻只有一个goroutine访问被锁定的资源,从而避免数据竞争。在高并发读写共享资源时,锁可以提供有效的并发控制。

Redis则是一个高效的内存数据结构存储系统,支持多种数据结构,并提供了丰富的操作命令。在高并发场景下,Redis可以用作缓存数据库,加快数据读取速度,提高系统响应速度。此外,Redis还支持原子操作,可以用来实现分布式锁,保证数据一致性。

如果应用场景主要是保护共享资源的并发访问,且数据规模较小,使用锁可能更为简单直接。而如果需要处理大量数据,且对性能要求较高,Redis则是一个更好的选择。Redis的缓存机制和原子操作能够显著提升系统性能,同时保证数据一致性。

综上所述,在高并发场景下,选择锁还是Redis需要根据具体的应用场景和需求来决定。

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!