NoSQL Talk

NoSQL数据库笔谈

思想篇

CAP、BASE、最终一致性是 NoSQL 数据库存在的三大基石。

五分钟法则是内存数据存储了理论依据。

CAP

理论

  • C: Consistency 一致性

  • A: Availability 可用性(指的是快速获取数据)

  • P: Tolerance of network Partition 分区容忍性(分布式)

CAP 理论告诉我们,一个分布式系统不可能满足一致性,可用性和分区容错性这三个需求,最多只能同时满足两个

架构师

一般有两个方向来利用 CAP 理论:

(1) key-value 存储,如 Amaze Dynamo 等,可根据CAP三原则灵活选择不同倾向的数据库产品。

(2) 领域模型 + 分布式缓存 + 存储 (Qi4j和NoSql运动),可根据 CAP 三原则结合自己项目定制灵活的分布式方案,难度高。

第三种方案:

(3) 实现可以配置 CAP 的数据库,动态调配 CAP。

  • CA:传统关系数据库

  • AP:key-value 数据库

而对大型网站,可用性与分区容忍性优先级要高于数据一致性,一般会尽量朝着 A、P 的方向设计,然后通过其它手段保证对于一致性的商务需求。 架构设计师不要精力浪费在如何设计能满足三者的完美分布式系统,而是应该进行取舍。

最终一致性

简而言之:宽入严出,结果必须保持一致性。

元素概念

为了描述一致性。提供一个场景。

  • 存储系统

存储系统可以理解为一个黑盒子,它为我们提供了可用性和持久性的保证。

  • Process A

ProcessA 主要实现从存储系统 write 和 read 操作

  • Process B 和ProcessC

Process B 和 C 是独立于 A,并且 B 和 C 也相互独立的,它们同时也实现对存储系统的 write 和 read 操作。

各种程度

  • 强一致性

强一致性(即时一致性) 假如A先写入了一个值到存储系统,存储系统保证后续A,B,C的读取操作都将返回最新值

  • 弱一致性

假如A先写入了一个值到存储系统,存储系统不能保证后续A,B,C的读取操作能读取到最新值。 此种情况下有一个不一致性窗口的概念,它特指从A写入值,到后续操作A,B,C读取到最新值这一段时间。

  • 最终一致性

最终一致性是弱一致性的一种特例。假如A首先write了一个值到存储系统, 存储系统保证如果在A,B,C后续读取之前没有其它写操作更新同样的值的话, 最终所有的读取操作都会读取到最A写入的最新值。 此种情况下,如果没有失败发生的话, 不一致性窗口的大小依赖于以下的几个因素:交互延迟,系统的负载, 以及复制技术中replica的个数(这个可以理解为master/salve模式中,salve的个数), 最终一致性方面最出名的系统可以说是DNS系统,当更新一个域名的IP以后, 根据配置策略以及缓存控制策略的不同,最终所有的客户都会看到最新的值。

BASE

BASE 的意义是碱,而 ACID 是酸。真的是水火不容啊。

  • ACID

原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability).

  • BASE

Basically Availble(基本可用)、Soft-state(软状态/柔性事务)、Eventual Consistency(最终一致性)

I/O的五分钟法则

简而言之,如果一条记录频繁被访问,就应该放到内存里,否则的话就应该待在硬盘上按需要再访问。这个临界点就是五分钟。

手段篇

一致性哈希

第一阶段

考虑到单服务器不能承载,因此使用了分布式架构,最初的算法为 hash() mod n, hash()通常取用户ID,n为节点数。此方法容易实现且能够满足运营要求。

缺点:是当单点发生故障时,系统无法自动恢复。

第二阶段

为了解决单点故障,使用 hash() mod (n/2), 这样任意一个用户都有2个服务器备选,可由client随机选取。

由于不同服务器之间的用户需要彼此交互,所以所有的服务器需要确切的知道用户所在的位置。因此用户位置被保存到memcached中。

当一台发生故障,client可以自动切换到对应backup,由于切换前另外1台没有用户的session,因此需要client自行重新登录。

缺陷:

  • 负载不均衡,尤其是单台发生故障后剩下一台会压力过大

  • 不能动态增删节点

  • 节点发生故障时需要client重新登录

第三阶段

打算去掉硬编码的hash() mod n 算法,改用一致性哈希(consistent hashing)分布 假如采用Dynamo中的strategy 1 我们把每台server分成v个虚拟节点,再把所有虚拟节点(n*v)随机分配到一致性哈希的圆环上, 这样所有的用户从自己圆环上的位置顺时针往下取到第一个vnode就是自己所属节点。 当此节点存在故障时,再顺时针取下一个作为替代节点。

优点:发生单点故障时负载会均衡分散到其他所有节点,程序实现也比较优雅。