导论linux
曾经被问过好屡次怎样实现秒杀系统的问题。昨天又在CSDN架构师微信群被问到了。所以这里把我设想的实现秒杀系统的价格设计分享出来。供你们参考。算法
秒杀系统的架构设计后端
秒杀系统,是典型的短时大量突发访问类问题。对这类问题,有三种优化性能的思路:缓存
写入内存而不是写入硬盘性能优化
异步处理而不是同步处理服务器
分布式处理微信
用上这三招,不论秒杀时负载多大,都能轻松应对。更好的是,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工程化、高性能及分布式、深刻浅出。性能调优、Spring,MyBatis,Netty源码分析的朋友能够加Java后端架构群:687810532,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给你们。