专訪阿里陶辉:大规模分布式系统、高性能server设计经验分享

http://www.csdn.net/article/2014-06-27/2820432



摘要:先后就职于在国内知名的互联网公司,眼下在阿里云弹性计算部门做架构设计与核心模块代码的编写,主要负责云server管理系统和存储系统的优化。陶辉就大规模分布式系统、高性能server设计分享了自己的看法。

关注陶辉非常长时间,初次对陶辉的了解还是在我们CSDN的博客上,从2007年開始写博客,一直到如今,假设不是对技术的追求和热爱,以及热爱分享的精神,我想不是非常多人能坚持下来,拥有多年大型互联网公司的从业经验,对linux下的高性能server开发、大规模分布式系统的设计有着丰富经验,对企业的Nginx\开发Nginx模块也有着独到的理解。


免费订阅“CSDN云计算”微信公众号,实时掌握第一手云中消息!

CSDN作为国内最专业的云计算服务平台,提供云计算、大数据、虚拟化、数据中心、OpenStack、CloudStack、Hadoop、Spark、机器学习、智能算法等相关云计算观点,云计算技术,云计算平台,云计算实践,云计算产业资讯等服务。


Nginx是一个高性能的 HTTP 和反向代理server, Nginx 是由俄罗斯人 Igor Sysoev 为 Rambler.ru 开发的,其将源码以类BSD许可证的形式公布,因它的稳定性、丰富的功能集、演示样例配置文件和低系统资源的消耗而闻名。在谈到Nginx未来会代替Apache时,陶辉表示云与端的时代,端越来越多,云的性能就会越来越重要,server资源的效率在企业成本上将占领越发重要的地位,从这个角度来说,Apache的市场份额被Nginx代替的趋势是不会变的。这次,笔者有幸联系到陶辉,他就大型软件的开发,云计算等分享了自己的经验心得。

陶辉

毕业于西安交通大学计算机科学与技术专业,先后工作于华为、腾讯、思科、阿里巴巴等公司。

对linux下的高性能server开发、大规模分布式系统的设计有着丰富经验。著有《深入理解Nginx:模块开发与架构解析》一书。

CSDN:给大家介绍一下您及眼下从事的工作?

陶辉:我眼下在阿里云 弹性计算部门做架构设计与核心模块代码的编写,主要负责云server管理系统和存储系统的优化。大家在阿里云上购买的ECSserver就是弹性计算部门的产品。

CSDN:是什么缘由促使您写了一本关于Nginx的书籍?

陶辉:大约2010年在思科工作时须要开发一个云文档系统,当时选用了Nginx作为web容器开发一个有较高性能诉求的文件上传下载服务。

但是发现非常难从网上找到系统的资料能够指导Nginx模块的开发,对于Nginx的设计思路也是一头雾水,仅仅好看它的源码来倒推作者的初衷与模块设计思路。那个过程对于已有多年server开发经验的我来说也是痛苦的,于是就開始陆续写了一些Nginx模块开发的文章分享到CSDN上,希望能够帮助其它开发人员高速解决这个问题。这时机械工业出版社的编辑lisa看到这些文章找到了我,希望我能写一本系统的、从开发人员角度介绍Nginx的书。这本书诞生的缘由就在这里。

CSDN:眼下国内知名的互联网公司非常多都在使用Nginx,您认为企业在使用Nginx\开发Nginx模块的过程中须要注意什么?

陶辉:仅当须要并发处理万级别或以上的TCP连接时,才应当考虑Nginx。

当官方Nginx无法满足项目需求,在开发你的个性化模块之前,先看一看大量的Nginx第三方模块里,有没有能够解决这个问题的Nginx模块,不要反复开发轮子,尤其Nginx轮子的开发难度还不低。Nginx.conf里能够玩的花样非常多(这由每个Nginx模块决定,如ngx_lua这种模块还能够在里面插入lua语法),也许一段几十行的配置就能完毕复杂的功能。

假设确实没有满足需求的模块,那么,再看看能不能通过相似subrequest这种机制将问题分解为多个子问题,当中多数子问题能够由现成的模块完毕,或者通过proxy机制来与其它现成的组件通过tcp协议交互完毕。组合这些子问题来构成解是个好习惯。

若真有必要编写Nginx模块,先要确保它仅仅是解决一个非常纯粹、简单的子问题,不要耦合太多的需求。Nginx进程里是拒绝不论什么堵塞操作的,这是由于模块都执行在IO核心处理线程中的。不论什么一个边缘化的模块都可能由于自己小小的堵塞调用毁掉Nginx的高性能。所以,谨慎的考虑模块中的每个调用,确认它们不会导致进程进入sleep状态,确认它们不会在那里空转占用系统资源。好好使用Nginx定时器事件、共享内存,往往能解掉上述问题。

写模块时,使用好Nginx的变量机制,让自己的模块插上http框架的翅膀,依据框架解析出的变量来做灵活的处理。甚至,提供一些新的变量作为底层模块而给上层模块使用。

使用好nginx.conf,通过灵活的配置来提供丰富的功能。

debug级别的error.log日志非常详尽,仅有它就能够定位出非常多你的模块bug,别忘了使用它必须在编译时添加--with-debug。

最后,假设模块可能对其它人有帮助,那么,分享它吧。

CSDN:对于正在学习Nginx的同学有什么建议?对开源软件的学习有没有什么分享的?

陶辉:事实上《深入理解Nginx》这本书的文件夹,就是我推荐的学习路径。

首先,从最外面看Nginx是什么样的,了解进程模型、配置文件语法、基本功能等。

其次,从尝试编写最简单的http模块入手,渐渐地使用到Nginx Http框架的一些高级特性,了解Nginx的内存池、各数据结构的使用方法等;

再次,系统的了解Nginx框架,包含它怎样启动、怎样停止、怎样升级、怎样重载配置,多进程间怎样负载均衡,http连接的建立、URL与包头的收取、解析、选用哪些http模块处理请求、怎样向client回响应等。

这样学习Nginx,大家就能够清晰得了解异步事件框架,理解松耦合设计与web请求的处理方式。

学习其它开源软件也能够仿照这一过程。

CSDN:我知道你在思科、腾讯等企业工作过,关于大规模分布式系统、高性能server设计上有没有什么经验、心得和大家分享一下?

陶辉:使用高级语言、中间件来开发较大型软件时,一定先有一个评估标准:这样玩性能不是问题。这里的潜台词是把性能当做了基础货币。比如,使用python代替C进行程序开发所牺牲的性能C1,与其带来的其它优点C2相比,必须C1<C2。所以,性能事实上是一个永恒的话题。以下零散的谈谈我对性能的理解。

单组件的性能提升上,算法最重要。特别是越前沿的技术、场景,通用算法的功效距离期望值就越远,开发人员这时要能够正确的分析不同的算法在各种情况下的执行时间,基于你的数据特性设计个性化的算法以提升性能,PS,这里最终能够用到大学里学过的如概念论这种数学技巧了。同一时候,仔细的梳理业务,能够并行处理的绝对不要串行化,谨慎加锁,提高吞吐量。

对于组件依赖的其它系统,也须要深刻理解怎样使用它,才干最大化硬件效率。比如操作系统,假设组件使用多线程去抢占有限的CPU资源,就必须评估进程间切换的代价,这往往是性能大杀器;了解不同的设备间的訪问速度(如SSD硬盘、内存等),将高速设备放在慢速设备前作为缓存;使用TCP作为通讯协议时,既要了解理论也要了解实现,包含演变过程,在实践中才干高效的使用、改进它;降低内存等资源的频繁使用,考虑内存池及怎样避免大块内存拷贝;提高缓存的命中率,如coding时应当考虑变量是否经常落到CPU CACHE中,及代码分支预測的命中率等等。

事实上性能“高”也是相对的,须要从开发效率和执行效率上权衡。协程是一个非常好的方向,通过创建协程栈来伪造线程开发环境提升开发效率,通过改变底层堵塞API的实现来提升吞吐量、执行效率。比如linux上的ucontext、nginx的lua模块,这里最大的问题还是堵塞API的协程化改造。

团队的技术积累、业务特点都对开发效率有不同的要求,架构上的scalability也是重要约束,能够通过水平扩展线性地提升性能时,就能够通过牺牲单组件性能来提升开发效率了。

分布式系统的ACP是一个权衡问题,适当的牺牲一致性是常见解决方式。scalability是一个重要属性,而这个属性会带来请求串行化的场景,经常使用zookeeper这类系统来提供可靠的锁服务。有了scalability常会导致系统引入缓存服务:组件的主存不可缓存了。缓存也有非常多种成熟的解决方式,如memcached、redis等。

开发大型系统时组件间的高内聚松耦合非常重要,否则代码非常快就难以维护,有一种解耦方式比較受青睐:使用如rabbitmq等服务来提供异步消息订阅通知机制。

多个会落地的数据服务可能会引入“事务”,而分布式事务解决起来是比較头疼的,paxos两段式提交经常是首选,事务的回滚、清理、残留未完毕事务的回滚等都是须要考虑的事项,能够借鉴关系数据库的undo、redo等事务解决方式。

CSDN:是否能谈谈Nginx眼下还有哪些不足?还有哪些地方有待完好?

陶辉:我们对Nginx的期望一直在提高:早期仅仅把它用做静态web与反向代理,渐渐地希望它能够处理动态请求。这样,在Nginx进程内部添加功能就越来越重要。

怎样添加动态请求的处理呢?最方便的是使用一些抽象了经常使用动态功能的模块,这些模块以nginx.conf中的配置来定义web请求的动态处理流程。然而,非常多时候这些模块模块仅仅能处理大众化的需求,这样程序猿们仅仅好挽起袖子直接编写C代码了。

但是,nginx模块的开发门槛还挺高,须要开发人员对于server的非堵塞调用、事件模型有较深的理解,而假设请求处理时须要有全局化视角时,麻烦的多进程通信又来了,开发人员不能使用简单的堆分配对象,而要使用nginx_slab管理内存。

因此,除了期待很多其它的开发人员贡献出多样的抽象模块,眼下nginx最应该完好的应当是二次开发的易用性--能够更方便、高速的开发出高性能的nginx模块。比如,nginx的框架能够考虑支持多线程模型,能够考虑支持ucontext协程方式,使开发时不用考虑API的异步回调,不用考虑锁的满足条件。

CSDN:Nginx市场份额一直稳步提升,您认为Nginx未来会代替Apache吗?

陶辉:在云与端的时代,端越来越多,云的性能就会越来越重要;而互联网思维本就不高富帅,同一时候会服务全部草根用户,而用户体验也须要提升,所以,server资源的效率在企业成本上将占领越发重要的地位。从这个角度来说,Apache的市场份额被Nginx代替的趋势是不会变的。

CSDN:是否能谈谈对眼下国内云计算市场有什么看法?有哪些趋势值得去关注?

陶辉:云市场发展開始加速,云服务提供商将開始在国计民生中扮演愈发重要的角色,社会基础服务将会进入公有云中,从而对云服务的可靠性安全性有了非常高的要求。比方,早期公有云一个技术人员眼中的小bug,这时就非常可能会对社会生活造成严重影响。如阿里云这种主流公有云服务提供商必须承担起社会使命,宛如水、电、空气一样不能中断、不能出错地提供服务。服务质量越来越重要。

还有一方面,由于云服务提供商通过规模效应能够提供更便宜的服务,所以企业、个人都在将自己的服务上云,这又在推动着主流云商必须思考怎样以更低的成本提供服务。所以,云商必须深入到基础设施中,把原先的通用性设备改造成适合云的专有设备,以此提高效率;必须提升原先不适合为云服务的管理系统,以满足不间断服务的要求。比如,云商将须要自己运维网络,须要与硬件厂商合作,设计适合特定场景的网卡、CPU、内存等,软硬结合着在底层添加效率,降低企业成本。



posted on 2014-10-11 16:43  gcczhongduan  阅读(420)  评论(0编辑  收藏  举报