借助Redis做秒杀和限流的思考

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介:

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

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

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问题,但我们可以找到许多解决办法。

 

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

我不相信神话,我只相信汗水!我不相信命运,我只相信双手!
分类: C#, 大数据

本文转自大石头博客园博客,原文链接:http://www.cnblogs.com/nnhy/p/Seckill.html,如需转载请自行联系原作者
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
缓存 NoSQL Java
基于代码实操SpringBoot、Redis、LUA秒杀系统!
基于代码实操SpringBoot、Redis、LUA秒杀系统!
179 0
|
NoSQL Redis 安全
借助Redis做秒杀和限流的思考
原文:借助Redis做秒杀和限流的思考 最近群里聊起秒杀和限流,我自己没有做过类似应用,但是工作中遇到过更大的数据和并发。 于是提出了一个简单的模型: var count = rds.inc(key); if(count > 1000) throw "已抢光!" 借助Redis单线程模型,它的inc是安全的,确保每次加一,然后返回加一后的结果。
978 0
|
新零售 Web App开发 NoSQL
使用阿里云redis搭建电商秒杀系统
本文介绍如何使用阿里云redis搭建一个高性能的电商秒杀系统。
2483 0
|
新零售 NoSQL JavaScript
阿里云Redis读写分离典型场景:如何轻松搭建电商秒杀系统
本文介绍如何使用阿里云redis搭建一个高性能的电商秒杀系统。
9934 0
|
9天前
|
NoSQL Linux Redis
06- 你们使用Redis是单点还是集群 ? 哪种集群 ?
**Redis配置:** 使用哨兵集群,结构为1主2从,加上3个哨兵节点,总计分布在3台Linux服务器上,提供高可用性。
19 0
|
18天前
|
负载均衡 监控 NoSQL
Redis的集群方案有哪些?
Redis集群包括主从复制(基础,手动故障恢复)、哨兵模式(自动高可用)和Redis Cluster(官方分布式解决方案,自动分片和容错)。此外,还有如Codis、Redisson和Twemproxy等第三方工具用于代理和负载均衡。选择方案需考虑应用场景、数据规模和并发需求。
17 2
|
23天前
|
NoSQL Redis
Redis集群(六):集群常用命令及说明
Redis集群(六):集群常用命令及说明
15 0
|
2月前
|
运维 NoSQL 算法
Redis-Cluster 与 Redis 集群的技术大比拼
Redis-Cluster 与 Redis 集群的技术大比拼
46 0
|
17天前
|
NoSQL Java 测试技术
面试官:如何搭建Redis集群?
**Redis Cluster** 是从 Redis 3.0 开始引入的集群解决方案,它分散数据以减少对单个主节点的依赖,提升读写性能。16384 个槽位分配给节点,客户端通过槽位信息直接路由请求。集群是无代理、去中心化的,多数命令直接由节点处理,保持高性能。通过 `create-cluster` 工具快速搭建集群,但适用于测试环境。在生产环境,需手动配置文件,启动节点,然后使用 `redis-cli --cluster create` 分配槽位和从节点。集群动态添加删除节点、数据重新分片及故障转移涉及复杂操作,包括主从切换和槽位迁移。
30 0
面试官:如何搭建Redis集群?
|
21天前
|
存储 缓存 NoSQL
【Redis深度专题】「核心技术提升」探究Redis服务启动的过程机制的技术原理和流程分析的指南(集群功能分析)(一)
【Redis深度专题】「核心技术提升」探究Redis服务启动的过程机制的技术原理和流程分析的指南(集群功能分析)
42 0

热门文章

最新文章