使用日志型的数据结构
Cassandra、HBase、Redis 和 Riak 都会把写操作顺序的写入到一个日志文件中。相对于存储系统中的其他数据结构,上面说到的日志文件可以频繁地进行 fsync 操作,这样就把对磁盘的随机写变成顺序写了。
通过合并写操作提高吞吐性能
Cassandra 有一个机制,它会把一小段时间内的几个并发的写操作放在一起进行一次 fsync 调用,这种做法叫 group commit。
多机可靠性
由于硬件层面有时会造成无法恢复的损坏,单机可靠性的保证在这时就鞭长莫及了。对于一些重要数据,跨机器做备份保存是必备的安全措施。一些 NoSQL 系统提供了多机可靠性的支持。
Redis 采用传统的主从数据同步的方式。
MongoDB 提供了一种叫 Replica Sets 高可用架构。
Riak、Cassandra 和 Voldemort 提供了一些更灵活的可配置策略,并提供一个可配置的参数N,代表每一个数据会被备份的份数。为了应对整个数据中心出现故障的情况,需要实现跨数据中心的多机备份功能。
横向扩展带来性能提升
横向扩展的目标是达到线性的效果,即如果你增加一倍的机器,那么负载能力应该也能相应的增加一倍。其主要需要解决的问题是如何让数据在多台机器间分布,这里面涉及到分片技术。
分片的意思,就是没有任何一台机器可以处理所有写请求,也没有任何一台机器可以处理对所有数据的读请求。下面我们将会对 hash 分片和范围分片两种分片方式进行描述。
如非必要,请勿分片
分片会导致系统复杂程度大增,所以,如果没有必要,请不要使用分片。普通情况下,我们可以使用读写分离和构建缓存的方式来缓解我们的数据读压力。但如果写操作达到单点无法承担的程度,那我们可能就真的需要进行分片了。
通过协调器进行数据分片
一种分片策略是通过引入一个中间代理层来实现,该代理层记录数据在各个节点的分布状况,所有读写请求都通过代理层来做路由。比如与 CouchDB 的两个项目:Lounge 和 BigCouch。类似的,Twitter 自己也实现了一个叫 Gizzard 的协调器,可以实现数据分片和备份功能。
一致性 hash 环算法
一致性 hash 是一种被广泛应用的技术,其最早在一个叫 distributed hash tables(DHTs)的系统中进行使用。那些类 Dynamo 的应用,比如 Cassandra、Voldemort 和 Riak,基本上都使用了一致性 hash 环算法。
如图 1 所示,一致性 hash 环算法有一个 hash 函数H,所有存储数据的节点和数据本身都可以通过这个函数算出一个 hash 值,作为自己在下面环上的位置。然后每个节点会负责存储其 hash 值到下一个节点间的所有数据的存储。这样使得即使节点数变化了,大部分数据并不需要进行迁移。
图 1 一致性 hash 环算法的 hash 函数