• Feeds

  • Archive for the ‘架构’ Category


    微观架构及宏观架构

    大部分工程师包括架构师都是从微观架构起步的。微观架构指在一个局部的领域达到设计及实现的合理性,比如写一个排序的程序,达到时间空间复杂性的合理性,同时在代码的易读性、扩展性及可维护性方面也达到一个合理的标准。但一个系统中不仅只是存在微观问题,宏观架构指一个更高层级的,全局领域的策略及架构设计,通过架构来最终达到对产品或系统在效率、成本上的收益。当系统变大之后,宏观架构的问题更突出,也更能取得收益。比如在一个互联网Web应用中,从微观角度来看,cache命中率自然越高越好,从设计上尽量让访问落在内存上。但是从宏观角度,只要SLA能得到保证,比如让70%的最近数据(可能只占1%容量)能够通过cache访问,而30%长尾数据(可能需要占用99%容量)是通过存储返回,整体开销可能会下降一个数量级,而整体性能也基本有没有大的变化。

    Coding出身的工程师刚脱离微观问题的时候,可能会觉得不习惯。微观的问题容易看到成效,比如将一个程序的QPS性能提升了30%,这是一个容易度量的成绩,而宏观架构看起来很“虚”,也不容易快速产生成效,比如将一个大型传统的系统改造成一个SOA的架构。辛苦花力气改造完成,也不容易看到及度量成效,而且一些隐性的收益需要更长时间才能体现。

    尽管如此,微观架构及宏观架构如同战略及战术一样,是相辅相成的。而且双方都有其重要性,无法判断一个比另外一个重要。微观方面,一个平庸工程师组成的团队,即使一个优秀的架构师从天而降,短期内也无法改变团队的成绩。同样如果技术领导只关注宏观层面问题,忽视代码细节及基本功培养,团队的产品始终难尽人满意。由于宏观架构的设计者通常在组织中拥有更大的话语权,如果对微观的问题缺少一个基本的理解,对微观的出现的矛盾不能做出正确的判断,系统的开发效率及运行效率都会出现问题。宏观方面,一群优秀的工程师,如果能聚集到一个优秀设计架构的平台上,肯定如虎添翼。在一个团队中,宏观架构及微观架构的人员需要达到一个合理的比例。

    以下是以前思考的一些断言,你判断是这些是宏观还是微观架构?

    • The C10k problem refers to the problem of optimising server software to handle a large number of clients at the same time (hence the name C10k – concurrent ten thousand connections). The problem of web server optimisation has been studied because a number of factors must be considered to allow a web server to support many clients. This can involve a combination of operating system constraints and web server software limitations.
    • The goal of SPDY is to reduce web page load time. This is achieved by prioritizing and multiplexing the transfer of web page subresources so that only one connection per client is required. Transmission headers are gzip-or DEFLATE-compressed by design. Moreover, servers may hint or even push content instead of awaiting individual requests for each resource of a web page. SPDY可以用作HTTP RPC一个高效替代
    • 普通硬盘的访问延时是SSD的5-500倍
    • 使用event方式事件模型的编程模型可以极大降低线程之间context switch的开销
    • Code review is systematic examination of computer source code. It is intended to find and fix mistakes overlooked in the initial development phase.
    • 在大型系统中,模块之间组合的架构可以看出整体架构的优良及团队效率
    • 移动app方向,未来一段时间仍然主要以产品模式及运营方向主导,技术驱动领域主要集中在快速迭代能力
    • 虽然大数据是以后的一个发展趋势,但是数据挖掘的大部分场景还只是浅层次的应用,系统瓶颈不在挖掘能力,而是在应用能力上

    案例与故障的知识库

    一个团队内部经常有很多针对不同场景的设计方案,同时技术系统在历史上出现的各种问题故障可能也会在事后记录下来,但是这些记录及文档通常并没有一个好的归属,随着时间的推移就淹没在邮件的海洋中。如果知识库具备,这里简单探讨一下相关作用。

    团队中新人未经历过系统所有阶段,不能有历史的阅历。即使是老的员工,如果团队规模变大,或者是精力的原因,也不可兼顾到系统中所有的信息,因此设计案例及故障案例对一个团队共享经验及共同能力的提高都具有极大的帮助。

    看书是一种最佳的学习方式,但是在互联网工程领域,很多经验及成果并无公开的书籍及文档描述,因此很多有志于在此领域提升的新人经常会碰到困惑,如果当前不在一个成熟的互联网公司,根本没有机会来提升自己。另外一方面,即使能进入这些环境,新人也会碰到另外一些问题,公司内的牛人忙忙碌碌,已经完成的伟大作品也很少被详细介绍,新人只能在日常零星的工作中逐渐去了解全貌,很难得到一个快速成长的机会。

    这对老人也是一个启示,大家热衷于解决的新场景的问题并非最大的价值所在,新领域问题无非是根据个人经验,走了一条不那么弯的路而已。但是总结已有的典型设计加以抽象总结,形成一些系统性的设计库,或者将所有的故障及走过的弯路分门别类,形成故障库,这对于提升一个较大团队的整体能力,具有更重要的意义。

    说了知识库的需求,也许有人会顾虑知识库的技术领域差异性,技术人员对专业细分领域之外的问题不感兴趣现象比较普遍。前端的对后端的案例分析不感兴趣,数据库工程师对开发领域的问题不感兴趣。因此需要案例材料尽量跳出具体的语言细节本身。但是技术人员如果能够跳出自身的认知圈子,从更宏观的视野来讨论及分析这些问题,对于综合能力的提高具有更大的帮助,这也是走向架构师方向的一个基本要求。

    对于设计案例,理想的知识库需要有系统的分类,而且大部分新设计的功能都可以在其中找到一个对应的历史案例,虽然很少有两个系统完全一样,但是真正设计思想的区别并不会大。

    随着案例知识库的完善,案例的讨论的深入,一个团队的技术能力得到了整体提高及升华。

    微信架构的启示

    腾讯大讲堂中最近分享了周颢演讲的微信技术总监解读微信架构的秘密,看完视频的一些心得。

    技术微创新

    微信的技术设计上有很多微创新,看起来都很小,但是对于系统的稳定性、用户体验及开发敏捷都具有重要作用。

    前轻后重
    由于客户端升级不便,从技术设计上尽量利用后端的设计来减少依赖客户端升级的方法。如某个版本新增了群聊功能,按常规思路,需要所有客户端升级才能全部打通。微信采用服务器兼容的方法,在老客户端不升级情况下让其增加群聊的功能,通过在服务端将群聊协议转换成之前旧版兼容的协议返回给老的客户端。

    客户端辅助设计
    微信客户端做了很多非常规的功能,比如常规的客户端测速方法是登录阶段轮询测试多个IP来选择服务器,这样会带来流量及登录速度双方面的开销,因此微信选择的方法是服务端返回最佳的IP(可能是通过历史数据分析)。客户端另外实现了一些容灾能力的配合,当一个IDC访问出现异常自动选择另外一个IDC。

    流量控制
    由于大部分无线用户对流量非常敏感,为了防止由于客户端不可预知的bug如死循环导致“偷流量”,服务端增加用户流量实时分析的方法,可以在海量数据下找出流量异常的用户,并给这些用户强制下行终止连接信号。

    基础研发的策略

    从视频介绍来看,微信的基础研发与业务结合非常紧密,提到的有基础组件比如Client/Server框架,从原理上看类似Twitter Finagle,框架封装了大容量网络通讯及远程调用所需各种功能。此外介绍的一些监控与统计框架也较为先进,可以随时增加监控指标。

    大量可复用的基础组件让业务开发非常敏捷,周颢总结的基础研发策略是“实现已有经验的固化”。这和其他一些公司中的基础研发团队思路有所区别。业界中基础研发脱离生产闭门造车的情况并不罕见,一方面业务部门重复低层次开发现象严重,另外一方面基础研发对业务理解欠缺,开发的组件模块与业务结合不紧密,无法被有效利用。因此类似微信这样增强业务团队的力量,在开发业务同时总结抽象更多的基础组件或许是一种更为实用的发展思路。

    腾讯海量课程

    视频中多次提到腾讯内部的一种海量模型的培训课程,其中的经验或设计模式包括
    大系统小做
    将一个复杂的大系统分解成多个独立的、小的、简单的任务去完成,“分而治之”。

    柔性可用
    服务端系统通常不是0与1之间的选择,可以在极端情况下做一定优雅降级,在服务端代码中需要体现这些设计。

    Set模型
    类似最近讨论的cell架构,按一个服务按用户范围分成不同的小单元,每个小单元(cell/set)具备全部业务服务能力,当一个set发生故障时候,只会影响这一小部分用户。微信架构中所做的补充是,在set之间增加了容错处理,当一个set发生故障时,使用类似一致性哈希的算法,调用方可以自动切换到下一个set来存储,并且将新的位置记录在index上(类似GFS master),周颢自称是一个简化版的GFS。

    微信的协议

    里面提到了XMPP和类Sync的自定义协议,里面提到XMPP的缺点是流量大和消息不可靠。但是流量大并非XMPP主要矛盾,可以很简单将其映射成二进制协议。消息ACK也可以添加简单的扩展协议来实现。较繁琐的还是兼容CMWAP网关的设计。

    使用XMPP或者简化的XMPP标准协议有很多好处,类似的场景有业界广泛使用的open api基本都使用HTTP及JSON,并不是由于这两种协议优化或高效,而是其简洁并得到广泛的认知。一种标准协议的认知及扩展成本要比一个自定义协议小得多,XMPP流量大的问题可以通过转换协议来实现,比如用binary 1代表login等全部协商协议,2代表message,消息增量获取也可以通过自定义扩展协议来实现。标准协议可以让团队内部及新人的认知成本降低,每一个参与者都很容易想到代码及架构改进建议。而且微信目前也在构建开放平台,自定义协议在开放方面必然具备一些局限。

    其他

    分布式理论
    从微信的分享也看到,指导业界不同背景的团队(不管大小)的分布式理论主要还是Google及Amazon系列论文,对互联网技术的发展具有深远影响。微信借鉴了Quorum及Merkle tree的理论,创造了一种自定义的做法,用于实现一种分布式递增发生器。
    不过分布式递增算法其实有更简单的实现方法,twitter也有相关的公开博文,由于视频相关背景介绍比较简短,可能大家解决的需求具有差异,就不展开了。

    监控
    数千的监控项,可以在分钟发现系统的异常

    敏捷
    每天20个后台变更

    技术传承
    从视频和PPT来看,微信的技术体系是从头搭建的,可能有不少利用qqmail时代的基础代码,但与深圳团队并不存在太大技术沿袭或者传承关系。从另外一个角度也看到微信技术团队的战斗力。

    新人力量
    一位毕业生的创意:按SET分布,全量数据从2G减到200K(具体的情况待了解)
    另外一个新特性,漂流瓶及摇一摇,据说也是2个月的本科毕业生一周完成,而且上线后运行稳定。

    存储

    上图中可扩展设计中字段配置表的做法感觉略显繁琐,目前大部分NoSQL产品的schema free方式可能更易于维护。

    产品驱动

    如图,其中“允许发布十分钟前的变更”这样做法通常在大型团队通常会引起广泛质疑,单纯学习这种形式并非正解,如何在互联网产品上实现敏捷值得产品和研发进一步思考。