关于大规模互联网系统开发运维和组织管理的总结(2016-11)

支 持 本 站: 捐赠服务器等运维费用,需要您的支持!

通过某次交流,把自己对大型互联网系统设计开发运维以及部门管理时的实践思路简单总结一下。
为了保密这里不涉及具体的项目名,硬件,OS,语言,软件和数据库选型,
另外每个项目的团队经验和企业业务逻辑千变万化,所以也只从一些抽象的概念上进行小结。

在互联网产业工作了近20年,尤其是从2000年起一直在这个网站工作,
公司规模以工程师人数来说,从当时只有三十多名发展到现在的二三千名,
以startup的心态加入公司,当时实在是没想到会发展到如此的规模。
另外访问量也从每天的几千万PV到几十亿PV,加上API以及各种静态资源,
虽然没有具体的统计数字,但是每天上百亿的访问肯定是有的。
自己也从devops开始做起,到多项目的架构设计,
以及项目和部门的宏观管理,还是能感到业务经验和知识的成长的。

自己的想法可以从下面几个轴来考虑
--信息安全,软件工程,构架,团队建设,宏观管理。

一是信息安全的三要素CIA,机密性Confidentiality,完整性Integrity,可用性Availability,
别管系统的规模有多大,用户数有多少,技术多么先进,
有安全性隐患的东西谁都不敢用的,
因此信息安全的这三点是系统设计和业务设计最基本的原则。

这么多年来,经历过DoS攻击,ATP攻击,
内部人员盗窃客户数据,设计不当的大规模当机等大事件,
因此对安全性的感受颇深。

信息安全工作具体包括:
通过软硬件的访问控制设计使所需信息只能由最少的人能接触到;
通过加密使重要数据不会泄漏和盗取;
通过对平均故障恢复时间MTTR,单一故障点等主要KPI持续收集并不断评价;
通过建立信息安全事件管理体制和预备计划,这样在Incident发生时就不会手足无措;
通过风险管理不断找出系统和业务中的不确定性要素,并不断加以改进;
通过建立CSIRT和Security Operation Center组织不断收集对内对外系统的脆弱性信息,并不断升级等等。

ISO 27001的ISMS信息安全管理系统对此有个比较概括的定义,
信息系统安全认证专家CISSP里面有更多的实践性的描述。
参加过ISMS和CISSP的培训,觉得里面的总结还是非常全面的,
(公司不断提供这种外部培训, 花了都有100万日元了吧)
因此在工作中会有意识地应用这些原则。

二是软件工程Software Engineering的一些基本原则的贯彻。
自己在大学里学习的是电子工程,不是计算机科学,因此对于算法等领域不精通,
在工作中往往需要这方面的专家来解决问题,
比如以前(2008年到2010年的一个项目)曾和美国方面的科学家们建立机器学习的模型。
但是作为工程师,如何把模型真正的反映到系统里去,理论联系实践,
既需要一般计算机系统的开发,
更需要不断调试参数,不断更新扩大字典和知识库的过程。

因此作为工程人员,在有限的人力物力资源情况下,
为了完成经营者要求的业务目标和日程表,
需求管理,架构设计,工程进度和人员资源管理,开发流程和规范制定,
质量管理,维护管理等实践性知识和经验就非常重要。
当然长远的规划,方向性技术选型,配合经营方针对组织结构的调整,
这些也都是软件工程中的重要内容。

最近的项目里,
使用灵活的Scrum敏捷开发项目管理;
使用面向对象的软件设计和系统设计;
使用Restful的WebAPI和SOA对功能进行服务化和解耦;
使用CI/CD把以往需要手工做的版本管理/测试/编译/链接/部署等一系列工作自动化;
这些都已经成为理所当然的选择。



支 持 本 站: 捐赠服务器等运维费用,需要您的支持!

第三是关于系统架构,因为是网站,最一开始IDC数据中心的问题要解决。
当然中小型网站,使用亚马逊/谷歌/微软/百度/阿里提供的云服务是最省事的方法,
但是这里的前提是大规模网站,如果用云服务也不是不可以,
从经济性来说还是自己搭网站比较划算吧。
因此数据中心选择时,安全性,有线电视监视系统,可扩展性,
365天24小时的故障对应体制,发电设备,UPS电池的老化管理等等都成为考虑因素。

十几年前的话晚上有系统故障,如果又不能远程登录上服务器,
即使半夜三四点钟也只好打车到数据中心,接上键盘显示器拿console做维护;
有时还要自己去把有问题的服务器从机柜搬出并换上备用机器;
现在好多了,有VPN也有了搞IDC的子公司,很多问题即使相隔几百公里,一个电话就可以解决。

从商业计划中预测的用户数/访问量/交易量等算出几年后需要的网络带宽,
因此可以购买合适的路由器,负载平衡,交换机,防火墙等设备。
网络出口当然很重要,但是往往系统内部的流量要远远大于外部,
比如前台/多层分布式业务层/缓存/分布式数据库/监控/数据分析/内部业务系统工具等子系统之间的通信量极其巨大,
用于内部的网络设备的带宽绝对不能忽视。

BCP也是需要的,尤其是在地震多发的日本地区,
在北部/中部/南部建立多个IDC也成为当前的常识。
colo之间的网络延迟确实是个问题,这只能通过调整业务流程,
毕竟异步处理和数据一致性是很难两全的。
另外根据物理位置路由到相关的colo,
尽可能减少跨IDC通信,做到"服务的本地化"也是提高处理速度的重要原则。

接下来是软件构架。
子系统之间的stateless原则早在90年代初就已经由Roy Fielding提出来并用于http的设计。
REST(Representational State Transfer)的概念很多人不了解其详细,
其实可以说这就是一个面向全球网络级规模系统的设计规范。
我在公司写WebAPI开发规范,七八年前给工程师们做SOA和REST讲座的时候,
由于其内容太枯燥感觉一半人都睡着了。
但是REST中无状态,缓存,面向资源,分层系统,统一接口以及多种方式资源的表现形式
等基本原则还是比较容易被应用于实际设计工作的。

现如今已经进入移动设备时代,为了开发手机应用APP,
工程人员和企划人员对于产品"接口服务化"的认知度比起以往已经大大提高,
回想起十年多前在公司内推广时的艰辛,有恍如隔世之感。

edge层或者网关层对于系统安全性的意义自然很重要,
OAuth用户认证,TLS,路由,日志,缓存,访问控制等功能都可以由这一层来负责。
(在大约2007年的时候就在公司里提出WebAPI Gateway的构想,
但是因为工作调动没有能把这个项目彻底推动下去,
今天夏天看到亚马逊在AWS上推出了同名的服务,
看起来他们也是注意到了同样的需求)
Circuit-breaker断路器,Fail-fast,Retry,Throttling流控等技术术语最近经常看到,
我在08年的一个项目就实现了类似的功能,并和两个部下一起还申请了专利,
不过确实人家起的名字就是很酷。

CDN对于静态内容传输起到的高性能和可扩展性作用也是极其明显的,这也是常识性知识了。

为了解决C10K问题,开发应用时也要注重对于系统资源的利用和tuning,
比如调整OS和服务器软件(如apache, mysql等)中网络/内存/handler/缓冲/文件句柄的大小,
在经验中即使是如apache1.x这种prefork+阻塞模式下也能很好的运作。
利用epoll/kqueue/libevent/nodejs的libev的多路复用技术已经非常成熟,
但非阻塞I/O模式下不考虑运维时对系统资源的监控也是不可想象的。

对于大规模系统来说,功能复杂,开发人员总多,
通过对"业务分层"把复杂的计算分开到专用层中,
能够得到提高开发效率,对资源(CPU/存储)有效分散后资源争夺的瓶颈即会自然消解,
这一实践也是从2000年就已经开始。
有时业务需要增加一些集中式状态管理数据用来解决一致性问题,
但是很多情况下一致性问题并不会成为Web系统的瓶颈,
用户很难感觉到这种短时间内的数据同步延迟。
至少自己负责的项目里,弱最终一致性的系统相对比较多。

对于大量数据,通过按照用户维度分区sharding(shared nothing architecture)把数据分割,
在水平方向上可以做到无限拆分,高弹性伸缩的这种手法现在已经成为常识。
自己从2000年起在一些项目里就已经采用这种方法来搭建系统。
用户数不会无限制增长,一般来说分拆数也是可以预测的,
因此动态分区的需求不会太高,虽然以前也用过动态hash环的做过实验,
但是在实际系统中并没有用上。

即使使用了分布式NoSQL数据库,在一些业务需求下为了提高响应时间,
能够做到带状态带数据的分布式系统成为必须条件,
分层分区后每个子系统就变成一个矩阵的一个单元。
对数据访问的路径明确,所需要的数据可以通过最短路径得到,
这样的系统非常理想,但是运维可能会比较麻烦,
数据的备份和复制如果能够以非常透明的方式实现,
那么系统部署就会非常容易。
自己以前做过的项目中还使用的是手工操作管理,
支付宝单元化的智能方式还差的比较远。
如果有非常清晰PaaS和IaaS的分层业务支持的话,
负责应用层开发的工程师就可以专注于产品业务逻辑,
开发和部署的速度都会大大改善,从这点上还是挺羡慕支付宝的平台的。

知道命令查询职责分离模式CQRS(Command Query Responsibility Segregation)这个词还是最近,
虽然从2000年起我们就使用这个方法做到NoSQL数据库的读写分离,
通过异步消息队列达到避免资源竞争。
CAP和BASE原则这些名词也是很久之后才知道的,
但是使用事件模式,使用消息模式的实践这么多年来起就没有停止过。

分布式事务的状态管理有时需要引进一个集中式管理机制,这在上面也提到过了。
另外这种模式对于failover也很有帮助,数据复制非常容易实现。
还有大数据分析时通过消息队列/消息总线可以很容易传输到hadoop一类的平台上。

软件开发的方向应该就是不断的抽象化,不断的自动化,
通过高级语言,面向对象设计,面向对象编程,UML,服务化(IaaS, PaaS, BaaS, SaaS, FaaS...), 云计算, CI/CD, 容器化,微服务等一系列技术演化,
今后DevOps工程师的工作可能会更趋向于建模和自动部署配置, 最终走上NoOps的方向,
像我们以往学习OS kernel的内部运作,大量UNIX命令和选项,读apache等服务器开源软件源程序等需求会越来越少吧。

摩尔定律据说还要10年就会失效,
因此我们近几十年来借硬件飞速升级得到的免费红利会逐渐消失,
不深入考虑CPU/内存/IO也能做出大规模系统的好日子也许不会再来。
今后充分发挥计算机科学和软件工程的力量,
对算法和并行计算模式研究的重要性会逐渐显现出来。

第四是关于团队建设的问题,
高水平团队成员需要一个能够自我管理,自我发展,以及能够开放交流沟通的氛围。
从最近参加的组织发展(Organization Development,OD)培训里学到的干预技术也很有帮助。

从管理者的角度来说,这个open的团队氛围最为重要,
大家注重协调,自由发言,对事不对人,不搞官僚主义,
不用担心有不同意见后的挑拨是非,
不用担心秋后算账的危险,让团队中所有人都拥有安心和安全感,
而不仅仅是一两个嗓门大的人总在发言。

具体到实践上,包括
更关注人的优点,不带偏见,不带有色眼镜,宽容;
不浮躁,关注细节;
不急于得到结论,更关注课题的本质;
为了不迷失目标定期检查和再定位,因为把手段当做目的来追求的错误在周围经常能够看到;
重视执行力,反对华而不实的喊口号;
不盲目迷信流行技术,对新技术通过不断学习、测试和实践的过程逐步掌握其特征特点,也就是尝试错误法(trial and error);
关心对商业需求深刻的理解;
等等,
总之踏实,诚实,务实,适应性等特征都是自己追求的方向。

作为管理者,通过与成员的定期1on1,了解双方的思路,得到各种反馈的过程十分重要。
同时也要遵重个人性格和习惯的多样性,具有包容力。
当然管理者绝不只是做个老好人,凡事和稀泥,做好好先生,
毕竟明确的原则性是最基本的管理要求,需要做到有赏有罚。
一个只可意会,无法言传的规章制度(技术选型时就是明确的指标定义和整体业务需求的平衡)是无法让人心服口服的。
只要团队成员适应习惯了这种管理手法,并且在实践中做出了成绩,
接下来就可以权力下放,疑人不用,用人不疑,使之充分发挥自身的独立性,向自我管理自我提高的方向发展。

关于沟通和协作关系,工程师队伍以外的stakeholder也非常重要,
这里面包括了公司内部的企业经营者,产品和项目负责人,业务开发,市场人员,客服,媒体宣传人员,法律专家,
也包括企业外部的合作伙伴。
真正理解公司的战略目标,通过良好的互动和业绩,
与各方建立起良好的信任关系,这是保证项目顺利的最基本条件之一。

做为技术团队的代表,
需要不使用专业术语,通过逻辑性的说明,
让没有技术背景的各方也能理解技术部门所需要的资源和进程;
对于来自各方商业方面的需求,应能够通过系统分析,
完成可行性评估,资源评估,项目规划,风险评估等一系列顾问咨询业务。

作为一个不擅长言辞,没有八面玲珑的政治手腕的工程师,
不愿意参加到派系政治里,只希望与所有人建立良好合作关系但又保持适当距离,
持续保持诚恳,谦虚,踏实,低调的工作作风。


第五,总结一下自己参与过的关于部门(某事业部)管理业务的内容,
具体包括:
人员计划--根据中长期的业务计划对人力资源不足的项目和部署补充新生力量;
人事--目标管理,业绩考核,OJT培训,1on1,考勤管理,个人成长计划,管理手法培训,新管理人员培养;
财务管理--预算和预算执行情况管理,包括人员计划,软硬件等设备投资,购买书籍资料,培训费用,外包项目计划,出差费用,工资奖金计划,行业性组织会费,饮食交际费等;
部门管理--部门愿景,组织构成,风险管理,安全性管理,ISMS认证,合作伙伴的合同管理,多项目的优先级管理;
部门会议运营等--安全卫生健康消防管理,部门经营会议,定期会,年会;
等等。

号称是管理,其实杂活非常多,但是没办法,
公司发展到一定规模,法律中也有很多章程规定,
这些工作总得需要人干,虽然自己并不很擅长。
好在部门里有各方面的专业人员,做好宏观管理也就是了。

团结一致,集体的力量等词汇好像很老生常谈,
但现在深深体会到一个人的力量是有限的,
能在优秀的部下的支持下一起工作,
做出成绩时的成就感真是非常幸福!!

最后列举一下不足,也是今后的改进方向,如何提高自己还是一个长期的课题。。。
-非计算机专业出身,关于算法和网络等基础比较薄弱
-没有java/go/swift/ruby/python 等语言的开发经验,以前做程序员是用的是C/C++/Shell/VB为主
-比较内向,不喜欢抛头露面,参加演讲,研讨会等面向外部的活动
-不善言辞,不善察言观色,不是八面玲珑,跟各种人打好交道的性格
-现在很多新技术不断涌现,自己缺乏实际使用经验,感到有些跟踪不过来
-不擅长快速决策,更愿意花时间仔细考虑,所以有时会犹豫不决
-思考模式有时可能会比较僵硬,比起年轻人缺乏灵活性
-有时会偏向保守,所以会担心影响年轻人的积极性,比如新技术,新构架,新设计的采用等
-对用户体验,UI,UX等缺乏了解
-对于商业模式,服务企划的经验不多
-英语水平一般,听说能力有待提高。
-还不成熟的高并发的工作方式。经常有大大小小十几个项目在同时进行,如何分配好资源和优先级,不让一些项目被阻塞,还需要继续实践

能把自己这十几年的工作做个总结,理顺些思路,还是很感谢这次交流机会的。

支 持 本 站: 捐赠服务器等运维费用,需要您的支持!

发布时间: