[高并发]抢红包设计(使用redis)

2021年11月22日 阅读数:3
这篇文章主要向大家介绍[高并发]抢红包设计(使用redis),主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

假设一个需求,在某个预告活动中准备了10w个红包,100w人在某个时间点去开抢,每人只能抢1次,如何保证性能和准确性,下面我给出个人一个设计方案,抛砖引玉

  1. 分析瓶颈
    • 查询用户是否已参与过活动
    • 获取一个可抢的红包,保证多我的不能获取到同一个红包
    • 创建红包与用户的关系
  2. 设计数据结构解决瓶颈问题
    • 查询用户是否已参与过活动:能够使用Set的特性,集合中不能出现重复的数据,每一个用户发起抢的动做就将用户标识放入Set中,若是Set中已存在这个用户标识,则说明用户不可再抢了
    • 获取一个可抢的红包:能够使用队列的数据结构,每次获取红包都是一个出队的动做,解决了多人获取同一个红包和超发的问题
    • 创建红包与用户的关系:一样使用队列的数据结构,每次创建都是一个入队动做,使用单独线程每秒尝试出队多个,批量存储到数据库中
  3. 实现功能
    • 准备工做:生成可抢红包,入队redis的list结构,命令为RPUSH
    • 用户发出抢的请求:用户标识写入redis的Set中,命令SADD,返回1标识插入成功,可继续获取红包,返回0则为已抢,直接返回
    • 获取红包:list出队一条红包数据,命令为LPOP,若是返回不为nil时,表明获取成功,继续下一步,反之则说明已抢完,返回
    • 创建红包与用户的关系:构建红包与用户的关系对象,入队Redis的list,使用单独线程每秒尝试出队1000个(举例),批量存储到数据库中
  4. 需求扩展
    • 10w红包不是先到先得,而是有必定随机性
      • 能够在构建可抢红包列表时,根据需求算法,构建一个包含无红包item的的列表入队,出队判断若是此item表明无红包时返回,反之则进行创建红包与用户的关系
    • 每人能够抢N次,N>=1
      • 使用redis的string数据结构中的INCR命令,用户发起抢的动做,则调用INCR,若是返回数据>N,说明抢的次数已达到上限
  5. 其余
    • redis并非必须的,若是web服务器无横向扩展须要也能够使用内存内的相关数据结构实现,一样的若是其余中间件可提供类似的数据结构功能,也能够替换redis