假设一个需求,在某个预告活动中准备了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

[高并发]抢红包设计(使用redis)的更多相关文章

  1. java高级精讲之高并发抢红包~揭开Redis分布式集群与Lua神秘面纱

    java高级精讲之高并发抢红包~揭开Redis分布式集群与Lua神秘面纱 redis数据库 Redis企业集群高级应用精品教程[图灵学院] Redis权威指南 利用redis + lua解决抢红包高并 ...

  2. Java生鲜电商平台-高并发的设计与架构

    Java生鲜电商平台-高并发的设计与架构 说明:源码下载Java开源生鲜电商平台以及高并发的设计与架构文档 对于高并发的场景来说,比如电商类,o2o,门户,等等互联网类的项目,缓存技术是Java项目中 ...

  3. 高并发架构系列:Redis为什么是单线程、及高并发快的3大原因详解

    Redis的高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快: 2.redis是单线程的,省去了很多上下文切换线程的时间: 3.redis使用多路复用技术,可以处理并发的连接.非阻塞 ...

  4. 朱晔的互联网架构实践心得S2E6:浅谈高并发架构设计的16招

    朱晔的互联网架构实践心得S2E6:浅谈高并发架构设计的16招 概览 标题中的高并发架构设计是指设计一套比较合适的架构来应对请求.并发量很大的系统,使系统的稳定性.响应时间符合预期并且能在极端的情况下自 ...

  5. 15套java架构师、集群、高可用、高可扩 展、高性能、高并发、性能优化Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分布式项目实战视频教程

    * { font-family: "Microsoft YaHei" !important } h1 { color: #FF0 } 15套java架构师.集群.高可用.高可扩 展 ...

  6. 【高并发简单解决方案】redis队列缓存 + mysql 批量入库 + php离线整合

    需求背景:有个调用统计日志存储和统计需求,要求存储到mysql中:存储数据高峰能达到日均千万,瓶颈在于直接入库并发太高,可能会把mysql干垮. 问题分析 思考:应用网站架构的衍化过程中,应用最新的框 ...

  7. 【高并发简单解决方案】redis缓存队列+mysql 批量入库+php离线整合

    原文出处: 崔小拽 需求背景:有个调用统计日志存储和统计需求,要求存储到mysql中:存储数据高峰能达到日均千万,瓶颈在于直接入库并发太高,可能会把mysql干垮. 问题分析 思考:应用网站架构的衍化 ...

  8. 高并发架构系列:Redis缓存和MySQL数据一致性方案详解

    一.需求起因 在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节.所以,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问MySQL等数据库. 这个业务场景, ...

  9. 高并发架构系列:Redis并发竞争key的解决方案详解

    https://blog.csdn.net/ChenRui_yz/article/details/85096418 https://blog.csdn.net/ChenRui_yz/article/l ...

随机推荐

  1. bzoj 4569: [Scoi2016]萌萌哒

    Description 一个长度为n的大数,用S1S2S3...Sn表示,其中Si表示数的第i位,S1是数的最高位,告诉你一些限制条件,每个条 件表示为四个数,l1,r1,l2,r2,即两个长度相同的 ...

  2. Docker(七):Docker容器卷管理

    1.使用容器卷的原因:Docker容器产生的数据,如果不通过commit生成新的镜像,数据会在容器删除后丢失.为了能持久化保存和共享容器的数据,Docker提出了两种管理数据的方式:数据卷和数据卷容器 ...

  3. 几个关于js数组方法reduce的经典片段

    以下是个人在工作中收藏总结的一些关于javascript数组方法reduce的相关代码片段,后续遇到其他使用这个函数的场景,将会陆续添加,这里作为备忘. javascript数组那么多方法,为什么我要 ...

  4. bug运输[辽宁2014年省队互测一]

    奇奇怪怪的题目,不知道他要我们干什么. 我们观察一波局势,发现答案最大不过5.因为如果答案是6或以上的话,我们就至少要2^(5*5)个5*5的方格. 仔细计算一波时间复杂度,再信仰一波,坚信暴力压正解 ...

  5. Lambda 表达式,Java中应用Lambda 表达式

    一.Lambda 表达式 简单来说,编程中提到的 lambda 表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数. 链接:知乎 先举一个普通的 Python 例 ...

  6. Python day02 三元运算

     type  查看数据类型.2 **32  :2的32次方 .浮点的表示类型是小数,但是小数不仅仅包括浮点 浮点数用来处理实数,即带有小数的数字 三元运算:  result = 值1 if 条件 el ...

  7. 《Python cookbook》 “定义一个属性可由用户修改的装饰器” 笔记

    看<Python cookbook>的时候,第9.5部分,"定义一个属性可由用户修改的装饰器",有个装饰器理解起来花了一些时间,做个笔记免得二刷这本书的时候忘了 完整代 ...

  8. window64 PHP ffmpeg详解简单上手 音频amr转mp3

    从网上找了一大堆关于window 64 ffmpeg的信息,都是又长又不关键,让人难消化. 我只要简单的amr转MP3格式而已. 终于搞明白.自己总结了下! 希望能帮助到喜欢言简意赅,一眼上手的同学. ...

  9. Python的Django框架完成一个完整的论坛(源码以及思路)

    一个完整的论坛,登录.注册.发表.头像.点赞.评论.分页.阅读排行等 使用Django2,Python3.5 开发工具:Pycharm5 需要的知识:Python基础知识,Django原理的理解以及使 ...

  10. 记录一次APP的转让流程

    由于业务需要,需要将开发的App从一个账号(A账号)转移到另一个账号(B账号),这里简单介绍一下转让流程.主要包括两大步骤: 转让方(A账号)提出转让申请 接收方(B账号)接受转让App 如果不想看这 ...