如何解决秒杀的性能问题和超卖的讨论

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何解决秒杀的性能问题和超卖的讨论相关的知识,希望对你有一定的参考价值。

参考技术A KDJ指标又叫随机指标,应用法则是三条曲线,在应用时主要从五个方面进行考虑:KD的取值的绝对数字;KD曲线的形态;KD指标的交叉;KD指标的背离;J指标的取值大小。第一,从KD的取值方面考虑。KD的取值范围都是0~100,将其划分为几个区域:80以上为超买区,20以下为超卖区,其余为徘徊区。根据这种划分,KD超过80就应该考虑卖出了,低于20就应该考虑买入了。应该说明的是,上述划分只是一个应用KD指标的初步过程,仅仅是信号,完全按这种方法进行操作很容易招致损失。第二,从KD指标曲线的形态方面考虑。当KD指标在较高或较低的位置形成了头肩形和多重顶(底)时,是采取行动的信号。注意,这些形态一定要在较高位置或较低位置出现,位置越高或越低,结论越可靠。第三,从KD指标的交叉方面考虑。K与D的关系就如同股价与MA的关系一样,也有死亡交叉和黄金交叉的问题,不过这里交叉的应用是很复杂的,还附带很多其他条件。以K从下向上与D交叉为例:K上穿D是金叉,为买入信号。但是出现了金叉是否应该买入,还要看别的条件。第一个条件是金叉的位置应该比较低,是在超卖区的位置,越低越好。第二个条件是与D相交的次数。有时在低位,K、D要来回交叉好几次。交叉的次数以2次为最少,越多越好。第三个条件是交叉点相对于KD线低点的位置,这就是常说的“右侧相交”原则。K是在D已经抬头向上时才同D相交,比D还在下降时与之相交要可靠得多。第四,从KD指标的背离方面考虑。在KD处在高位或低位,如果出现与股价走向的背离,则是采取行动的信号。第五,J指标取值超过100和低于0,都属于价格的非正常区域,大于100为超买,小0为超卖。具体的可用个牛股宝手机炒股去看看,里面有多项指标指导,每项指标都有详细说明如何应用,使用起来有一定的帮助,希望能帮助到您,祝投资愉快!

秒杀与超卖的 性能解决之路

一、秒杀带来了什么?

        秒杀或抢购活动一般会经过【预约】【抢订单】【支付】这3个大环节,而其中【抢订单】

这个环节是最考验业务提供方的抗压能力的。


 

抢订单环节一般会带来2个问题:

  1、高并发

  比较火热的秒杀在线人数都是10w起的,如此之高的在线人数对于

       网站架构从前到后都是一种考验。

 

     2、超卖

  任何商品都会有数量上限,如何避免成功下订单买到商品的人数不

       超过商品数量的上限,这是每个抢购活动都要面临的难题。

 


 

 

二、如何解决? 

首先,产品解决方案我们就不予讨论了。我们只讨论技术解决方案

1、前端

     面对高并发的抢购活动,前端常用的三板斧是【扩容】【静态化】【限流】

  A:扩容

  加机器,这是最简单的方法,通过增加前端池的整体承载量来抗峰值。

  

       B:静态化

  将活动页面上的所有可以静态的元素全部静态化,并尽量减少动态元素。通过CDN来抗峰值。

  

C:限流

  一般都会采用IP级别的限流,即针对某一个IP,限制单位时间内发起请求数量。

  或者活动入口的时候增加游戏或者问题环节进行消峰操作。

  

D:有损服务

  最后一招,在接近前端池承载能力的水位上限的时候,随机拒绝部分请求来保护活动整体的可用性。


 

2、后端

那么后端的数据库在高并发和超卖下会遇到什么问题呢?

主要会有如下3个问题:(主要讨论写的问题,读的问题通过增加cache可以很容易的解决)

  I:  首先MySQL自身对于高并发的处理性能就会出现问题,一般来说,MySQL的处理

       性能会随着并发thread上升而上升,但是到了一定的并发度之后会出现明显的拐点,

       之后一路下降,最终甚至会比单thread的性能还要差。

  II:   其次,超卖的根结在于减库存操作是一个事务操作,需要先select,然后insert,最

        后update -1。最后这个-1操作是不能出现负数的,但是当多用户在有库存的情况下

        并发操作,出现负数这是无法避免的。

  III:  最后,当减库存和高并发碰到一起的时候,由于操作的库存数目在同一行,就会出现

      争抢InnoDB行锁的问题,导致出现互相等待甚至死锁,从而大大降低MySQL的处理性

      能,最终导致前端页面出现超时异常。

 


 

针对上述问题,如何解决呢? 我们先看眼淘宝的高大上解决方案:

  I: 关闭死锁检测,提高并发处理性能。

  II:修改源代码,将排队提到进入引擎层前,降低引擎层面的并发度。

  III:组提交,降低server和引擎的交互次数,降低IO消耗。


解决方案1:

       将存库从MySQL前移到Redis中,所有的写操作放到内存中,由于Redis中不存在锁故

不会出现互相等待,并且由于Redis的写性能和读性能都远高于MySQL,这就解决了高并发

下的性能问题。然后通过队列等异步手段,将变化的数据异步写入到DB中。

优点:解决性能问题

缺点:没有解决超卖问题,同时由于异步写入DB,存在某一时刻DB和Redis中数据不一致的风险。


 解决方案2:

      引入队列,然后将所有写DB操作在单队列中排队,完全串行处理。当达到库存阀值的时候

就不在消费队列,并关闭购买功能。这就解决了超卖问题。

优点:解决超卖问题,略微提升性能。

缺点:性能受限于队列处理机处理性能和DB的写入性能中最短的那个,

          另外多商品同时抢购的时候需要准备多条队列。

 


 

解决方案3:

将写操作前移到MC中,同时利用MC的轻量级的锁机制CAS来实现减库存操作。

优点:读写在内存中,操作性能快,引入轻量级锁之后可以保证同一时刻

           只有一个写入成功,解决减库存问题。

缺点:没有实测,基于CAS的特性不知道高并发下是否会出现大量更新失败?

          不过加锁之后肯定对并发性能会有影响。

 


 

解决方案4:

        将提交操作变成两段式,先申请后确认。然后利用Redis的原子自增操作(相比较MySQL的

自增来说没有空洞),同时利用Redis的事务特性来发号,保证拿到小于等于库存阀值的号的人都

可以成功提交订单。然后数据异步更新到DB中。

优点:解决超卖问题,库存读写都在内存中,故同时解决性能问题。

缺点:由于异步写入DB,可能存在数据不一致。另可能存在少买,也就是如果拿到号的人

          不真正下订单,可能库存减为0,但是订单数并没有达到库存阀值。

 

以上是关于如何解决秒杀的性能问题和超卖的讨论的主要内容,如果未能解决你的问题,请参考以下文章

秒杀与超卖的 性能解决之路

解决redis秒杀超卖的问题

如何解决高并发秒杀的超卖问题

秒杀系统是如何防止超卖的?

java redis 实现抢购秒杀

使用Redis解决秒杀业务问题分析与解决方案