【转】实现大系统的小体会
2011-11-16 19:44 shy.ang 阅读(307) 评论(0) 编辑 收藏 举报http://blog.csdn.net/historyasamirror/article/details/6966672
这些体会是基于一个这样的系统:它包含有十几个大小不一的模块,这些模块分布在不同的机器上,每个请求都需要这些模块的协作才能够完成。我不是太好意思称它为大系统或者分布式系统,因为它确实还差了那么点东西。但我也相信,任何一个真正的大系统/分布式系统也是从这么一个系统开始的。
对于这样一个系统,消息通信模块,日志模块和监控模块是非常基础却至关重要的几个模块:
消息通信模块是一切的基础。为了使得所有的模块尽可能的独立和解耦合,并且能够部署到不同的机器上,你应该让他们只使用某种基于网络协议的通信机制进行交互,而抛弃诸如管道,共享内存等方式。这种情况下, 一个统一的消息通信模块非常必要:它提供统一的协议去定义服务的接口;它应该支持多语言,因为你的模块实现的语言可能各不相同;它至少要提供同步的消息通信机制,比如RPC,最好能够有异步的方式;它的性能会对整个系统有很大的影响。
所以,google有Protocol Buffer,Facebook有Thrift(严格的说,Profocol Buffer只开放了多语言之间消息交互的格式和编解码)。当一个公司的系统越做越大以后,一定会出现这样的东西。
日志模块的重要是因为这样一个系统的调试非常的困难。每个模块接口的正确并不代表整个流程的正确,而且一旦出现问题,定位到问题的发生地点也并不容易,很多时候,唯一的办法就是分析日志。这样一个日志模块应该提供:统一的日志格式,所有的语言输出的日志是一致的;日志附带的信息应该足够丰富;能够将所有机器上所有模块的日志汇总,整理(最好还能实时整理);提供良好的接口能够对日志做查询(最好也能实时)。
我所了解的大部分这样的系统都是这么实现的:每台机器有一个日志模块的agent,它收集这台机器的所有模块的日志,同时有一个日志中心,将所有机器的日志汇总(或推或拉)。模块与agent之间,agent与中心之间的交互也应该都基于消息通信模块。
监控模块除了能够了解到整个系统的运行状况以外,它也应该能够用于系统的调试。因为监控模块对于运维人员和开发人员都很重要。最近一篇很火的文章《SteveY对Amazon和Google平台的长篇大论》中提到“...直到你的监控系统能够全面性地系统地检查所有的Services和数据,此时,监控系统就跟自动化测试QA没什么两样了,所以两者完美的统一了...”,我深以为然。
而且,监控系统应该早规划早做,不要等到整个系统完成之后才开始上马,而应该在系统第一次迭代的雏形完成后就开始开发(甚至可以更早),并且随着系统的开发而不断完善。在实现每个模块的时候,都应该要考虑这个模块应该提供怎样的监控接口,输出什么样的监控信息。同样,监控系统和模块之间的交互也应该基于消息通信模块。还有一个方案就是将监控模块完全构建于日志模块之上,所有的监控信息都写入到日志,对日志的统计分析就能够得到所有的监控信息。
最后,除了这三个组件,如果系统存在着大数据量的交互,那么一个提供统一接口的分布式存储模块也很有用。GFS,BigTable已经证明了这一点。