0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

关于高并发和秒杀系统基本的概念的建立

C语言专家集中营 来源:未知 作者:李倩 2018-06-04 17:10 次阅读

大家也许开发过高并发的系统或者秒杀程序,但肯定都有接触过,像电商平台的秒杀、抢购等活动,还有12306春运抢票。

互联网公司,做一些有奖活动,而且数量有限,奖品给力,如果是先到先得的策略,那就类似秒杀系统了。

这类系统最大的问题就是活动周期短,瞬间流量大(高并发),很少人可以成功下单,绝大多数人都是很遗憾。所以从运营体验上,没有成功下单的人,心里肯定是不好受的,如果这时候,因为技术、网络问题,影响用户体验,那就更是骂声一片。

这里,就来讲一讲技术在这种情况下,会发生和要做的事。

下面是基本的概念的建立。

第一:高并发

技术要做的事,一方面优化程序,让程序性能最优,单次请求时间能从50ms优化到25ms,那就可以在一秒钟内成功响应翻倍的请求了。

另一方面就是增加服务器,用更大的集群来处理用户请求,设计好一个可靠且灵活扩充的分布式方案就更加重要了。

第二:时间短

火热的秒杀活动,真的是一秒钟以内就会把商品抢购一空,而大部分用户的感受是,提交订单的过程却要等待好几秒、甚至十几秒,更糟糕的当然是请求报错。

那么一个好的秒杀体验,当然希望尽可能减少用户等待时间,准确的提示用户当前是否还有商品库存。而这些,也是需要有优秀的程序设计来保证的。

第三:系统容量预估

系统设计的时候,都需要有一个容量预估,那就是要提前计算好,我们设计的系统,要承载多大的数量级。

假如线上前端服务器规格是8核16G内存的服务器,而提交订单的处理程序耗时100ms,那么可以简单计算一下:

每秒可以处理的订单请求数=1000ms/100ms*8=80qps

上面这个结果,对于秒杀系统来说,肯定是非常不理想的。

如果能将处理程序耗时优化后,降低到10ms,那么就可以达到800qps。

如果我们可以把程序继续优化,能快速区分开有库存和无库存处理,那么无库存时处理就有可能做到1ms甚至更低的耗时。这样无库存时就能有更好的性能,上万的qps也是可以达到的。

上面的预估,都是针对单机,那么简单的增加前端服务器,是不是就能有更好的并发处理量呢?

肯定没这么简单,因为数据库、缓存系统甚至机房网络带宽都会成为瓶颈。

于是就要有一个更好的分布式方案。

第四:好的分布式方案

一个好的分布式方案,首先当然是稳定可靠,不要出乱子,然后就是方便扩充,最好的效果当然是增加一台服务器,并发处理量可以1:1线性增长。

比如:单机qps是1k,那么10台服务器可以做到1w,100台可以做到10w每秒。

要做到这样的线性增长效果,就要杜绝出现瓶颈,否则还是会代价太大。

拒绝假的分布式尤其重要,比如:前端服务器是可以独立存在的,但是都依赖集中的一个数据库或者缓存系统,那最后,一定是集中的那个数据库或者缓存系统受不了,同样无法做到一个好的分布式。

第五:关注系统的瓶颈

大家先有几个基本的共识,系统的处理速度

程序内数据读写 > redis > mysql > 磁盘

单机网络请求 > 局域网内请求 > 跨机房请求

我们优化程序的时候,尽量用最快的方式,尽量用最简短的逻辑。

用redis替代mysql来保存订单处理中依赖的数据,用程序中的提交的数据代替从redis中二次获取数据,比如:商品库存信息,用户订单信息。

逻辑处理中,把速度快且提前中断的逻辑放在最前面,比如:验证登录,验证问答

我们做分布式方案的时候,尽量把资源调用放在最近的地方。

前端服务器依赖的数据尽量就在局域网内,如果能在单机都有读的redis服务当然更好,程序维护数据响应会复杂些。

不要出现跨机房网络请求,不要出现跨机房网络请求,不要出现跨机房网络请求,重要的事情说三遍。

第六:什么语言更适合这类系统

课程中用的是PHP语言,开发这类系统也是没问题的。

当然,像是用golang, ngx_lua可能在高并发和性能方面会更有优势。

如果使用java、.net当然也是可以的,作为一个系统,语言只是工具,更好的设计和优化,才能达到最终想要的效果。

有了上面的基本概念,我们接下来再来看看,具体运行时,会出现什么状况。

下面是一些具体的问题:

问题1:库存超卖

只有10个库存,但是一秒钟有1k个订单,怎么能不超卖呢?

核心思想就是保证库存递减是原子性操作,10--返回9,9--返回8,8--返回7。

而不能是读取出来库存10,10-1=9再更新回去。因为这个读取和更新是并发执行的,很可能就会有1k个订单都成功了,而库存实际只有10。

那么,怎么保证原子性操作呢?

1 数据库:

update product set left_num=left_num-1 where left_num>0;

这里用到的是left_num=left_num-1,如果left_num>0才能执行成功,数据库查询、更新的时候有用到锁,是可以保证更新操作的原子性的。

数据库性能较差,不建议使用。

2 分布式锁

用redis来做一个分布式锁,reids->setnx('lock', 1) 设置一个锁,程序执行完成再del这个锁。

锁定的过程,不利于并发执行,大家都在等待锁解开,不建议使用。

3 消息队列

将订单请求全部放入消息队列,然后另外一个后台程序一个个处理队列中的订单请求。

并发不受影响,但是用户等待的时间较长,进入队列的订单也会很多,体验上并不好,也不建议使用。

4 redis递减

通过 redis->incrby('product', -1) 得到递减之后的库存数。

性能方面很好,同时体验上也很好,在PHP秒杀课程中,优化后就是用的这种方法,而没有使用上述其他方法,大家应该也能对比了解啦。

问题2:集群怎么来规划

前端服务器因为没有相互间关联,集群的数量不受影响。

redis的性能可以达到每秒几万次响应,所以一个集群的规模,也就是redis服务可以承载的数量。

比如:一台前端服务器是1~2k的qps(有库存时),那么10台+1台redis就可以是一个独立的集群,可以支撑1~2w每秒订单量。

10个上述的集群就可以做到一秒钟处理10w~20w的有效订单。

如果秒杀活动的库存量在1w以内,预计参与的人数在百万左右,那么有一个集群也就可以搞定。

如果秒杀参与的人数超过千万,那么就要用到不止一个集群了。

问题3:多个集群的数据怎么保持一致性

不要做多集群的数据同步,而是用散列,每个集群的数据是独立存在的。

假设,有10个商品,每个商品有1w库存,规划用10个集群,那么每个集群有10个商品,每个商品是1k库存。

每个集群只需要负责把自己的库存卖掉即可,至于说,会不会有用户知道有10个集群,然后每个集群都去抢。

这种情况就不要用程序来处理了,利用运营规则,活动结束后汇总订单的时候再去处理就好了。

如果担心散列的不合理,比如:某个集群用户访问量特别少,那么可以引入一个中控服务,来监控各个集群的库存,然后再做平衡。

问题4:机器人抢购怎么办:

没什么太好的办法,类似DDOS攻击,只能是让自身更强大才是王道。

运营策略上,可以严格控制用户注册,必须登录,提交订单的时候引入图像验证码,问答,交互式验证等。

上面的内容不知道大家还会有什么疑问,可以给我留言。

具体的关于高并发、秒杀的实战内容,在课程中也有详细的讲解,这里用文字的形式提炼整理出来,希望能更好的帮助大家理解,谢谢~

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 服务器
    +关注

    关注

    12

    文章

    8109

    浏览量

    82485
  • 数据库
    +关注

    关注

    7

    文章

    3590

    浏览量

    63364

原文标题:关于高并发和秒杀系统,你知道的和不知道的一些事

文章出处:【微信号:C_Expert,微信公众号:C语言专家集中营】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    从服务端视角看并发难题

    ,比如:使用集群,分布式的系统架构应用优化,比如:使用更高效的编程语言,优化处理业务逻辑的算法,优化访问数据库的SQL基本原则:分而治之,并提高单个请求的处理速度并发处理的基本手段1)客户端发出请求
    发表于 11-02 15:11

    并发程序设计

    并发是大部分软件在设计开发中都会涉及到的,所以不管到没有到那个职位,并发还是有必要来学习习下的,,我这两天也发现了一个飞关于并发的资料还算不错进程间的创建以及该如何设计说的都很清楚。
    发表于 11-19 13:55

    并发、并行、进程、线程和协程的区别

    首先是并发并发概念是很早就有的了。最早的时候机器都是批处理系统,而且是单道批处理系统,这个系统
    发表于 08-05 08:24

    高性能并发服务器架构分享

    由于自己正在做一个高性能大用户量的论坛程序,对高性能并发服务器架构比较感兴趣,于是在网上收集了不少这方面的资料和大家分享。希望能和大家交流 msn: ———————————————————————————————————————  初创网站与开源软件 6  谈谈大型
    发表于 09-16 06:45

    如何去实现一种基于SpringMVC的电商并发秒杀系统设计

    参考博客Java并发秒杀系统API目录业务场景要解决的问题Redis的使用业务场景首页倒计时秒杀活动,抢购商品要解决的问题
    发表于 01-03 07:50

    Swift中关于并发的一些干货

    Swift 中关于并发的一切:第一部分 当前2017-07-03 11:35程序设计/操作系统原文地址:All about Concurrency in Swift - Part
    发表于 09-25 14:52 0次下载
    Swift中<b class='flag-5'>关于</b><b class='flag-5'>并发</b>的一些干货

    并行和并发哪个好?并行和并发概念和区别

    摘要:并发与并行是两个既相似而又不相同的概念并发性,又称共行性,是指能处理多个同时性活动的能力;并行是指同时发生的两个并发事件,具有并发
    发表于 12-08 09:12 6.5w次阅读
    并行和<b class='flag-5'>并发</b>哪个好?并行和<b class='flag-5'>并发</b>的<b class='flag-5'>概念</b>和区别

    阿里的秒杀系统是如何设计的?

    阿里的秒杀系统是怎么设计的?,服务器,redis,调用,后端
    的头像 发表于 02-20 11:23 1738次阅读
    阿里的<b class='flag-5'>秒杀</b><b class='flag-5'>系统</b>是如何设计的?

    解密高并发业务场景下典型的秒杀系统的架构

    中,就更别提如何构建高并发系统了! 究竟什么样的系统算是高并发系统?今天,我们就一起解密高并发
    的头像 发表于 11-17 10:32 2023次阅读
    解密高<b class='flag-5'>并发</b>业务场景下典型的<b class='flag-5'>秒杀</b><b class='flag-5'>系统</b>的架构

    【源码版】基于SpringMVC的电商高并发秒杀系统设计思路

    参考博客Java高并发秒杀系统API目录业务场景要解决的问题Redis的使用业务场景首页倒计时秒杀活动,抢购商品要解决的问题高并发下库存的控
    发表于 01-12 10:23 0次下载
    【源码版】基于SpringMVC的电商高<b class='flag-5'>并发</b><b class='flag-5'>秒杀</b><b class='flag-5'>系统</b>设计思路

    如何实现一个秒杀系统

    实现一个秒杀系统,采用spring boot 2.x + mybatis+ redis + swagger2 + lombok实现。
    的头像 发表于 09-15 09:56 1732次阅读

    如何控制秒杀商品页面购买按钮的点亮

    售空;(4)一般是定时上架;(5)时间短、瞬时并发量高;   2 秒杀技术挑战 假设某网站秒杀活动只推出一件商品,预计会吸引1万人参加活动,也就说最大并发请求数是10000,
    的头像 发表于 06-29 11:12 507次阅读
    如何控制<b class='flag-5'>秒杀</b>商品页面购买按钮的点亮

    服务器并发概念

    自己调整系统的相关参数 并发概念是什么?什么是并发? 对于服务器并发概念,下面几点是错误的定
    的头像 发表于 11-10 10:05 1369次阅读
    服务器<b class='flag-5'>并发</b>的<b class='flag-5'>概念</b>

    java结合redis秒杀功能

    近年来,随着电子商务的快速发展,各大电商平台都推出了各种促销活动来吸引用户。秒杀活动作为一种高效的促销方式,能够在很短的时间内促成大量的交易。然而,高并发场景下的秒杀活动也给系统带来了
    的头像 发表于 12-04 11:06 255次阅读

    redis高并发能力直接相关概念有哪些

    Redis是一种高性能的开源内存数据库,具有出色的并发能力。为了实现高并发,需要有一些相关概念和技术。下面是关于Redis高并发能力的详细解
    的头像 发表于 12-05 10:34 513次阅读