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

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

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. 【java】反射简单示例

    package 反射; public class Test反射 { public static void main(String[] args) { System.out.println(Runtim ...

  2. 【java】正则表达式简单示例

    public class Test { public static void main(String[] args) { String str="135axy"; String r ...

  3. 商城项目回顾整理(二)easyUi数据表格使用

    后台主页: 商品的数据表格展示 引入用户表数据表格展示 引入日志表数据表格展示 引入订单表数据表格展示 后台主页代码: <%@ page language="java" co ...

  4. [array] leetcode - 39. Combination Sum - Medium

    leetcode - 39. Combination Sum - Medium descrition Given a set of candidate numbers (C) (without dup ...

  5. C++ 头文件系列(iostream)

    1. 简介 这个头文件非常特殊,它只声明了8个常用流对象. 2. 8个对象 2.1 窄字符对象(char) extern istream cin extern ostream cout extern ...

  6. ArcGIS 网络分析[8.4] 资料4 聚合——创建及打开网络数据集的类实现

    这篇是对前三篇的总结,因为网络数据集涉及的"点"太多了,我只能挑重点来设置,大家明白框架后可以自行寻求帮助文档添加功能. 我以C#类的形式给出,这个类包含很多种方法,因为本人的C# ...

  7. open-falcon(v0.2)安装grafana部署

    下载rpm wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-4.4.3-1.x86_64.rpm 本地 ...

  8. CJOJ 免费航班

    Description 小Z在MOI比赛中获得了大奖,奖品是一张特殊的机 票.使用这张机票,可以在任意一个国家内的任意城市之间的免费飞行,只有跨国飞行时才会有额外的费用.小Z获得了一张地图,地图上有城 ...

  9. bzoj 2119: 股市的预测

    Description 墨墨的妈妈热爱炒股,她要求墨墨为她编写一个软件,预测某只股票未来的走势.股票折线图是研究股票的必备工具,它通过一张时间与股票的价位的函数图像清晰地展示了股票的走势情况.经过长时 ...

  10. 5.Nginx作为web缓存服务器

    Nginx作为web缓存服务器 从0.7.48版本开始,Nginx支持类似Squid的缓存功能.Nginx的web缓存服务主要由proxy_cache相关命令集合fastcgi_cache相关命令集构 ...