当前位置: 首页 > news >正文

用 Redis 轻松实现秒杀系统的构思

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

秒杀系统的架构设计

秒杀系统,是典型的短时大量突发访问类问题。对这类问题,有三种优化性能的思路:

1. 写入内存而不是写入硬盘、

2. 异步处理而不是同步处理、

3. 分布式处理

用上这三招,不论秒杀时负载多大,都能轻松应对。更好的是,Redis能够满足上述三点。因此,用Redis就能轻松实现秒杀系统。 用我这个方案,无论是电商平台特价秒杀,12306火车票秒杀,都不是事:)

下面介绍一下为什么上述三种性能优化思路能够解决秒杀系统的性能问题:

  • 写入内存而不是写入硬盘 传统硬盘的读写性能是相当差的。SSD硬盘比传统硬盘快100倍。而内存又比SSD硬盘快10倍以上。因此,写入内存而不是写入硬盘,就能使系统的能力提升上千倍。也就是说,原来你的秒杀系统可能需要1000台服务器支撑,现在1台服务器就可以扛住了。 你可能会有这样的疑问:写入内存而不是持久化,那么如果此时计算机宕机了,那么写入的数据不就全部丢失了吗?如果你就这么倒霉碰到服务器宕机,那你就没秒到了,有什么大不了? 最后,后面真正处理秒杀订单时,我们会把信息持久化到硬盘中。因此不会丢失关键数据。 Redis是一个缓存系统,数据写入内存后就返回给客户端了,能够支持这个特性。
  • 异步处理而不是同步处理 像秒杀这样短时大并发的系统,在性能负载上有一个明显的波峰和长期的波谷。为了应对相当短时间的大并发而准备大量服务器来应对,在经济上是相当不合算的。 因此,对付秒杀类需求,就应该化同步为异步。用户请求写入内存后立刻返回。后台启动多个线程从内存池中异步读取数据,进行处理。如用户请求可能是1秒钟内进入的,系统实际处理完成可能花30分钟。那么一台服务器在异步情况下其处理能力大于同步情况下1800多倍! 异步处理,通常用MQ(消息队列)来实现。Redis可以看作是一个高性能的MQ。因为它的数据读写都发生在内存中。
  • 分布式处理 好吧。也许你的客户很多,秒杀系统即使用了上面两招,还是捉襟见肘。没关系,我们还有大招:分布式处理。如果一台服务器撑不住秒杀系统,那么就多用几台服务器。10台不行,就上100台。分布式处理,就是把海量用户的请求分散到多个服务器上。一般使用hash实现均匀分布。 这类系统在大数据云计算时代的今天已经有很多了。无非是用Paxos算法和Hash Ring实现的。 Redis Cluster正是这样一个分布式的产品。

使用Redis实现描述系统

Redis和Redis Cluster(分布式版本),是一个分布式缓存系统。其支持多种数据结构,也支持MQ。Redis在性能上做了大量优化。因此使用Redis或者Redis Cluster就可以轻松实现一个强大的秒杀系统。 基本上,你用Redis的这些命令就可以了。 RPUSH key value 插入秒杀请求

当插入的秒杀请求数达到上限时,停止所有后续插入。 后台启动多个工作线程,使用 LPOP key 读取秒杀成功者的用户id,进行后续处理。 或者使用LRANGE key start end命令读取秒杀成功者的用户id,进行后续处理。 每完成一条秒杀记录的处理,就执行INCR key_num。一旦所有库存处理完毕,就结束该商品的本次秒杀,关闭工作线程,也不再接收秒杀请求。

要是还撑不住,该怎么办

也许你会说,我们的客户很多。即使部署了Redis Cluster,仍然撑不住。那该怎么办呢? 记得某个伟人曾经说过:办法总比困难多!

下面,我们具体分析下,还有哪些情况会压垮我们架构在Redis(Cluster)上的秒杀系统。

脚本攻击

如现在有很多抢火车票的软件。它们会自动发起http请求。一个客户端一秒会发起很多次请求。如果有很多用户使用了这样的软件,就可能会直接把我们的交换机给压垮了。

这个问题其实属于网络问题的范畴,和我们的秒杀系统不在一个层面上。因此不应该由我们来解决。很多交换机都有防止一个源IP发起过多请求的功能。开源软件也有不少能实现这点。如linux上的TC可以控制。流行的Web服务器Nginx(它也可以看做是一个七层软交换机)也可以通过配置做到这一点。一个IP,一秒钟我就允许你访问我2次,其他软件包直接给你丢了,你还能压垮我吗?

交换机撑不住了

可能你们的客户并发访问量实在太大了,交换机都撑不住了。 这也有办法。我们可以用多个交换机为我们的秒杀系统服务。 原理就是DNS可以对一个域名返回多个IP,并且对不同的源IP,同一个域名返回不同的IP。如网通用户访问,就返回一个网通机房的IP;电信用户访问,就返回一个电信机房的IP。也就是用CDN了! 我们可以部署多台交换机为不同的用户服务。 用户通过这些交换机访问后面数据中心的Redis Cluster进行秒杀作业。

总结

有了Redis Cluster的帮助,做个支持海量用户的秒杀系统其实So Easy! 这里介绍的方案虽然是针对秒杀系统的,但其背后的原理对其他高并发系统一样有效。 最后,我们再重温一下高性能系统的优化原则: 写入内存而不是写入硬盘、异步处理而不是同步处理、分布式处理。

群内提供免费的Java架构学习资料,QQ群:643459718
(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,
MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)

转载于:https://my.oschina.net/u/4051865/blog/3036104

相关文章:

  • UITableView/UIScrollView 不能响应TouchBegin 的处理 及窥见 hitTest:withEvent:
  • UDP,TCP之间的区别
  • springboot 系列教程六:springboot mybatis集成
  • windows添加开机启动项
  • 关于Docker文件系统
  • XP和Win 7双系统安装说明和注意事项
  • jQuery之getAll()和cleanData()
  • 利用pig分析cdn访问日志内指定时间段的url访问次数
  • 6本Python好书上新,来撩~
  • cursor:hand与cursor:pointer的区别介绍
  • 【AC自动机】AC自动机
  • Java 生成 exe 文件
  • 大数据分析工具如何摆脱样子工程?
  • 学习Android怎么在未来站稳脚跟
  • 预测《权游》角色生死,AI算法魔力何在?
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • 0x05 Python数据分析,Anaconda八斩刀
  • CentOS7 安装JDK
  • dva中组件的懒加载
  • EOS是什么
  • golang 发送GET和POST示例
  • IDEA 插件开发入门教程
  • JavaScript-Array类型
  • JavaScript创建对象的四种方式
  • vue-loader 源码解析系列之 selector
  • WebSocket使用
  • 闭包,sync使用细节
  • 构建工具 - 收藏集 - 掘金
  • 缓存与缓冲
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 理解在java “”i=i++;”所发生的事情
  • 前言-如何学习区块链
  • 实战|智能家居行业移动应用性能分析
  • 微服务核心架构梳理
  • 在 Chrome DevTools 中调试 JavaScript 入门
  • 责任链模式的两种实现
  • No resource identifier found for attribute,RxJava之zip操作符
  • ​​​​​​​​​​​​​​Γ函数
  • ​Base64转换成图片,android studio build乱码,找不到okio.ByteString接腾讯人脸识别
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • ​第20课 在Android Native开发中加入新的C++类
  • #{} 和 ${}区别
  • (06)Hive——正则表达式
  • (AtCoder Beginner Contest 340) -- F - S = 1 -- 题解
  • (Python) SOAP Web Service (HTTP POST)
  • (附源码)springboot宠物医疗服务网站 毕业设计688413
  • (附源码)基于SSM多源异构数据关联技术构建智能校园-计算机毕设 64366
  • (过滤器)Filter和(监听器)listener
  • (十) 初识 Docker file
  • (四)TensorRT | 基于 GPU 端的 Python 推理
  • (算法)N皇后问题
  • (一) springboot详细介绍
  • (转)Oracle存储过程编写经验和优化措施
  • (转)关于pipe()的详细解析
  • (转)真正的中国天气api接口xml,json(求加精) ...