标签:复杂度 数据中心 epp 图片 down 修复bug linked 手动 大量
坦白说也是机缘巧合,在硕士生阶段进入分布式系统领域学习。无论是大规模存储或计算,其核心也是运用分布式技术利用并行性来解决数据密集型应用的需求。最近开始在啃这本《Designing Data-Intensive Applications》大部头,作者Martin Kleppmann在分布式数据系统领域有着很深的功底,并在这本书中完整的梳理各类纷繁复杂设计背后的技术逻辑,不同架构之间的妥协与超越,很值得开发人员与架构设计者阅读。
很可惜的是国内目前并没有对应的中文版本,这个系列算是一个读书感悟,同时也夹带私货,阐述一些自己的理解与看法,抛砖引玉,希望大家多交流学习。这本书共有12个章节,接下来我会一个章节更新一篇读书笔记。(囧rz,感觉自己又开了一个坑)同时也希望国内的出版社可以尽快引入版权,我也想要参与翻译工作啊(,,? ? ?,,) !!
作为一个开发者来说,目前绝大多数应用程序都是数据密集型的,而不是计算密集型的。CPU的计算能力不再成为这些应用程序的限制因素,而更加亟待解决的问题是海量的数据、数据结构之间的复杂性,应用的性能。
先看看我们经常打交道的数据系统:
而很多时候,我们所谓应用程序的绝大工作就是将这些数据系统进行组合,然后添加我们的运行逻辑,但是如何更加合理的整合这些数据系统,对我们来说仍然是一个值得学习和思考的问题。而数据系统也在慢慢变得越来越相似,不同的数据系统也在各自学习彼此的优点。如Redis这样的缓存系统可以支持数据落地,很多时候的应用场合我们可以替代传统的RDBMS。而Kafka这样的数据队列也可以支持数据落地来存储消息。更加深刻的理解这些数据系统,来更好的权衡架构设计,是一门很精深的课题。
上图是一个典型的由多种数据系统构成的应用程序,随着数据量和数据逻辑的复杂,就成为了一个数据密集型的应用。
显然,这三个原则不单单是数据密集型应用应当遵循的原则,在绝大多数软件系统中同样是很重要的问题,接下来我们一一梳理一下。
硬件故障
硬盘崩溃,内存出现故障时,电网停电,有人拔了网线,几乎硬件故障在数据中心总是不间断的出现。
解决方案:
人为的错误
人是很不可靠,从驾驶技术的演变就可以看出来,人为的疏失会带来巨大的灾难。而且,人经常犯错。
解决方案:
人们犯最多错误的地方和那些可能导致失败的地方解耦。
全面测试,从单元测试到整个系统集成测试和手动测试。
允许快速和容易地从人为错误中恢复,以尽量减少在失败的情况下的影响。例如,使其快速回滚更改配置,逐步推出新的代码(所以任何意想不到的错误只影响一小部分用户),并提供工具来重新计算数据(如果原来旧的计算是不正确的)。
即使一个系统今天工作可靠,但这并不意味着它将来一定会可靠地工作。一个常见原因是负载增加:也许系统已经从10000个并发用户发展到100000个并发用户,或者从100万个增加到1000万个。
“如果系统以特定的方式增长,我们应对增长的选择是什么?” “我们怎样才能增加计算资源来处理额外的负载?”
缓存的命中率
描述性能
一旦描述了系统上的负载,就可以讨论负载增加时发生的情况。可以从两方面看:
1.增加负载参数并保持系统资源(CPU、内存、网络带宽等)不变时,系统的性能如何受到影响?
2.当增加负载时,如果希望保持性能不变,需要增加多少资源?
所以我们需要有描述性能的尺子:
负载情况与性能情况是很重要的,有时系统的瓶颈是由少数极端情况引起的。作者举了一个Twitter的例子,我觉得很好,这里详细分享一下这个例子:
Twitter在2012年11月16日公布的数据。
Twitter的两个主要操作是:
Twitter在扩展性的挑战主要不是由于Tweet的数量,而主要是在每个用户都有很多订阅者,每个用户也有很多关注者。执行这两种操作大致是两种方法:
java SELECT tweets.*, users.* FROM tweets JOIN users ON tweets.sender_id = users.id JOIN follows ON follows.followee_id = users.id WHERE follows.follower_id = current_user
如上图所示的结构显然更合适Tweet的发布,因为发布的Tweet的写操作几乎比读的操作低两个数量级,所以在这种情况下,最好是在写时做更多的工作,而不是在读时做更多的工作。但是方法2并不适用于有大量关注者的账号,假设某人有3000W粉丝,一次发布Tweet产生的写操作可能是巨大的。所以目前在Twitter的Tweet系统中,Twitter将这两种方法混合。大多数用户的推文在发布时仍然会被扩展到Tweet缓存之中,但只有少数用户拥有大量的关注者(即名人)。用户可以跟踪的任何名人的Tweet,并单独读取并与用户的Tweet缓存中进行合并。这种混合方法能够始终如一地提供良好的性能。
(这个例子很精炼的描述了架构设计的妥协与精妙,依据业务特点,最大化的优化了数据系统的性能。很佩服Twitter的工程师在架构设计上的功力。同时也很好奇如微博,微信是不是也是采用类似的架构进行设计。)
这部分教导了一些构建可维护系统的方法。软件的大部分成本不是在最初的开发中,而是在持续的维护中修复bug、保持系统运行、使其适应新业务、添加新特性。
可操作性
让操作运维团队保持系统运行的顺利。
简单
让新工程师很容易理解系统,通过尽可能地从系统中删除尽可能多的复杂性。
可进化性
让工程师很容易在将来对系统进行更改,以适应需求变化时的意料之外的用例。也被称为可扩展性、可修改性、可塑性。
(维护别人留下的烂摊子真的是很痛苦的事情,文档,注释真的是重中之重!!!)
可靠的、可扩展的、可维护的数据系统 ------《Designing Data-Intensive Applications》读书笔记1
标签:复杂度 数据中心 epp 图片 down 修复bug linked 手动 大量
原文地址:http://www.cnblogs.com/happenlee/p/7998429.html