一个资深程序员看12306(四)

     在写这篇文章的时候,想到我一仁兄很经典的话:“有时候用户只是说一句话,问一个问题,你就得写一篇文章来回应,甚至还不行。”我十分赞赏这句话,也佩服这位仁兄在处理用户需求的时候表现出的耐性和魄力。现在,我们继续上一篇的文章给定的标题的时候,发现我在这个标题上,也正在走这条路,并且已经走了很远了。

       本篇我又集中于平台上了,那么这篇,我尝试从下面几点举例来说明一下一个平台架构的复杂度。还是事先声明哦,本篇和12306依然没有半毛钱关系,只是分析平台而已。

一、          我对平台的定义。

这里我不想用技术性语言来表述,打算给其一个通俗的定义。

平台:即持续投入超过千万,开发周期在一年到两年,甚至两到三年,维护周期在两到三年。

做一个官网网站,考虑一天的访问量在20万左右,那根本就不需要平台,只需要架设一个网站服务器,设计好数据库的表结构以及优化好存储过程就行了,甚至于连集群和负载都不用考虑,开发周期估计2个月左右也就差不多了,这和平台差着十万八千里呢。有些人看到这里,可能开始咋舌了,这样的话,有多少家的公司才能支撑呀?很对,平台真不是一般中小公司能支撑的起来的,他们耗不起,甚至很多公司,连一个真正意义上的系统架构师都养活不了,还何谈平台?原因很简单,虽都是开发类公司,但行业不同,目标不同,目的也不同。有些仅是做网站的,有些只是致力于为客户开发软件,然后全套交付给客户的,有的是做服务运营商的,他们对于软件成型的标准显然是不同的。因此,很多公司的员工,可能在某一公司干了很多年了,属于一个公司的元老级人物,核心人物了,在公司内说话也是相当权威的,甚至在他们那个领域,那是他说了算的,但他们可能对平台依然没有概念,甚至于也没有接触过系统架构师。那当然也难以站在架构的角度考虑问题了。但你不能因为他没有平台或者架构概念或者这方面的经验,就认为他技术不行。

二、          哪些是架构师要考虑的。

要想基本阐明这个问题,我想我最好还是举例说明:

用户告诉你一个需求:我想要一个文件传输功能,即能把文件从A用户发送到B用户;你会怎么考虑?

可能有人会说:那还不简单,两个客户端,使用TCP长连接,A向B发起请求,B接受请求,然后A开始读文件,每读一包就发送一包,直到B接受了整个文件,无非就是几个消息而已,有毛思考的。如果用户确实仅仅需要这么一个功能,当然用不到架构师了,一个初级程序员就能很好的解决。这也要用一个架构师来考虑的话,那只会使事情复杂化,这时候的架构师就是个屁。这样的需求,根本就不应该到架构师那里去。但是,如果这个用户需求最后真传到了架构师手里,那就不应是简单的一个需求了。现在该如何考虑这个问题呢?

首先,这是在广域网传输还是在局域网传输得考虑,到了架构师这里,对于这个需求,那肯定是广域网传输了。

其次:用什么网络传输协议,要回答这个问题,就要实先确认使用对象、使用频率、带宽以及用户传输文件的大小 和需求者对这些文件的管控意愿。

在这些基本问题的牵引下,我们会想到,要想在广域网传输,就要考虑双方都处在各自处在一个不同的局域网内,他们和外网的交互是要通过一道甚至多道防火墙的,这样的话,文件传输就需要穿透这些防火墙,那我们的网络传输协议就需要考虑使用UDP,因为TCP很难或者不可能穿透这些防火墙,而UDP的穿透性就非常好(即通常所说的打洞),因此,我们自然会想到了P2P。到此,问题思考了将近五分之一了。

          接着:P2P传输也不能保证一定能打洞成功呀,比如说A用户在一个公司内,B用户也在一个公司内,两个公司都可以上外网,但公司会为了确保网络安全和网络带宽资源高效利用,会把连接广域网的局域网设置的比较复杂,还会有公司网管进行监控管理,这样的话。P2P成功的几率就比较低了。因此,我们需要为解决这个问题而部署一套文件传输服务器。也即A用户和B用户通过文件传输服务器来进行文件传输。因为几乎所有广域网下的用户,都可以访问外部指定的服务器,而不会主动让外部连接主动找到你。

          再接着:想到了文件传输服务器,那我们就得考虑文件传输服务器相关的内容了。如网络传输协议,这里我们会优先考虑TCP连接了。既然是服务器,免不了考虑假设很多人都要借助这个服务器来传输文件的情况,那链路个数你得控制,因为不是链路个数越多,效率就越好,效率的好坏,和带宽,单包文件传输字节数、线程个数等有直接关联的。那我们就要考虑这个用户愿意投入多大的钱来支撑带宽量了。有意愿的朋友可以这么算一下或者网上查一下,2兆带宽和4M带宽的差价,他们是倍数级关系甚至还要大,那么假如说根据用户需求,我们算出需要200M的带宽,这个价格可能就已经到了百万级别了。那用户会为了一个文件传输服务器每年耗费近百万么?所以,基于这个问题,我们得想法节省带宽,那必然要减少单包传输字节数,或者控制并发传送文件数量,那就会在效率上存在一个互为矛盾的问题。那么架构师得根据经验或者一些实际数据来找到一个最为高效的折中方案。至于要不要考虑服务器冗余备份及备份方案;很多用户传相同的文件的验证问题(这问题又涉及到文件MD5校验和秒传的问题);文件服务器磁盘空间问题;用户文件保存时限问题等等这些必须考虑的问题,这里暂且不述了。

最后:综合了上面的思考之后,架构师得出具一个架构文档,给出每个节点模块的要求,接口,网络传输协议封装方案等等。这一切都齐了之后,还得回头来从新思考一下,在现有前提下,客户端使用哪种语言开发,服务器又使用哪种语言开发,操作系统选用哪个,给出大概的时间节点,然后把这个架构给到技术总监或者部门经理手中,技术总监或者部门经理根据拿到的东西,如何安排人手和时间,保证每个里程碑节点,那不是架构师的事情了。

至此,架构师才基本完成了一个文件传输功能的思考,而这对架构师来说,如果是给予一个平台,这只能算是一个相当相当小的模块。一个平台的复杂度。也就基本能想到了。

              说到这里,我想起一个曾经的同事的话:你看架构师多*,一个月下来,在公司呆的时间几乎不到一周,还从公司每月拿走那么那么高的工资,也没人敢记他的迟到早退。或许他根部不了解,一个架构师,为了一个平台,经常要在无人打扰的情况下思考多久,才能确保一个平台尽可能少的出现问题。而很多时候,他连个商量的人都没有,因为有多少公司,能同时样几个如此级别的人物呢?所以他得慎之又慎,考虑在考虑。要知道一旦平台存在重大缺陷。那依托于该平台的所有东西都难以进行,他承受的压力又有多少人能理解?而一旦一个平台成功了,在某个专业领域内,可以依托这个平台*的驰骋。

三、          平台的核心内容之一:分布式数据存储

只说上面那些东东,很多人还难以考虑到平台的复杂度,所以,还得从一个问题的角度,分析一下一个平台必然会遇到的处理问题:分布式数据存储。还好,这个在CSDN上有了一篇相当不错的文章了,我暂且引用一部分,这篇文章名字为《深入解析:分布式系统的事务处理经典问题及模型》我引用并修改一下如下片段:

用一台服务器来提供数据服务的时候,经常会遇到如下的两个问题:

1、一台服务器的性能不足以提供足够的能力服务于所有网络请求。

2、担心服务器宕机,造成服务不可用或是数据丢失。

面对问题,我们必须对服务器进行扩展,以及解决单点故障问题。通常,我们会通过两种手段来扩展我们的数据服务:

1、  数据分区:就是把数据分块放在不同的服务器上(如:uid % 16,一致性哈希等)。

2、  数据镜像:让所有的服务器数据同步,提供无差别的数据服务。

第一种方案,单台服务器出问题时,定会有部分数据丢失。所以,数据服务的高可用性只能通过第二种方法来完成——数据的冗余存储(一般工业界认为比较安全的备份数应该是3份,如:HadoopDynamo)。 但加入的机器越多数据就会变得越复杂,尤其是跨服务器的事务处理,也就是跨服务器的数据一致性。我们用最经典的Use Case“A帐号向B帐号汇钱来说明一下,熟悉RDBMS事务的都知道从帐号A到帐号B需要6个操作:

1.   A帐号中把余额读出来;

2.   A帐号做减法操作;

3.   把结果写回A帐号中;

4.   B帐号中把余额读出来;

5.   B帐号做加法操作;

6.    把结果写回B帐号中。

为了数据的一致性,这6件事,要么都成功做完,要么都不成功,而且这个操作的过程中,对AB帐号的其它访问必需锁死,所谓锁死就是要排除其它的读写操作,不然会有脏数据问题,这就是事务。但是,在加入了多个机器后,这个事情会变得复杂起来:

1.   在数据分区的方案中:如果A帐号和B帐号的数据不在同一台服务器上怎么办?我们需要一个跨机器的事务处理。也就是说,如果A的扣钱成功了,但B的加钱不成功,我们还要把A的操作给回滚回去。在不同的机器上实现,就会比较复杂。

2.   在数据镜像的方案中:A帐号和B帐号间的汇款是可以在一台机器上完成的,但是别忘了我们有多台机器存在A帐号和B帐号的副本。如果对A帐号的汇钱有两个并发操作(要汇给BC),这两个操作发生在不同的两台服务器上怎么办?也就是说,在数据镜像中,在不同的服务器上对同一个数据的写操作怎么保证其一致性,保证数据不冲突?

同时,还有性能因素,如不考虑性能,事务完成并不困难,系统慢一点就行了。除了考虑性能外,我们还要考虑可用性,也就是说,一台机器没了,数据不丢失,服务可由别的机器继续提供。 于是,我们需要重点考虑下面的这么几个情况:

·        容灾:数据不丢、结点的Failover

·        数据的一致性:事务处理

·        性能:吞吐量  响应时间

前面说过,要解决数据不丢,只能通过数据冗余的方法,即数据副本:当出现某个节点的数据丢失时可以从副本读到,数据副本是分布式系统解决数据丢失异常的唯一手段。简单说来:

         要想让数据有高可用性,就得写多份数据。

         写多份的问题会导致数据一致性的问题。

·        数据一致性的问题又会引发性能问题

这就是软件开发,按下了葫芦起了瓢,当然,文章也给出了解决方案,我这里就不引用了,因为平台也是有大小的,一个千万级资金的平台,解决方案和一个上亿级资金的平台解决方案是有相当的不同的。因为每个方案的背后,都离不开资金和成本的支持。


一个资深程序员看12306(四)

上一篇:Photoshop制作浪漫非主流情侣照片


下一篇:Illustrator(AI) 基础知识:颜色面板的使用技巧介绍