zoukankan      html  css  js  c++  java
  • 抛砖引玉之一 —— 由12306引发的抢购模式的思考

    本文不涉及数据库原理,不会简单的对比oracle、mysql、sqlserver这些RDBMS的优异(事实上也很难得出结论),只是基于个人观点引发的一点思考,欢迎拍砖;

        一个话题总要有切入点,但这次的切入点显得有些突兀;

        事实上,我们是从数据库的负载均衡问题聊起来的。前面的内容不再赘述,只是话题忽的引到12306订单系统如何应对大并发的问题上;

        由于没有现成的资料,无法评论12306的应用以及数据库架构是否合理。不过从表象上可以猜到一些倪端:

        表象:在春运期间,一般车票是提前N天开始预订,但在放票开始的几秒内被抢购一空

        分析:

    • 明显的“排队”模式(或者说是队列模式);特点和显示生活中排队购票的情景一样,大家排起长队,放票开始后排在前面的先买到,排在后面的如果正好赶上“票已售完”,那就完成了这轮购票任务,下次请早……这是V1.0
    • 通过分时段放票,增加用户排在前面的几率;经历过第一阶段,可能有人发现,如果集中放票,大家都在拼谁起的早,谁跑得快。如果每天只放一部分,那第一天抢到票的人后几天就不会再排队了;或者有人不可能天天都起那么早,于是其他人就有机会买到票了,间接增加了用户买到票的几率;由于这还是基于排队理论,我们姑且叫它V1.1
    • 通过多开窗口,提高并发能力;这是大并发环境下的产物。有人发现,购票的人太多了,票也太多了,指着一个售票员,可能20个小时也卖不完,如果下班关窗口走人,又会激怒后面已经排队的人。于是,1个窗口变成8个,同时销售,增加了并发能力;不过也有问题,要是您排的这队前面有个用钢镚买好几张票的,那估计又白排了。不过这个现象在虚拟环境会通过设置超时时间来控制;这个版本是V1.2

        经过3个版本的演变,貌似我们的购票系统已经相对完善了很多,抽象化一下就可以开始架构设计、开发了。但事实是真的可以么?

        用过12306的同学们,99%以上都经历过春运购票的痛苦,而上面这种购票的模式,在很多场景都被广泛应用,似乎没有什么问题,那问题出在哪里?痛苦的根源在哪里?

    =====================华丽丽的分隔线=====================

        我们先来比较一下排队模式在现实世界和虚拟世界有哪些差异

    • 成本比较

      现实世界:最常见就是通宵排队,争取排到靠前的位置,以此来争取在购票环节能抢得先机。要想在这个环节中获胜,身体好、跑得快是关键因素;

      虚拟世界:有了软件,很方便的实现了定时抢票的效果,不用人盯着机器通宵达旦(为了避免程序BUG,有时还是需要熬夜手动抢票),时间成本被极度缩减;

      效果1:原来排一次队可能要1个小时才能到达售票窗口咨询是否有票,现在可能1分钟甚至更短的时间就能从几百名开外排到售票窗口前,并迅速查出是否有票;

    • 并发比较

      现实世界:尽管购票窗口有多个,但每个人每次只能选择一条队列,而对于是否能买到票,还存在诸多运气因素,比如前面购票人动作太慢,导致有限的资源被其他窗口先占得,亦或是你前面那个人买下了所有的当次车票等等;

      虚拟世界:由于时间成本的降低,以及计算机运算的高效性,单位时间内可操作的指令数增加,排队效率随之增加;简单说,就是原来一次只能排一队,现在只要开多个窗口就能同时排到多个队列中(在实际情况中,往往会通过身份验证等方式限制并发登陆的问题)

      效果2:原来一个人一次只能排一队,现在一个人可以同时排多个队列;

      上面两种,我们称之为客观因素;那其他方面呢?

     

    • 情感因素

      为了照顾老幼病残孕以及军人及其他有特殊贡献的人,现实世界中往往会有“绿色通道”或“优先购票窗口”的存在,这是基于道德层面而产生的符合大众道德观念的做法。当然,只要做好“身份验证”这一关键步骤,大众都是可以理解的;

      但这在虚拟世界中却很难实现,一个是由于“身份验证”的问题(虚拟世界很难判定符合优先条订票人和实际操作人是否为同一个人,如果选择代购,按照我们的道德观念,也不应该排到优先窗口那一队),另一方面是由于相对于现实世界,有这种需求的群体其比例相当小,而通过网络方式订票,从操作上的最低需求上,基本上屏蔽了这一部分群体;
    • 黄牛因素

            这可能是差异最大的问题。

            现实世界:由于时间成本、人力成本(毕竟雇人排队也是要付报酬的)、处罚成本相对较高,因此从总体样本上来看,黄牛党尽管必定存在,但随着处罚力度的加强,势必会逐步维护大众购票利益;

            虚拟时间:根据上面客观因素的分析,黄牛的成本大大降低,而虚拟身份的辨识度问题也为黄牛党制造了更多有利的条件(手上没有现实的统计数据,但我相信黄牛订单无论从数量还是样本占比上,都比现实世界高了很多,甚至是数量级上的差异)

      上面两种,我们称之为主观因素

      

      基于以上因素的考虑,我们可以看出,尽管网络购票的方式有极大的便利性,但直接套用“排队模式”或许会带来更大的问题(黄牛问题最为明显),这就对原有模式中强调的公平性产生最大的挑战,但如何才能做到更公平?

          严格意义上讲,公平只是我们在诸多因素影响下想要达到的一种理想化状态而已,这个状态是短暂的,或者说是极不稳定状态,任何一点的因素都可能打破它的平衡性;如果这样看,那不公平或许才是一种常态;

      笔者观点:公平并非必然,不公平也并非偶然。

    =====================华丽丽的分隔线=====================

      既然公平是一种极不稳定的状态,或许我们可以通过一种工具使之趋于的动态平衡,这里我倾向于引入随机性;

      简单来说:假设我们在收集的所有样本(这些样本可以理解为某一列次车票的所有订单)中随机选择一些使其获得车票,这或许也是一种公平的描述方式(现实中,在有限资源的争用问题上,“猜拳做主”并非不是一无是处,尽管这被大多数人视为儿戏……)

      既然这样,那我们就有了一个方向——通过引入随机性,而使得资源进行离散式的分配;

      现实世界中,这种方式也是有实用场景的,比如目前的《北京地区小客车摇号政策》;

      这是如何实现的呢?

      1、每一期在固定的时间段内(一般是10~50天)接收用户申请信息,并又后台来进行审核,确认申请单的有效性;

      2、固定时间(目前为双月的26日),摇号线程将在纪检监察人员的监督和公证人员的公证下,从现场摇号的申请人代表中随机抽取6人,抽取按确定的6人按顺序从左到右排列,从高位到地位随机取6个数字,生成随机种子数,产生摇号结果。

      至此,结果生成了,整个摇号的过程完全不存在流量过大的问题,因为申请单已经在几天前都收集完了。

      这样的好处有两个:

      1、分流申请流量。通过提前收取、审核的方式,将流量分摊到信息收集的窗口的每个时间片;

      2、避免某些不法人士通过非正常手段抢在队列前面。由于中签结果存在随机性,而与提交申请单的先后顺序无关,因此没有人可以提前预测结果(程序BUG除外)

      看到这里,也许有人会说,购买火车票是刚性需求,和小客车摇号完全不是一个概念。

      我有以下2个解释:

      1、小客车摇号也是刚性需求。或许在这个月买车还是下个月买车的问题上不像火车票那样紧迫,但从更高一级的层面上看,回家的方式有多种,买不到火车票可以坐飞机、长途车、搭顺风车、甚至跑几个马拉松回去,比购车只能摇号,不知道多了多少种实现的方法;

      2、如果将现实世界中的车票购买量转化为虚拟世界的订单量,通过随机方式中签的几率不比你排到前面并买到票的几率低(排队买票的时候,有没有遇到过排在第二位,发现还有两张票,正在庆幸没白等的同时,前面一位拿出几张毛爷爷一晃“两张我都要了”的情形?)

      至此,或许我们已经有了一种方案来替代现有的排队模式

      1、划定时间段,用户提交申请,并在摇号前完成审核,确认有效订单;

      2、增加摇号时的随机性,使结果更为“公平”;

    =====================华丽丽的分隔线=====================

      话题聊到这里,貌似可以进入总结陈词了,但另外一个问题冒了出来:

      如果采用提前提交申请的方式,可能导致大量黄牛多次提交申请,导致有效样本(这里指需要订票,且只提交一次申请的订单)的占比急剧下降,而大量脏样本(形如黄牛订单,一人提交多个,或利用他人身份信息订票但实际不乘车)在随机算法的应用下,获得更多的中签几率,这就公平么?

      当然,上面所说的通过随机方法摇号生成中签结果的过程,只是在理想状态下实现的(有效样本即为总样本),在现实中,上面问题提到的情况是必然存在的。因此,如何审核并辨识有效订单就成为这个问题的关键;

      在此,由于个人知识层面远没有涉及这么广泛,因此不敢妄断,但我要说的是:在排队模式中,脏样本就不会存在了么?如果脏样本都排在队列的前面(现实中,在春运期间,一张车票放出来往往几秒钟就被抢购了,这其中被黄牛拿到的几率有多大,大家想想就知道了),那就是所谓的公平么?

      总结:采用随机方法确定中签订单的方法,在虚拟世界这种大样本量的环境中,比队列模式更能体现公平,而与此同时,还对分散流量有很大的帮助;

      而这种方法也适用于各种抢购、秒杀场景(现实中,抢购、秒杀的商业意义远大于其趣味性);

      以上仅代表个人观点,欢迎拍砖~

  • 相关阅读:
    [BJOI2019] 光线
    C# 从零开始写 SharpDx 应用 笔刷
    BAT 脚本判断当前系统是 x86 还是 x64 系统
    BAT 脚本判断当前系统是 x86 还是 x64 系统
    win2d 通过 CanvasActiveLayer 画出透明度和裁剪
    win2d 通过 CanvasActiveLayer 画出透明度和裁剪
    PowerShell 拿到显卡信息
    PowerShell 拿到显卡信息
    win10 uwp 如何使用DataTemplate
    win10 uwp 如何使用DataTemplate
  • 原文地址:https://www.cnblogs.com/diabloxl/p/4451361.html
Copyright © 2011-2022 走看看