- 可靠性
硬件故障
一块硬盘可以使用40-50年,10000块磁盘的系统每天至少有一块磁盘故障(50 * 365 在10000的量级上)
注:数字有两个作用,第一是对硬件故障率有一个初步感知,第二是设计系统时默认边界是硬件故障是常态。
软件错误
避免方法:仔细考虑实现细节、描述清楚系统设计场景(约束)、系统间交互、测试(单测、集成测试等)、监控系统行为。
人为失误
避免方案:以最小出错方式设计系统、分离易出错模块、充分测试、恢复机制、完善的监控系统、好的团队建设。
注:好的团队建设对于项目及团队发展直观重要,博主遇到过比较好的新人学习计划包括:如新人串讲、线上问题处理、小功能开发、小模块开发、RPC框架分享、分布式基础理论学习、小功能开发等等。
- 可扩展性
比较有意义的描述扩展性:如果系统以某种方式增长,我们应对增长的措施有哪些,如果增加计算资源满足额外的负载(针对具体增加的负载进行考虑,数据量?访问量?计算量?)
描述负载
原文中引入了“扇出”的概念,简单说就是一个用户请求进来,可能需要多个请求完成;
原文中引用tweet例子,一个tweet用户可以关注多个其他用户,每个用户能看到他关注用户的消息(一个用户的消息需要“扇出给多个用户”)
方案1:每个用户的消息都发送到一个数据池里,然后关注者来读取;
方案2:每个用户发送一个消息之后即刻同送给每个关注者的消息队列中;
注:方案1 缺点是多个用户读一个数据池会成为瓶颈,然后汇聚多个被关注者的数据(时间线)计算也是耗时的。方案2 解决了方案1的问题,但是针对大V(关注者较多百万、千万级别),一个大V发送数据需要推送的太多,推送成为瓶颈,并这百万千万的关注者大部分不是活跃用户,方案1更适合大V。
抽象一下更像是消息队列的推模式与拉模式,使用上还是要考虑应用场景。
描述性能
平均响应时间、长尾、分为统计、QPS、SLA等。
原文中区分了延迟和响应时间的概念,可以粗略的理解前者是server端耗时、后者是client端耗时(统计都是有意义的要看具体问题需要哪个数据)。
- 可维护性
可运维性
简单性
复杂性包括:状态空间膨胀、模块紧耦合、相互依赖关系繁琐、命名不规范、为了性能或者特殊场景的设计等等。
注:有经验、能力的开发者可以很好的抽象 并 预防上述问题的发生,而不是出一个问题解决一个问题(俗称“一坨堆一坨”)。
可演化性
- 感想
本书第一章内容比较抽象,没有一定经验的工程师很难有深刻的体会,将原文中较为重点的内容摘录了一下供后续回忆。在日常的工作中可靠性中提及的硬件故障、软件错误、人为失误等因素都会被重视,在系统设计阶段都被充分考虑进来。扩展性亦是如此,因为互联网的特点之一就是增速快、流量大、数据量大。
可运维性在一定程度上被忽视,因为它不容易在“领导”面前表现出来,不是所谓高附加值的工作,恰恰相反运维性卓越的系统可以大大加快研发、线上问题处理效率,让工程师有更多的时间做所谓高附加值的工作。在解决业务需求的情况下,设计出小而美的系统需要具备很好地抽象和实践能力,小而美的系统可以大大的减低复杂度减少运维成本且具备良好的可演化性。