1.前面的情况提醒了这篇文章。继续说之前亿级流量架构的演进。本系列前几篇文章更新了可扩展架构的设计。老规矩!我们先来看看这个复杂的系统架构演进到现在这个阶段,整体的架构图是什么样子的。下面我们就来说说在核心系统每天承载百亿级流量的背景下,如何保证复杂系统的数据一致性?2、什么是数据一致性?简单来说,在一个复杂的系统中,有些数据必须处理得非常复杂,它可能是很多不同的子系统,甚至是多个服务。将一条数据按照一定的顺序进行复杂的业务逻辑执行,最终可能会产生有价值的系统核心数据,并存储在存储器中,例如数据库中。给大家一张手绘彩图,感受一下现场气氛:从上图可以看出,多个系统是如何依次处理一个数据,最终得到一个核心数据,落地到存储中去.那么在这个过程中,可能会出现所谓的数据不一致问题。这意味着什么?给大家举个最简单的例子,我们原本预计的数据变化过程是:数据1->数据2->数据3->数据4,那么最后登陆数据库的应该是数据4吧?结果呢?不知道为什么,经过上面这个复杂的分布式系统中的各个子系统,或者各个服务的协同处理,最终产生了一个数据87。搞了半天,做了个跟数据4无关的东西,终于登陆数据库了。然后,该系统的最终用户可能已经通过前端界面看到了莫名其妙的数据87。这很尴尬。用户会明显感觉到数据有误,会反馈给公司客服。这个时候就会把bug报告给工程组,大家开始找问题。上面提到的场景其实就是数据不一致的问题,也是我们接下来几篇要讨论的问题。事实上,任何大型分布式系统都存在类似的问题。无论是电商、O2O,还是本文举例的数据平台系统,都是一样的。3、梳理一个数据计算环节问题弄清楚了,我们再来看看数据平台系统。哪些问题可能导致最终存储的数据出现异常?要理解这个问题,我们先回顾一下。前面提到的数据平台项目中,最终数据的计算环节是什么?看下图:如上图所示,其实从最简单的角度来看,这个数据计算的环节大概和上面一样。首先通过MySQLbinlog采集中间件获取数据,转发到数据访问层。然后,数据访问层会将原始数据放入kv存储中。然后,实时计算平台会从kv存储中提取数据进行计算。最后将计算结果写入数据库+缓存集群。数据查询平台会从数据库+缓存集群中提取数据。为用户提供查询看起来很简单吧?但即便是这套系统,数据计算环节也绝对没有那么简单。如果你看过之前的系列文章,你应该知道这个系统引入了大量复杂的机制来支持高并发、高可用、高性能等场景。所以实际上,一段原始数据进入系统,直到最后落地到存储中。计算环节还会包含以下内容:接入层的限流处理实时计算层的故障和实时计算层本地内存存储的重试。降级机制数据分片的聚合和计算。单条数据可能进入数据分片中数据查询层的多级缓存机制。以上只是随便列举的几个。然而,即便是以上几项,也会让一个数据计算环节复杂很多倍。4、数据计算环节的BUG现在大家明白了,在一个复杂的系统中,一个核心数据可能要经过极其复杂的计算环节处理,中间有几百圈,任何可能的情况都会发生。那么我们就可以理解在大型分布式系统中数据不一致的问题是如何产生的。其实原因很简单。说白了就是数据计算环节的bug。也就是说,在数据计算的过程中,某个子系统出现了bug,没有按照我们预期的行为去处理,导致最终输出的数据出现错误。那么,数据计算环节为什么会出现这种BUG呢?原因很简单。如果你参与过一个上百人的大型分布式系统,或者领导过一个上百人开发的大型分布式系统的架构设计,你应该对核心数据的异常和错误非常熟悉,你会觉得头痛不已。在大型分布式系统中,动辄数百人协作开发。很有可能是某个子系统或者某个服务的负责人对数据处理逻辑理解错误,在代码中写了一个隐藏的bug。而且这个bug不会轻易触发,也没有在QA测试环境中测试过。结果,系统上线了一颗定时炸弹。最终这个bug是在一个特殊的线上场景下触发的,导致最终的数据出现问题。5、电商库存数据的不一致性接触过电商的同学可能很快就会在脑海中联想到一个类似的经典场景:电商中的库存。在一个大型电子商务系统中,库存数据绝对是核心中的核心。但实际上,在分布式系统中,很多系统可能会使用一定的逻辑来更新库存。这可能会导致类似于上述场景的问题,即多个系统更新库存,但某个系统的库存更新存在错误。这可能是因为该系统的负责人不了解如何更新库存,或者他在更新时采用的逻辑没有考虑到一些特殊情况。这样做的结果是系统中的库存与仓库中的实际库存不匹配。但是就是不知道是哪个环节出了问题,导致库存数据出现了问题。这其实就是典型的数据不一致问题。6.大规模系统中数据不一致的排查有多难当面对大规模分布式系统时,如果你之前从来没有考虑过数据不一致的问题,那么我敢打赌,当你负责的系统被报错时通过在线客服,当某个核心数据不一致时,你肯定会一头雾水。因为一个核心数据的处理,少则涉及多个系统的协同处理,多则涉及十多个系统的协同处理。如果不留任何日志,或者只有一些日志,那基本上大家就只能互相盯着看,盯着自己的代码看。大家根据一个数据最后的错误结果,比如数据87。10多个人面对自己的代码,反复思考,苦思冥想。然后大家就在脑子里疯狂的模拟着自己代码的运行,就是想不通为什么本该是数据4,结果却是一个数据87?所以真正的问题是这个。这种数据不一致的问题大概有以下几个痛点:我基本上无法提前主动感知数据问题,只能被动等待用户发现并反馈给客服。这很可能会引起很多关于您的产品的投诉,老板很生气,后果很严重。就算客服告诉你数据有误,但你无法还原现场,没有留下任何证据,基本就是一群工程师在代码上想象和猜测。就算你解决了一次数据不一致的问题,以后可能还有一次。再这样下去,队里好几个能干的家伙,都要花在这种狗屎上了。
