V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
zhuzhibin
V2EX  ›  问与答

[!]小白请教高并发确保不会有重复数据的问题

  •  
  •   zhuzhibin · 2020-11-30 23:26:36 +08:00 · 1477 次点击
    这是一个创建于 1491 天前的主题,其中的信息可能已经有所发展或是发生改变。

    想请教一下各位大佬们,我们假想一个现在有几十万或者几百万的用户在点击一个图片,点击图片我们会发送一个短信给用户,同个用户不论点击多少次图片,我们期望每个用户只能收到一条消息,也就是一个用户只能发送一条消息。

    每点击图片,我们 new 一个 message 一个进程异步扔到队列去消费,当消息发送出去我们会记录一条 log,发送前我们会去 count 一次 log,如果发过就不要发。

    针对这种场景,大家有啥建议,发散思维,一起聊聊,跟老哥们请教一下。

    我想到的是:
    1.表唯一索引
    2.事务+乐观锁

    如果这样还是会存在部分用户发送了多条消息会是什么情况?

    13 条回复    2020-12-01 12:18:40 +08:00
    zhuzhibin
        1
    zhuzhibin  
    OP
       2020-11-30 23:30:50 +08:00
    🚘🚘🚘🚘🚘🚘🚘🚘🚘🚘
    936053688
        2
    936053688  
       2020-11-30 23:42:55 +08:00
    redis 分布式锁如何?
    Jooooooooo
        3
    Jooooooooo  
       2020-11-30 23:44:44 +08:00
    这种防重不用特别严谨的场景 redis 的 setnx 搞定
    zhuzhibin
        4
    zhuzhibin  
    OP
       2020-11-30 23:55:49 +08:00
    @Jooooooooo 如果说点击加 1s 锁 ,用户发起两次请求,第一次一直 loading 可能响应了 20s,用户觉得好像没点到在第一次响应完之前又点了很多次,这时候其实第一次的锁已经失效了。反正我遇到过类似场景,有部分的重复数据,很头疼,有什么好的定位排查方法吗
    zhuzhibin
        5
    zhuzhibin  
    OP
       2020-11-30 23:58:50 +08:00
    起 N 个进程同时消费队列 如果上面说的都做了 是一定会杜绝重复数据么 之前遇到过 review 代码该做的都做了,但是拉数据就是会有部分重复的,或者重复消费的,如果针对这种问题,有老哥可以大致分析一下整一个 flow 是如何流转的吗,以及会产生什么问题,要怎么去避免,出现问题如何更好的排查。小白请教哈,勿喷
    zhuzhibin
        6
    zhuzhibin  
    OP
       2020-11-30 23:59:12 +08:00
    @936053688 老哥展开说说?
    crazyhorse
        7
    crazyhorse  
       2020-12-01 08:43:21 +08:00
    你这需求表唯一索引就可以了,你的顺序有点问题。图片 ID 和 user id 建个联合唯一索引,如果 insert 成功就执行你的队列、失败就直接结束
    CURD663
        8
    CURD663  
       2020-12-01 09:34:17 +08:00
    @crazyhorse 同意,建个唯一索引,第一次能插入成功,后面插入失败不用管.
    zhuzhibin
        9
    zhuzhibin  
    OP
       2020-12-01 10:01:37 +08:00 via iPhone
    @crazyhorse 如果说某个场景这个表同个用户会多条记录呢?例如某一天可以最多发两条消息 要怎么设计了 这时候不能唯一索引
    zhuzhibin
        10
    zhuzhibin  
    OP
       2020-12-01 10:04:53 +08:00 via iPhone
    @CURD663 常规来说的确是这样 唯一索引 事务来保证唯一 如果说某种情况会存在两天记录呢
    serical
        11
    serical  
       2020-12-01 10:07:54 +08:00 via iPhone
    给用户 id 加分布式锁
    936053688
        12
    936053688  
       2020-12-01 11:38:14 +08:00
    @zhuzhibin 哦,发现场景不一样。你是接收后推消息到队列,然后消费消息去发送短信;如果只是过滤用户的话,感觉可以参考前不久看到的布隆过滤器概念,用户点击过后,用户编码哈希过后校验位图,如果位图存在则已点击过,不发消息;未点击过,加入位图,发送消息。个人浅见,互相学习。
    Dingjiangnan
        13
    Dingjiangnan  
       2020-12-01 12:18:40 +08:00
    @zhuzhibin Redisson
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1000 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 21:46 · PVG 05:46 · LAX 13:46 · JFK 16:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.