总览
《数据密集型应用系统设计》非常好的一本书。全书分为三部分:
- 数据系统的一般原则
- 单机数据系统转向分布式系统
- 派生数据的系统
这里是第一部分。
数据系统基础原则
-
可靠性
- 容忍软硬件失效,人为错误
-
可扩展性
- 评测负载与性能,延迟百分位数,吞吐量
-
可维护性
- 可运维,简单与可演化性
第1章 可靠、可扩展、可维护的应用系统
问题来源:
当今应用都属于数据密集型(data-intensive
),而不是计算密集型(compute-intensive
)
数据应用系统常用模块:
- 数据库
- 高速缓存
- 索引
- 流式处理:持续发送消息至另一个进程
- 批处理:定期处理大量的累积数据
本书将这个些都归类于:数据系统(data system
)
Redis既可以用户数据存储,也适用于消息队列
ApacheKafka可作为消息队列,同时也具备持久化存储保证。
缓存层Memcached
全文索引服务器Elasticsearch/Solr
可靠性Reliability
简单说:即使发生某些错误,系统仍然可以正常工作。
硬件故障
添加冗余来减少系统故障率。云平台(AmazonWebServices,AWS
)强调总体灵活性与弹性,不是单台机器的可靠性,所以云服务器虚拟机实例的可靠性相对较差。
软件错误
没有什么好的解决办法。
人为错误
假定人是不可靠的来设计系统.设计接口原则:使做正确的事情很简单,使做错误的事情很难。
可扩展性Scalability
描述系统应对负载增加能力的术语。
描述负载
有一个twitter的例子很好。负载多是由系统的关键业务参数决定。
描述性能
批处理系统如Hadoop
,通常关心吞吐量throughout
。在线系统更看重响应时间responsetime
。
采用百分位数(percentiles
)描述响应时间。如中位数是50ms,则说明有50%的请求响应时间大于50ms。通常使用p95,p99,p999.亚马逊采用p999.描述、定义服务质量目标(ServiceLevelObjectives,SLO
),服务质量协议(ServiceLevelAgreements,SLA
)。
应对负载
垂直扩展:升级到更强大的机器
水平扩展:负载分布到多个更小的机器,无共享体系结构。
可维护性Maintainability
许多人不愿意维护遗留系统。
第2章 数据模型与查询语言
问题来源
数据模型可能是开发软件最重要的部分,它决定了软件的编写方式,包含业务逻辑知识。应用程序通常通过一层一层叠加数据模型来构建。每一层面临的关键问题是:如何将其用下一层来表示。
构建每一层的基本思想:每层都通过提供一个简洁的数据模型来隐藏复杂性。
这一章的内容就是数据存储和查询的通用数据模型。关系模型、文档模型、图状模型。还有数据查询语言。
关系模型与文档模型
NoSQL
:最初是为了吸引眼球创造的。现意为"不仅仅是SQL".采用NoSql的驱动因素:
- 比关系数据库更好的扩展性需求,支持超大数据集/超高写入吞吐量
- 免费/开源
- 关系模型不能很好支持的一些特定的查询操作
- 关系模型具有一些限制
混合持久化:结合关系数据库和各种非关系数据库一起使用。
对象-关系不匹配
是指业务代码与数据库模型之间可能存在的不匹配问题。
ActiveRecord,Hibernate
这样的对象-关系映射(ORM)框架减少了转换层的样板代码,但不能消除不匹配的问题。
传统SQL模型是规范化表示关系数据。之后SQL标准增加了对结构化数据/XML数据的支持。将多值数据存储在单行内,并支持在这些文档中查询和索引。例如MySQL支持JSON数据类型。
JSON的优势是JSON模型是一种“没有模式”的结构类型,能够减少阻抗失配的问题。
使用id而不是原始字符串
有很多好处,例如城市名字变更,只用更改id上值。id对人类没有任何直接意义,所以永远不需要改变。任何对人类有意义的东西都可能在将来某个时刻发生变更。
文档模型处理多对一的数据关系很弱
模型演化
- 层次模型。类似JSON模型。不能支持多对一,不支持联结查询。
- 网络模型:网络模型CODASYL模型,是层次模型的推广。层次模型一个记录只能有一个父节点,层次模型一个记录可以有多个父节点。层次/网络模型访问时都需要“遍历”。
- 关系模型:关系模型同网络模型有过竞争。关系模型定义所有的数据格式。关系表只是行的集合。访问记录时是有数据库自行选择“访问路径”(由查询优化器自动生成)。
文档数据库时某种方式的层次模型,但并未遵循CODASYL标准。
关系/文档数据库比较
- 应用代码:如果应用数据具有类似文档结构(一对多,树结构)。关系模型倾向某种数据分解,模式笨重。但文档模型也有局限性:不能直接饮用文档中的嵌套项。文档模型处理多对一的数据关系很弱。
- 文档模型的模式灵活性:文档模型类/关系模型 类似于编程语言中的动态/静态类型检查。文档模型是读时模式(数据结构是隐式的,只有在读取以后才解释),关系数据库传统的方式是写时模式(模式时显式的,写入/读取时都必须遵循预定的结构)。文档模型可以认为没有数据结构模式,因此改变模式非常方便。关系模式更改更复杂。大多数数据库能够在几毫秒内执行alter,但MySQL不行,MySQL会复制整张表(有辅助工具解决这个限制)
- 数据的存储局部性(
data locality
:数据视为整体存储):文档数据通常存储为JSON/XML/变体(MongoDB的BSON)连续字符串。如果频繁读取整个文档,则文档型数据库非常适用。文档数据库更新记录时,只有修改量不改变原文档大小时,才能采用原地覆盖更新,这些说明文档数据库不适用频繁更新记录的场景。 - 现在文档/关系数据库正在互相融合对方的功能点。如MySQL支持JSON数据。
Bigtable数据模型:用于Cassandra/HBase
数据查询语言
SQL是一种声明式的查询语言。相对的是命令式语言。声明式查询语言只需要指定所需的数据模式,而命令式语言要指定哪些操作(过程),类似于编程语言。声明式查询语言API比