V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
ruandao
V2EX  ›  Go 编程语言

咨询下,高并发情况下,用锁还是用 redis 会比较合适?

  •  
  •   ruandao · 2016-09-14 09:00:41 +08:00 · 1994 次点击
    这是一个创建于 3003 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    13 条回复    2016-09-14 17:53:43 +08:00
    yanchao7511461
        1
    yanchao7511461  
       2016-09-14 09:05:48 +08:00   ❤️ 1
    redis 是单线程的,不需要锁, redis 的 expire 其实很多时候就用来做锁的事情了。所以我觉得是可以的。但跨进程通信的代价还是要考虑下, IO 的确不是个省油的灯
    heww
        2
    heww  
       2016-09-14 09:07:03 +08:00 via iPhone   ❤️ 1
    你的系统会多实际部署吗?会的话, map 怎么在进程间通信?
    heww
        3
    heww  
       2016-09-14 09:09:21 +08:00 via iPhone
    s/实际 /实例 /g
    ruandao
        4
    ruandao  
    OP
       2016-09-14 09:12:15 +08:00
    @heww 会多实例部署,但是是长连接,同一个用户近连接同一个实例
    ipconfiger
        5
    ipconfiger  
       2016-09-14 09:20:29 +08:00
    卤煮其实不光要考虑高并发, 还需要考虑到分布式部署的问题, 如果你在进程内用锁搞定了, 那么多个进程跑的时候怎么办? 多台主机跑呢? 最后还是要归结到要用 io 来解决问题的思路上, 最后大多数人都用回了 redis, 或者你自己写一个分布式锁服务, 那不又绕回来了, DIY 啊亲, 有现成的干嘛自己撸啊, 有这个美国时间干点什么不好, 除非你觉得自己能撸得比 redis 更加优秀
    ryd994
        6
    ryd994  
       2016-09-14 09:30:43 +08:00 via Android
    其实我觉得更重要的是,你还要记住 1 分钟后销毁,不销毁又会浪费内存
    用 Redis 的话你就不用再记着这件事了, Redis 到时间一定会给你清掉(有时会有少许延迟,所以还是要保存时间值,自己再做比较。不过看你的需求,时间略微长一点应该也没啥
    ryd994
        7
    ryd994  
       2016-09-14 09:31:37 +08:00 via Android
    更重要,如果爆了个 exception ,你是不是还要记得擦屁股?
    少一个屁股少一个烦………
    hanwujibaby
        8
    hanwujibaby  
       2016-09-14 09:48:58 +08:00   ❤️ 1
    同一个用户重复进入有考虑吗?如果不是下次进入的时候不是同一个服务节点呢? golang 的 map 本身不是线程安全的。在高并发下如果不需要保证线程安全的话是可以保证效率的。
    ruandao
        9
    ruandao  
    OP
       2016-09-14 09:49:49 +08:00
    嗯, 谢谢 @ryd994 @ipconfiger
    9hills
        10
    9hills  
       2016-09-14 09:51:11 +08:00 via iPhone
    5 楼正解
    jy01264313
        11
    jy01264313  
       2016-09-14 10:15:08 +08:00
    5 楼正解+1
    楼主多大的并发,每次操作耗时多少?
    最简单满足需求就好。
    如果是一个 int 的加减,每秒 2 3 百万的操作都不用加锁,当然不是 100% 保险。
    UnitTest
        12
    UnitTest  
       2016-09-14 10:44:02 +08:00
    如果不是精确到毫秒级别, 肯定 redis 比自己写 map 来的方便.
    reus
        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 ,只能有一个原因:能力不足。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1016 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 21:07 · PVG 05:07 · LAX 13:07 · JFK 16:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.