目前是用 golang 开发的一个系统,有个需求是用户进来了, 1 分钟内不再发送进房提醒 我就把用户 id 以及上次发送进房提醒的时间,存在一个 map[string]int 里面,然后用锁,来防止并发读写出错,后续跑个 go routinue ,在 1 分钟时间到达后,销毁存的值
leader review 了代码下,跟我说,要避免用锁用 redis 的 expire 会比较合适,
这个有点疑惑,在 golang 中用 map ,然后高并发,会比用 redis 慢吗,毕竟用 redis 要维护一个连接,然后 redis 里面也需要锁吧?尤其是redis需要跨进程通信。
1
yanchao7511461 2016-09-14 09:05:48 +08:00 1
redis 是单线程的,不需要锁, redis 的 expire 其实很多时候就用来做锁的事情了。所以我觉得是可以的。但跨进程通信的代价还是要考虑下, IO 的确不是个省油的灯
|
2
heww 2016-09-14 09:07:03 +08:00 via iPhone 1
你的系统会多实际部署吗?会的话, map 怎么在进程间通信?
|
3
heww 2016-09-14 09:09:21 +08:00 via iPhone
s/实际 /实例 /g
|
5
ipconfiger 2016-09-14 09:20:29 +08:00
卤煮其实不光要考虑高并发, 还需要考虑到分布式部署的问题, 如果你在进程内用锁搞定了, 那么多个进程跑的时候怎么办? 多台主机跑呢? 最后还是要归结到要用 io 来解决问题的思路上, 最后大多数人都用回了 redis, 或者你自己写一个分布式锁服务, 那不又绕回来了, DIY 啊亲, 有现成的干嘛自己撸啊, 有这个美国时间干点什么不好, 除非你觉得自己能撸得比 redis 更加优秀
|
6
ryd994 2016-09-14 09:30:43 +08:00 via Android
其实我觉得更重要的是,你还要记住 1 分钟后销毁,不销毁又会浪费内存
用 Redis 的话你就不用再记着这件事了, Redis 到时间一定会给你清掉(有时会有少许延迟,所以还是要保存时间值,自己再做比较。不过看你的需求,时间略微长一点应该也没啥 |
7
ryd994 2016-09-14 09:31:37 +08:00 via Android
更重要,如果爆了个 exception ,你是不是还要记得擦屁股?
少一个屁股少一个烦……… |
8
hanwujibaby 2016-09-14 09:48:58 +08:00 1
同一个用户重复进入有考虑吗?如果不是下次进入的时候不是同一个服务节点呢? golang 的 map 本身不是线程安全的。在高并发下如果不需要保证线程安全的话是可以保证效率的。
|
9
ruandao OP 嗯, 谢谢 @ryd994 @ipconfiger
|
10
9hills 2016-09-14 09:51:11 +08:00 via iPhone
5 楼正解
|
11
jy01264313 2016-09-14 10:15:08 +08:00
5 楼正解+1
楼主多大的并发,每次操作耗时多少? 最简单满足需求就好。 如果是一个 int 的加减,每秒 2 3 百万的操作都不用加锁,当然不是 100% 保险。 |
12
UnitTest 2016-09-14 10:44:02 +08:00
如果不是精确到毫秒级别, 肯定 redis 比自己写 map 来的方便.
|
13
reus 2016-09-14 17:53:43 +08:00 1
检查超时用一个全局的 timer wheel 做。保护 map 用 RWMutex ,开销才那几十 ns , TCP 通讯的开销比锁大多了好吗……
按 uid 分流到不同进程或者机器,就可以避免进程间同步 map 了。再说 go 用单机单进程足够了。 1 分钟内才有效的数据,也不用做持久化,完全没有用 redis 的必要,太重了。 不过看你 leader 的水平,还是用 redis 吧,免得实现出来他觉得 hold 不住又要你改。 用 go 做主力开发语言了,还用 redis ,只能有一个原因:能力不足。 |