《开餐馆与做软件》续——关于架构的辩论

《开餐馆与做软件》续——关于架构的辩论

Chandler: 
     其实软件架构没有所谓对错之分,只有是不是适合之分,其实架构的本质就是分层,但是凡是都有代价,分层必然有通讯的成本(当然也有好处,比如降低耦合,提高扩展等),有时候,站在不同的角度,就会有不同的结论:性能,扩展性,可用性,易用性,安全性,一个架构不可能满足所有的要求,关键在于我们的取舍,另外,就是如何更好的适应不同变化,这和我们作软件设计时的道理是一样的。另外,其实产品的架构还要受很多非技术层面的影响,比如公司的策略,管理的要求,现实的开发约束,甚至是公司决策者的喜好,另外,关于分布式大规模软件的架构,有很多因素要考虑,比如集群,高可用,高性能等,其实我个人比较欣赏的是类似ebay的架构,应用层水平和垂直的拆分,应用层无状态,数据库水平和垂直切分。

Dreamcode:
    Chandler 非常感谢你的回复,你的架构应考虑管理的因素给我很大启发,受益匪浅,架构设计可以是多样的原则必须坚持,但是一些表面现象会让我们动摇。大型网络架构往往表现出短板效应,当访问量较少时,短板在系统本身的内耗如模块间的通讯,数据的存取等,此时我们可以通过减少通讯,数据缓存等方法,但是一旦现实的访问量很大时,这时短板在处理访问请求的能力,我们知道很多黑客就是通过制造大量访问请求来导致目标主机崩溃的,因此我们必须通过拆分的方式,首先保证系统稳定性,当其中一个模块崩溃时,系统其他部分可以继续运作,当崩溃模块得到修复可以快速的与系统衔接,而不需重启整个系统,同时通过水平扩展服务器,分表,分库等方法,提高处理访问请求的能力。找到那块短板是提高系统性能的关键,或者说产品开发是由“实在”的问题和需求驱动的,而非先进的方法或理念。我曾提到架构设计的五个阶段,这五个阶段由简单到复杂正是由问题来驱动的,并不是说最后一个阶段的方法是最好的,而是因为当餐馆发展到那个阶段我们必须做这样的改造,那么我们真的到了那个阶段遇到了那个阶段所面临的问题了吗,还是这只是我们的理想。

Chandler: 
     关于软件架构的进化,其实有很多软件架构的进化经验可供我们参考,比如说EBay的例子,也就像您说的餐馆的例子。我的看法是,首先,我们了解别人的经验是有意义的,因为那是宝贵的财富,可以帮我们少跑很多弯路,但是那不是说我们可以跳过其中的所有步骤直接到达最终步骤, 因为一是那是别人的经验,不见得适合我们,因为软件界没有银弹,我们不可能冀望某些技术能解决我们所有的问题。二是我们会丧失自己进化的经验,在我看来,成长过程的经验教训永远比直接拿来的结论要更重要。另外,我觉得,现实永远是我们首先考虑的问题,比如说“百万级”的概念,如你所说,我们的服务器必然是一台一台增长的,如果只强调远期的理想,有可能近期目标(比如成本)达不到。不过,如果我们在设计架构时不以其为目标,那么当Scale增加到如此规模的时候,我们所要面对的问题需要很大代价去克服,甚至会导致软件的重新Design。总而言之,不同的时期其侧重点可能是不一样的,所以,软件的架构就要考虑到这些问题,并且提供方法适应这些变化,所以,这个进化的过程我觉得不可避免。不过,毕竟现实还是最重要解决的问题,所以我们还是要解决现实问题,不过,对于即将发生的事情我们要做好准备。“格局决定结局,态度决定高度”,放到软件架构上我觉得也有道理。

欢迎大家加入我们的讨论!


《开餐馆与做软件》原文:

上学的时候曾有冲动想开一家餐馆,还买了本很厚的书,书名就叫《如何开一家餐馆》。后来阴差阳错做起了软件,最近装修房子这股冲动又来了,翻箱倒柜找出这本书看着看着却觉得这竟是一本传授如何做好大型网站的一本难得的武功秘笈。

一家餐管从小做大可以分如下几步,这个餐馆在变大的同时能容纳的顾客也越来越多,餐管的效率也越来越快。

首先,白手起家开一家餐馆手头自然不富裕,租不起大的店面,这时候厨房和餐厅挤在一个屋子里,一个厨师兼伙计。由于我们的菜口味独特吸引了大量的顾客,高峰的时候顾客只能排队等候,这时候我们的第一个想法就是扩大一点店面把厨房先挪出来同时再另聘一名伙计。即我们进入网站性能提升的第一步—— 应用与 数据库 分离,将网站的应用部分(相当于餐厅及伙计)与数据库(相当于厨房及厨师)分开部署在不同的服务器里,避免硬件资源的争夺。

这个时候店面扩大了,顾客不用再排队等候了,都可以进入餐厅。厨房和餐厅面积的扩大可以让厨师和伙计将平时常用的工具从柜子里取出来放在明面上,以备随时取用,这样干活效率明显提升了。即我们进入网站性能提升的第二步——数据缓存(包含页面、页面片段缓存),将常用数据从数据库中取出来,放到内存中,提高访问速度,减少数据库连接。

效率提高了,口碑也更好,自然顾客越来越多。由于我们人手有限,致使很多顾客需求(如点餐,买单等等)不得不等候一段时间,于是我们决定增加厨师和伙计,来处理更多的顾客请求。即我们进入网站性能提升的第三步——水平扩展“应用服务器”和“数据库服务器(即数据库集群或分库)”,通过增加应用服务器和数据库服务器,分担更多的应用及数据请求,为了让访问平均分配到多台应用服务器上需要负载均衡工具支持。

随着顾客的进一步增多,一个很现实的问题产生了,为了应对更多的顾客我们购买了大量的餐具等其他必备物品,原先由于数量不多这些物品都是由厨师和伙计随意取用,物品存储非常混乱,由于空间有限大家进进出出也很拥挤,因此这些物品的取用占用了大家很多时间,最终我们决定将这些物品进一步归类,分别存储,并由专人负责存取这些物品,同时加开新的窗口,物品的存和取在不同窗口进行。即我们进入网站性能提升的第四步——分表、建立数据访问层(DAL)与数据读写分离,一般MySQL中最快的存储引擎MyISAM,它是基于表锁定的,就是说如果一锁定的话,那么整个数据文件外部都无法访问,必须等前一个操作完成后,才能接收下一个操作,因此我们可以将较大的数据表进一步分解,即通过分表的方式,减少阻塞来提高数据库访问效率,分表造成一些应用不得不考虑分表规则,数据库访问程序的复杂度提高了,可以通过建立统一的数据访问层(DAL)来统一处理这些分表规则。使用数据读写分离技术,将数据读写在不同的数据库服务器进行,这需要一个程序级的同步方案支持,同时要对前面提到的DAL 层进行改造。

如同一家餐馆规模足够大而成为一家餐饮集团,原先的小饭馆的管理方法显然行不通,这时候我们需要按照职能进行划分,如建立独立的财务部门,对于简单应用这种独立的部门可能反而会使效率降低,但是对于复杂应用这种划分无论是对效率还是稳定性都是很有必要的,即我们进入网站性能提升的第五步——大型分布式应用。其实架构的本质就是分层,但是分层后一个很明显的需求就是高效稳定的通信框架,这个架构如何设计好是我们面对的一个问题。

本文的灵感来自《程序员》2008年11月刊的《大型网站架构和知识体系》一文,本文提出的方法也源于此文,此文还提出了这些方法的实现技术,有兴趣的朋友可以找来看一下。

©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页