数据密集型应用系统设计(读书笔记)第一天

简介: 数据密集型应用系统设计(读书笔记)第一天

第一章: 可靠、可扩展与可维护的应用系统

数据密集型应用通常也是基于标准模块构建而成,每个模块负责单一的常用功能。例如,许多应用系统都包含以下模块:

  • 数据库:用以存储数据,这样之后应用可以再次面问。
  • 高速缓存:缓存那些复杂或操作代价昂贵的结果,以加快下一次访问。
  • 索引:用户可以按关键字搜索数据井支持各种过掳
  • 流式处理:持续发送消息至另 个进程,处理采用异步方式。
  • 批处理:定期处理大量的累积数据。

影响数据系统设计的因素有很多,其中包括相关人员技能和 经验水平、遗留系统依赖性、交付周期、对不同风险因素的容忍度、监管合规等。这些因素往往因时因地而 异。本书将专注于对大多数软件系统都极为重要的三个问题:

可靠性 (Reliability)

当出现意外情况如硬件、软件故障、人为失误等,系统应可以继续正常运转:虽然性能可能有所降低,但确保功能正确。

每个人对于可靠大概都有一个直观的认识,对于软件,典型的期望包括:

  • 应用程序执行用户所期望的功能。
  • 可以容忍用户出现错误或者不正确的软件使用方法。
  • 性能可以应对典型场 理负载压力和数据量。
  • 系统可防止任何未经授权的访问和滥用。

如果所有上述目标都要支持才算 “正常工作”,那么我们可以认为可以大致意味着 :即使发生了某些错误,系统仍可以继续正常工作。

可能出错的事情称为错误( faults )或故障,系统可应对错民 称为容错( fault-tolerant )或者弹性( resilient )。 前一个词略显误导 :似乎暗示着系统可容忍各种 可能的故障类型,显然在实际中这是不可能的。举夸张一些的例子,如果整个地球 (及其上的所有服务器)都被黑洞吞噬,那么要在这个级别容错就意味着必须在宇宙 范围内进行系统冗余。试想,这将是天价的预算。因此,容错总是指特定类型的故障,这样的系统才更有实际意义

可扩展性 (Scalability)

随着规模的增长 ,例如数据 、流量或复杂性,系统应以合理的方式来匹配这种增长

是指负载增加时, 有效保持系统性能的相关技术策略。简单地以Twitt 浏览时间线为例描述负载,并将时间百分位数作为衡量性能的有效方式。对于可扩展的系统,增加处理能力的同时,还可以在高负载情况下持续保持系统的高可靠性。

可维护性 (Maintainability)

随着时间的推移,许多新的人员参与到系统开发和运维, 以维护现有功能或适配新场景等,系统都应高效运转。

我们可以从软件设计时就开始考虑,尽可能较少维护开发周期内的麻烦,甚至避免可能容易过期的系统,因此,我们应该特别关注软件系统的三个设计原则:

  • 可运维性
  • 保持软件和平台至最新状态, 例如安全补丁方面。
  • 了解不同系统如何相互影响,避免执行带有破坏性的操作。
  • 预测未来可能的问题,并在问题发生之前即使解决(例如容量规划)。
  • 建立用于部署、配置管理等良好的实践规范和工具包。
  • 执行复杂的维护任务, 例如将应用程序从一个平台迁移到另一个平台。
  • 当配置更改时,维护系统的安全稳健。
  • 制定流程来规范操作行为,并保持生产环境稳定 保持相关知识的传承(如对系统理解),例如发生团队人员离职或者新员工加入等。
  • 良好的可操作性意味着使日常工作变得简单,使运营团队能够注于高附加值的任务。数据系统设计可以在这方面贡献很多, 包括
  • 提供对系统运行时行为和内部的可观测性,方便监控。
  • 支持自动化, 标准工具集成
  • 避免绑定特定的机器,这样在整个系统不间断运行的同时,允许机器停机维护。
  • 提供良好的文档和易于理解的操作模式,诸如“如果我做了 ,会发生 ”。
  • 提供良好的默认配置,且允许管理员在需要时方便地修改默认值。
  • 尝试自我修复,在需要时让管理员手动控制系统状态 为可预测,减少意外发生。
  • 简单性

简化系统设计并不意味着减少系统功能,而主要意味着消除意外方面的复杂性,正如 Moseley Marks把复杂性定义为 种“意外”,即它并非软件固有、被用户所见 或感知,而是实现本身所衍生出来的问题。

消除意外复杂性最好手段之一是抽象。 个好的设计抽象可以隐藏大量的实现细节, 并对外提供干净、易懂的接口。一个好的设计抽象可用于各种不同的应用程序。这样,复用远比多次重复实现更有效率;另外一方面,也带来更高质量的软件,而质量过硬的抽象组件所带来的好处,可以使运行其上的所有应用轻松获益。 例如

  • 高级编程语言作为一种抽象,可以隐藏机器汇编代码、 CPU寄存器和系统调用细节和复杂性。
  • SQL作为一种抽象,隐藏了内部复杂的磁盘和内存数据结构 ,以及 来自多客户端的并发请求,系统崩愤之后的不 致等问题。

当然,使用高级编程语言 最终并没有脱离机器汇编代码,只是井非直接使用,与汇编代码打交道的事情已经由汇编程语抽象为高效接口代我们完成。 然而,设计好的抽象还是很有挑战性。在分布式系统领域中,虽然已有许多好的算桂 可供参考,但很多时候我们并不太清楚究竟该如何利用他们,封装到抽象接口之中, 最终帮助将系统的复杂性降低到可靠控的级别。

  • 可演化性:易于改变

一成不变的系统需求几乎没有,想法和目标经常在不断变化:适配新的外部环境,新的用例,业务优先级的变化,用户要求的新功能,新平台取代旧平台,注律或监管要求的变化,业务增长促使架构的演变等。

在组织、流程方面 ,敏捷开发模式为适应变化提供 了很好的参考。敏捷社区还发布很多技术工具和模式,以帮助在频繁变化的环境中开发软件,例如测试驱动开发 (TDD )和重构。


相关文章
|
JavaScript 数据可视化 前端开发
《面向三维GIS的Cesium开发与应用》读书笔记
《面向三维GIS的Cesium开发与应用》读书笔记
|
存储 SQL 缓存
读书笔记《数据密集型应用系统设计》- 数据存储与检索
《数据密集型应用系统设计》是一本很好的介绍数据密集类系统设计原理的纲要性书籍,笔者再次阅读下,记录一些读书笔记,也写一些自己的思考穿插其中,以做备忘。
175 0
|
存储 分布式计算 安全
【读书笔记】大数据原理与应用:分布式文件系统HDFS
【读书笔记】大数据原理与应用:分布式文件系统HDFS
186 0
【读书笔记】大数据原理与应用:分布式文件系统HDFS
|
存储 运维 监控
读书笔记之数据密集型应用的可维护性
前面两篇文章分别介绍了可靠性和可扩展性,本篇文章将介绍了第三个特性:可维护性。
|
Java 数据库 算法
《Akka应用模式:分布式应用程序设计实践指南》读书笔记9
性能   这也是一个比较大的问题,因为性能不一定是Akka本身的问题,还可能是你代码写的有问题。   优化的第一步就是找出性能的瓶颈,隔离出应用程序里面比较耗时的部分,然后尝试对其优化,减少需要耗费的时间成本。
1706 0
|
缓存 运维 数据库
《Akka应用模式:分布式应用程序设计实践指南》读书笔记8
可用性   简单点来说就是系统能否正常使用。如果系统能够及时响应一个请求,则认为是可用的;如果响应时间过长或者根本不响应,则是不可用的。系统在停机或超载时是不可用的。一般用系统正常运行时长的百分比来计量系统的可用性,例如常常用N个9表示系统的可用性。
1928 0
|
存储 缓存 NoSQL
《Akka应用模式:分布式应用程序设计实践指南》读书笔记6
一致性和可扩展性   一致性是系统内比较复杂的属性,它会随着系统的变化而变化。简单来说,一致性就是数据保持一致,在分布式系统中,可以理解为多个节点中数据的值是一致的。一旦系统具有并行性(分布式只是并行的一种表现),保持一致性就变得困难了,毕竟需要协调全局状态。
1424 0
|
运维 Java
《Akka应用模式:分布式应用程序设计实践指南》读书笔记7
容错   容错绝对是分布式系统最难搞定的事儿,至少我这样认为,因为意外总是会发生。   处理故障在许多方面意味着要放弃全局一致性。Akka是基于不粗要调用方负责处理故障的想法而建立的。它主张由发生故障的actor负责处理问题,在actor不能处理的情况下,会向其“监督者”寻求帮助。
1763 0
|
设计模式 Java API
《Akka应用模式:分布式应用程序设计实践指南》读书笔记2
Akka简介   Akka是什么:“Akka是在JVM上构建高并发、分布式、弹性消息驱动应用的开源工具包”。弹性意味着要积极响应失败情况,从失败中恢复的能力。   其实Akka的定义很符合响应式领域模型,这个模型有几个基本特征:   1、弹性。
2228 0
|
Web App开发
嵌入式实时操作系统uc/os-ii 原理及应用 读书笔记
对任务就绪表的操作理解: 将优先级别为prio的任务置为就绪状态,可使用如下代码 OSRdyGrp |= OSMapTbl[prio >>3];//将prio任务所在的组状态置为1,表示该组有任务就绪。
878 0