总结
  这篇文章是对一些话题的简单、高度概括。还有很多话题我没有涉及到,诸如对不同工作流的优化(OLAP、OLTP、批处理)和数据库的UX(查询语言、传输协议、客户端类库),这些都是同等重要的。不同语义一致性的影响,诸如sequential consistency, read your own write, at least once delivery 都是非常有趣的。 关于数据库棒的事情是它是一个非常成熟的抽象。它大部分都在工作,而作为一名应用开发者,你可以不用思考能非常容易地保存和读取数据。这是值得庆祝的,但是为了这足够先进的技术脱层皮也确实是值得的。 我希望有更多的人能被这个主题深深吸引,并充分利用它。
  参考文献和旁注
  [1] 你不能牺牲分区容忍性 —— http://codahale.com/you-cant-sacrifice-partition-tolerance/。Aphy’rs Jepsend 的文章是一个很好的入门资源 —— http://aphyr.com/tags/Jepsen [2] 现代数据库频繁地利用OS文件系统缓存显著地加速文件系统的访问。未使用的内存自动地被用作缓存。这样一个系统的推荐生产配置对于没经验的人来说是不寻常的,机器有90%的内存是空闲的。 [3] 在基于类似 dynamo 的 quorum 系统中的常见缺陷是写故障时没有给出任何信息。当没有按时写入到内部副本时,写操作可以在客户端外部失败。因此,失败的写操作是非常容易成功。糟糕的是,在后写成功(last-write-wins)解决策略和倾斜的系统时钟下,以后的写入操作可以被这次的写入故障覆盖。 [4] 在数据库之间迁移涉及到了在多个数据库之间同时做读写操作。数据的所有者(俗称“真相来源”)是不确定的,而在新旧系统之间做同步可能会有数据的丢失。 [5] 在初创公司的基础架构中,应用程序的 bug 可能是可靠性和可用性大的罪犯。扩展和性能问题是可以被预测到的,而当你有一把服务器的时候,硬件故障通常不能被预见。然而,每天都会有新代码部署上线。 [6] 从网络是可靠的 —— 网络分区比你想象的还要常见。从根本上说,没有办法区分高延迟、网络分区、GC 停顿、和机器故障 —— 他们的表现都是低速连接。在 ElasticSearch 中这是一个普遍面临的问题。一个节点正在遭受一个大 GC 停顿,而整个集群认为这个节点挂了,然后试图重新分配数据,一连串的问题出现了。
  多数据库
  一旦一个系统与多个数据库有交互了,系统是终一致性了。你不能在同一时刻并发地修改多个数据库,除非你实现了两阶段提交协议(2PC)。这类似于“原子操作的成分是不是原子”。
  关于删除
  在任何的分布式系统中,删除数据是困难且危险的。数据到处都被复制,不管是数据库还是应用程序。没有一个适当的协调,被删除的数据被恢复回来是不可能的。一种典型的处理方法是写一个tombstones记录来代表删除,然而, tombstones 有他们自己的问题 :
  Tombstones 占据硬盘空间。为了回收硬盘空间,tombstones 必须到期。如果 tombstones 在完全复制前过期且被删除了,已删除的记录可以被复制回来。
  你可以用一个旧的 tombstone 来删除一个将来的写操作。这被通俗地称为厄运石头(doomstone)。搞笑的是,这是一个现实存在的问题。