V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
voidmnwzp
V2EX  ›  程序员

求教,关于 im 中群组服务如何设计

  •  
  •   voidmnwzp ·
    NullpointerW · 108 天前 · 1345 次点击
    这是一个创建于 108 天前的主题,其中的信息可能已经有所发展或是发生改变。

    群组信息应该持久化保存在 db 中,群组相关的操作在群组服务中进行写入和读取,通过 api 对群组进行操作(比如添加成员)那么将会采用一致性 hash 通过群组 id 找到对应的群组服务器中进行业务操作,那么群组信息写入后缓存的操作逻辑有两种:

    1:对应请求后从 db 读取缓存在内存中加读写锁维护,进行写入时先写内存后写 db ,读只会读内存
    2:纯粹作为缓存来读取,有写入时则删除缓存,后续请求需要再从 db 读取数据

    第一种的问题是:如果群组集群有服务器 a 宕机,那么一个群组(id=xxx)就会被分配到新的服务器 b 上,当 b 服务器在写入时,a 服务器恢复上线就会造成 db 层数据不一致;或者是 b 服务器服务了一段时间后,a 重新上线,该群组又会回到 a 上处理,过了段时间又宕机,这时群组 xxx 又被分配到了 b 上,可 b 上的内存数据是旧数据 如果采用第一种感觉对 db 的操作会过于频繁,有什么更好的方案吗

    8 条回复    2024-07-26 10:10:29 +08:00
    codegenerator
        1
    codegenerator  
       108 天前
    肯定是第二种啊,但是想要优雅就需要特殊的技巧
    第一种因为要在分布式环境下保持内存与 db 的一致性太复杂了
    coderxy
        2
    coderxy  
       108 天前
    前置逻辑就是错的, 群组不是游戏的房间, 不会说某个群组的信息就在某个具体的服务器上, 群组信息存 db 即可,redis 缓存一份也行,都是无状态的。
    im 不是游戏,im 是无状态的。 最多只有最前端的 gateway 需要记录一下某个用户在某个 gateway 上,勉强算是有一点点状态逻辑。
    voidmnwzp
        3
    voidmnwzp  
    OP
       108 天前
    @coderxy 在微服务设计下 群组服务器是负责维护信息和根据群组路由到具体 gateway 的服务,对 gateway 来说只是将查询群组信息和具体业务操作抽离出来作为单独可横向扩容的服务
    GooMS
        4
    GooMS  
       108 天前 via Android
    自相矛盾
    feiyan35488
        5
    feiyan35488  
       108 天前
    服务应该是无状态的,群组缓存直接使用 redis ,把状态抽离出来
    GeekGao
        6
    GeekGao  
       107 天前
    任何随时扩容的服务都应保持无状态;任何需要持久化的数据都应及时落盘;
    CAP 、CAP 还是 CAP 。
    wkong
        7
    wkong  
       107 天前
    要限制写入的节点只有一个,其他节点只能读。 参考 raft 选举机制
    nodesolar
        8
    nodesolar  
       106 天前
    用户的归属群组存 redis 即可,以前基于 goim 搞过.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2035 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 16:15 · PVG 00:15 · LAX 08:15 · JFK 11:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.