最近群里聊起秒杀和限流,我自己没有做过类似应用,但是工作中遇到过更大的数据和并发。

于是提出了一个简单的模型:

var count = rds.inc(key);

if(count > 1000) throw "已抢光!"

借助Redis单线程模型,它的inc是安全的,确保每次加一,然后返回加一后的结果。如果原来是234,加一了就是235,返回的一定是235,在此中间,不会有别的请求来打断从而导致返回236或者其它。

其实我们可以理解为inc的业务就是占坑排队,每人占一个坑,拿到排队小票后看看是不是超额了,再从业务层面输出秒杀结果,甚至做一些更加复杂的业务。

六条提到限流,可能基于某种考虑,希望把key对应的count给限制在1000附近,可以接受1%偏差。

于是有了改进模型:

var count = rds.inc(key);

if(count > 1000){

rds.dec(key);

throw "超出限额!"

就加了一句,超出限额后,把小票给减回去^_^

采用Redis有一个好处,比如支持很多应用服务器一起抢……

当然,对于很大量的秒杀,这个模型也不一定合理,比如要枪10万部手机,然后来了300万用户,瞬间挤上来。

这里有个变通方法可以试一下,那就是准备10个Redis实例,每个放1万。用户请求过来的时候,可以随机数或者散列取模,找对应实例来进行抢购。

同理可以直接更多用户的场景。总的来说,在数据较大的时候,随机和散列就具有一定统计学意义,相对来说是比较均衡的。

上面是大量秒杀的简单场景,那么小数据场景呢?比如就只有几万并发的场景

小数据场景,单应用实例,可以考虑把Redis都给省了。

初级模型:

Interlocked.Increase(ref count);

if(count >= 1000) throw "抢光啦!"

中级模型:

private volatile Int32 count;

var old = 0;

do {

old = count;

if(old >= 1000) throw "抢光啦!"

}while(Interlocked.CompareExchange(ref count, old + 1, old) != old);

这个CAS原子操作可是好东西,在x86指令集下有专门指令CMPXCHG来处理,在处理器级别确保比较和交换数据的原子性。大多数系统想要迈过10万tps的门槛向100万tps靠齐,就必须得实现无锁操作lock-free,其中CAS是最为简单易懂,尽管有时候有ABA问题,但我们可以找到许多解决办法。

在实际使用场景中,可能有更复杂的需求,那就另当别论,这里只能班门弄斧几个简单易用的模型。

借助Redis做秒杀和限流的思考的更多相关文章

  1. spring中实现基于注解实现动态的接口限流防刷

    本文将介绍在spring项目中自定义注解,借助redis实现接口的限流 自定义注解类 import java.lang.annotation.ElementType; import java.lang ...

  2. 小白也能看懂的Redis教学基础篇——做一个时间窗限流就是这么简单

    不知道ZSet(有序集合)的看官们,可以翻阅我的上一篇文章: 小白也能看懂的REDIS教学基础篇--朋友面试被SKIPLIST跳跃表拦住了 书接上回,话说我朋友小A童鞋,终于面世通过加入了一家公司.这 ...

  3. 使用RateLimiter完成简单的大流量限流,抢购秒杀限流

    RateLimiter是guava提供的基于令牌桶算法的实现类,可以非常简单的完成限流特技,并且根据系统的实际情况来调整生成token的速率. 通常可应用于抢购限流防止冲垮系统:限制某接口.服务单位时 ...

  4. 【分布式架构】--- 基于Redis组件的特性,实现一个分布式限流

    分布式---基于Redis进行接口IP限流 场景 为了防止我们的接口被人恶意访问,比如有人通过JMeter工具频繁访问我们的接口,导致接口响应变慢甚至崩溃,所以我们需要对一些特定的接口进行IP限流,即 ...

  5. redis实际应用-限流

    为什么要做限流 首先让我们先看一看系统架构设计中,为什么要做"限流". 旅游景点通常都会有最大的接待量,不可能无限制的放游客进入,比如故宫每天只卖八万张票,超过八万的游客,无法买票 ...

  6. 浅谈 OpenResty,基于opebresty+redis进行实时线上限流

    一.前言 我们都知道Nginx有很多的特性和好处,但是在Nginx上开发成了一个难题,Nginx模块需要用C开发,而且必须符合一系列复杂的规则,最重要的用C开发模块必须要熟悉Nginx的源代码,使得开 ...

  7. springboot + aop + Lua分布式限流的最佳实践

    整理了一些Java方面的架构.面试资料(微服务.集群.分布式.中间件等),有需要的小伙伴可以关注公众号[程序员内点事],无套路自行领取 一.什么是限流?为什么要限流? 不知道大家有没有做过帝都的地铁, ...

  8. nginx 、springMvc(非分布式)相应的限流、消峰

    互联网服务赖以生存的根本是流量, 产品和运营会经常通过各种方式来为应用倒流,比如淘宝的双十一等,如何让系统在处理高并发的同时还是保证自身系统的稳定, 通常在最短时间内提高并发的做法就是加机器, 但是如 ...

  9. 简易RPC框架-客户端限流配置

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

随机推荐

  1. .NET Core RSA 签名和验签(密钥为 16 进制编码)

    使用 OpenSSL 生成公私钥对,命令: $ openssl genrsa -out rsa_1024_priv.pem $ openssl pkcs8 -topk8 -inform PEM -in ...

  2. Asp.net mvc 知多少(二)

    本系列主要翻译自<ASP.NET MVC Interview Questions and Answers >- By Shailendra Chauhan,想看英文原版的可访问http:/ ...

  3. mybatis转义符(转)

    第一种方法: 用了转义字符把>和<替换掉,然后就没有问题了. SELECT * FROM test WHERE 1 = 1 AND start_date  <= CURRENT_DA ...

  4. solr6.5搭建以及使用经验

    首先搭建环境为Linux 6.5 64位  jdk1.7 将webapp目录复制到tomcat下的webapps目录下 可以修改文件夹名为solr(这个自己随意定义,项目名而已) 在tomcat目录下 ...

  5. Cannot open url. please check this url is correct

    启动tomcat报错如下 任务管理器 kill 掉所有java进程,在配置中选中After launch选项 要是还是不行,那就无解,只能重启电脑.

  6. 4. sudo,PATH环境变量,修改字符集,ntpserver,加大文件描述符,隐藏内核版本,锁定关键系统文件

    1   命令:  visudo              98gg      98行             yy           复制当前行             p              ...

  7. npm发布vue组件流程

    初始化项目vue init webpack-simple XXX 定义组件略 发布配置1.package.json 2.webpack.config.js(注释部分为原配置) 发布1.登录 2.发布n ...

  8. PDO绑定含IN的SQL语句的参数注意事项

    PDOStatement::bindParam(),表示将PDO::prepare()语句中的占位符用参数替换掉.注意,在绑定含有IN的SQL多参数语句时要额外小心,比如$stmt = $db-> ...

  9. Windows下RabbitMQ安装及入门

    1.Windows下安装RabbitMQ需要以下几个步骤 (1):下载erlang,原因在于RabbitMQ服务端代码是使用并发式语言erlang编写的,下载地址:http://www.erlang. ...

  10. [置顶] MVC中使用signalR入门教程

    一.前言:每次写总要说一点最近的感想 进入工作快半年了,昨天是最郁闷的一天,我怀疑我是不是得了"星期一综合征",每个星期一很没有状态.全身都有点酸痛,这个可能一个星期只有周末才打一 ...