数据密集型应用设计读书笔记第一章。
现在的数据密集型应用,趋势是组件化。
存储数据,以便自己或其他应用程序之后能再次找到 (数据库(database))
记住开销昂贵操作的结果,加快读取速度(缓存(cache))
允许用户按关键字搜索数据,或以各种方式对数据进行过滤(搜索索引(search indexes))
向其他进程发送消息,进行异步处理(流处理(stream processing))
定期处理累积的大批量数据(批处理(batch processing))
一个系统里,缓存,数据库,索引,和消息队列等都解耦开来,每个部分再针对需求选择对应的组件。
而应用业务代码则负责维护组件之间的一致性。
而一个数据系统,非功能性需求的基础目标有三个,可靠性,可伸缩性,可维护性。
可靠性(Reliability)
系统在困境(adversity)(硬件故障、软件故障、人为错误)中仍可正常工作(正确完成功能,并能达到期望的性能水准)。
可伸缩性(Scalability)
有合理的办法应对系统的增长(数据量、流量、复杂性)(参阅“可伸缩性”)
可维护性(Maintainability)
许多不同的人(工程师、运维)在不同的生命周期,都能高效地在系统上工作(使系统保持现有行为,并适应新的应用场景)。
可靠性(Reliability) 意味着即使发生故障,系统也能正常工作。故障可能发生在硬件(通常是随机的和不相关的),软件(通常是系统性的Bug,很难处理),和人类(不可避免地时不时出错)。 容错技术 可以对终端用户隐藏某些类型的故障。
这里需要注意容错与预防的区别。容错意味着出错了并自动化地修复。而预防则是在设计实现时就防止出错的可能,往往代价和难度更大,毕竟许多错误无法预测。
在设计系统的容错能力时,要定义容忍什么样的错误,能力边界。不存在能容忍所有错误的系统。
可伸缩性(Scalability) 意味着即使在负载增加的情况下也有保持性能的策略。为了讨论可伸缩性,我们首先需要定量描述负载和性能的方法。我们简要了解了推特主页时间线的例子,介绍描述负载的方法,并将响应时间百分位点作为衡量性能的一种方式。在可伸缩的系统中可以添加 处理容量(processing capacity) 以在高负载下保持可靠。
关键:描述负载,描述性能。
负载:每秒一千次1kb的请求,还是每秒1次1mb的请求?访问流量的特征如何?
性能:吞吐量和响应时间(响应时间要用百分位点,更有意义。以及,对百分位点取平均值没有意义)
可维护性(Maintainability) 有许多方面,但实质上是关于工程师和运维团队的生活质量的。良好的抽象可以帮助降低复杂度,并使系统易于修改和适应新的应用场景。良好的可操作性意味着对系统的健康状态具有良好的可见性,并拥有有效的管理手段。
可操作性:有利于运维团队的工作,有监控,跟踪问题的工具,易读的文档,详细的日志等等。
简单性:需要良好的抽象(精心设计的API,隐藏底层细节)和设计(合适的设计模式)
可演化性:修改数据系统并使其适应不断变化需求的容易程度,与系统的简单性和抽象性密切相关。 敏捷(agile) 工作模式为适应变化提供了一个框架。敏捷社区还开发了对在频繁变化的环境中开发软件很有帮助的技术工具和模式,如 测试驱动开发(TDD, test-driven development) 和 重构(refactoring) 。
TDD ,是一种不同于传统软件开发流程的新型的开发方法。 它要求在编写某个功能的代码之前先编写测试代码,然后只编写使测试通过的功能代码,通过测试来推动整个开发的进行。 这有助于编写简洁可用和高质量的代码,并加速开发过程