zhuzhibin
V2EX  ›  问与答

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

  •  
  •   zhuzhibin · Nov 30, 2020 · 2382 views
    This topic created in 1988 days ago, the information mentioned may be changed or developed.

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

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

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

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

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

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