
简介与概述
|
157
这些情况,你能以更自然的方式解决问题,比如内置防护措施或修改设计。
8.2.4
本地和远程执行
将复杂性隐藏在 API 内部可能很危险。例如,对于本地数据集上的一个迭代器,即使你
对存储引擎不熟悉,也可以合理地推测内部行为。理解远程数据集上的迭代过程则是一
个完全不同的问题:你需要理解一致性、传递语义、数据协调、分页、合并、并发访问
含义以及许多其他事情。
简单地将两者隐藏在同一个接口后,即便有用,也可能会产生误导。调试、配置和可观察性
可能需要额外的 API 参数。我们应该始终牢记,
本地执行和远程执行是不同的
[WALDO96]。
隐藏远程调用最明显的问题是延迟:远程调用的成本比本地调用高很多倍,因为它涉及
双向网络传输、序列化 / 反序列化以及许多其他步骤。交错使用本地调用和阻塞的远程
调用可能会导致性能下降和预期之外的副作用 [VINOSKI08]。
8.2.5
处理故障的需要
刚开始构建系统的时候,我们可以假设所有节点都可以正常工作,但如果总是这么想就
很危险了。在长时间运行的系统中,节点可能会关机维护(通常会有个优雅关闭的过程)
或因为种种原因(例如软件问题、内存耗尽(out-of-memory killer [KERRISK10])、运行
时 bug、硬件问题等)而崩溃。进程会发生故障,而你能做的最好的事情就是做好准备
并知道如何处理它们。
如果远程服务器没有响应,我们并不总是知道确切的原因。这可能是由系统崩溃、网络
故障、远程进程或中间链路太慢导致的。一些分布式算法使用
心跳协议 ...