设计数据密集型应用 (DDIA) 读书笔记(1)

682 阅读6分钟

前言

最近在看 设计数据密集型应用 这本书,刚好加的一个技术读书群正在进行这本书的读书活动,于是参加了读书活动,我目前个人进度是读到第七章左右,预计大概一周左右能读完,加的群这周布置下来的任务是读完第一章和第二章且每章写不少于200字的笔记,刚好能作为我复盘 DDIA 这本书的动机,想了下刚好发到掘金专栏里,一方面作为任务,另一方面作为内容分享。

CH1:可靠性 可拓展性 可维护性

章节描述

这章主要是对 "数据密集型应用" 这个概念的描述,一个好的大型应用应该拥有可靠性 可拓展性 可维护性这三个特征,其实不只是大型应用,我个人认为任何一个有职业精神的程序员应该保证自己设计的应用能保证这三个特征。接下来我将结合书里的内容复盘下这三个小节的内容。

可靠性

可靠性主要描述的是应用服务的可靠,即可用的时间,我最近同时在看的 google SRE book 也提到了google 的SRE 团队有 SLO 和 SLA 的指标,即服务在某种程度上要保证一定程度的可用性,用户的体验可以降级,但是服务不能不可用。书中描述的导致可靠性问题的主要因素有三点 ①硬件故障 ②软件故障 ③人为故障 前面两个故障分别可以通过硬件冗余切换、版本回滚来解决,第三个故障只能通过管理方式来解决。所以说一个运维良好的系统最大的不稳定因素还是人,SRE 那本书里也提到过,通过开发对应的软件和脚本来减少人肉运维所带来的副作用,和本节内容所阐述的简直一模一样。

可拓展性

可拓展性这一节主要分为两个部分,前面部分提到的是如何描述和观察负载,另外一个部分则是提到怎么应对负载。观察和描述负载这部分提到了两个关键的概念:描述负载和描述性能。在我之前的工作中,这两者往往都是混合起来作为评估服务器状态的:PV QPS和服务器硬件占用都是作为观测服务器状态的指标之一。但是本书把这部分拆分了。PV和QPS这些其实准确来说是负载,即某个主机或者实例承载了多少的请求,并不能作为评估服务器全部性能指标的标准,一台实例的请求和访问可能很多,但是硬件占用并不一定会很高,同理,一台服务器的硬件状况可能会根据服务类型的不同而出现各种高占用,但是他的请求量不一定高,这两者要分别观测才能得出正确的评价,从而进行拓展。而拓展的话则存在两个概念:水平与垂直拓展,这个名称听起来有点像数据库表拆分的水平和垂直拆分,但是明显不一样,服务器的水平拓展主要是通过添加新的设备部署服务进行负载均衡,从而减轻其他服务器的压力,垂直拓展则是通过提升服务器配置,从而使服务器可以应对更多的请求。这里又得提到 SRE 那本书里提到的概念:即性能两倍的硬件的成本可能会远远大于两倍硬件的成本,这个概念在商业领域非常普遍也很容易理解,双倍性能的硬件可以承担的任务比单一硬件的要多许多,所以很多方案都不推荐进行垂直拓展,因为垂直拓展逃离不开摩尔定律的约束,一味的拓展硬件其实等于饮鸩止渴,在到达硬件性能之前必须得转换为水平拓展。

可维护性

可维护性这个部分主要说的还是运维和开发层面的内容,比如代码的结构应该简单,解耦明确,运维的内容应该可操作(个人觉得应该是可以通过UI界面进行配置和运维)在此就不多赘述了,其实我觉得开发人员可以看看代码整洁之道,讲的更加详细一些。

CH2 数据模型与查询语言

章节描述

第二章分为两个部分讨论了数据模型和查询语言,数据模型部分提到了关系型数据库(RDB)和非关系型数据库,而查询语言部分提到了SQL map reduce(MR)与图查询数据库等,查询语言部分的内容我只关注了比较感兴趣的Cypher(用于n4j的查询)。第二章的内容非常有意思,分别记录下。

数据模型

数据模型部分讨论了下上世纪数据库领域对于关系型和非关系型的讨论,作者提到,关系型数据库更适合数据结构标准化、需要范围化和连表查询的场景,而非关系型数据库更适合一对多的查询和存储,至于多对多查询存储则更适合图类型数据库,关系型和非关系型数据库不存在孰优孰劣的说法,只能说哪个更适合业务场景,在我看来,这个类似于静态类型和动态类型语言的选择问题,关系型数据库类似于静态语言,有固定的规范和格式,灵活性相对差一些,所以在存储复杂数据结构的时候会出现非常多额外的表结构设计,但是带来的优势也是非常明显的:(单机层面上)高效的聚合查询和连接查询,以及减轻了代码层面的心智负担(不会出现结构格式不一致的数据),而非关系型数据库的优势非常明显,单个文档可以存储多个数据,数据结构可以随时改变,这样也就保证了在单体查询时候的高效性,非关系型数据库在查询的时候可能需要多次连表或者多次查询的操作,非关系型数据库可能一次查询便能满足需求。

查询语言

书里主要讨论了命令式和声明式的查询语言,命令式的特点就是通过逻辑代码来进行查询和数据处理,而声名式类似于HTML 通过声明数据的查询方式来查询数据,其中特别提到了map reduce的方式进行数据查询,其实从定义上来看,map reduce属于命令式查询的一种,毫无疑问 声命式查询的方式更加方便于查询已有数据,但是声明式在数据处理上可能不如命令式的方便。 作者在这个部分提到了 n4j 的 cypher ,n4j 算是图数据存储的一个典型例子了,通过图数据库可以更好的存储数据之间的关系,也可以很方便的查询不同类型的节点之间的关联。