Nosql数据一致性技术概要

简介:

主要参考, http://highlyscalable.wordpress.com/2012/09/18/distributed-algorithms-in-nosql-databases/, Distributed Algorithms in NoSQL Databases

 

Data Consistency

It is well known and fairly obvious that in geographically distributed systems or other environments with probable network partitions or delays it is not generally possible to maintain high availability without sacrificing consistency because isolated parts of the database have to operate independently in case of network partition. This fact is often referred to as the CAP theorem. However, consistency is a very expensive thing in distributed systems, so it can be traded not only to availability. It is often involved into multiple tradeoffs. To study these tradeoffs, we first note that consistency issues in distributed systems are induced by the replication and the spatial separation of coupled data, so we have to start with goals and desired properties of the replication:

根据CAP理论, 现在的系统往往会牺牲consistency而换取可用性, 因为在分布式系统上保证数据一致性是非常困难的. 作者认为现在系统除了可用性, 还有从其他因素的考虑,需要牺牲一致性, 因素如下.

  • Availability. Isolated parts of the database can serve read/write requests in case of network partition.
  • Read/Write latency. Read/Write requests are processes with a minimal latency.
  • Read/Write scalability. Read/Write load can be balanced across multiple nodes.
  • Fault-tolerance. Ability to serve read/write requests does not depend on availability of any particular node.
  • Data persistence. Node failures within certain limits do not cause data loss.

 

Consistency is a much more complicated property than the previous ones, so we have to discuss different options in detail. It beyond this article to go deeply into theoretical consistency and concurrency models, so we use a very lean framework of simple properties.

  • Read-Write consistency

    From the read-write perspective, the basic goal of a database is to minimize a replica convergence time (how long does it take to propagate an update to all replicas) and guarantee eventual consistency. Besides these weak guarantees, one can be interested in stronger consistency properties:
    • Read-after-write consistency. The effect of a write operation on data item X, will always be seen by a successive read operation on X.
    • Read-after-read consistency. If some client reads the value of a data item X, any successive read operation on X will always return that same or a more recent value.

读一致性, 比较好理解, 更新一个复本, 这个更新传播到所有复本肯定需要时间, 所以我们需要尽量减少这个时间, 并保证最终的一致性.

但是在这个过程中, 读操作对于不同的复本肯定会出现不一致, 这就是Read-after-write consistency

 

  • Write-Write consistency

    Write-write conflicts appear in case of database partition, so a database should either handle these conflicts somehow or guarantee that concurrent writes will not be processed by different partitions. From this perspective, a database can offer different consistency models:
    • Atomic Writes. If a database provides an API where a write request can only be an independent atomic assignment of a value, one possible way to avoid write-write conflicts is to pick the “most recent” version of each entity. This guarantees that all nodes will end up with the same version of data irrespectively to the order of updates which can be affected by network failures and delays. Data version can be specified by a timestamps or application-specific metric. This approach is used for example in Cassandra.
    • Atomic Read-modify-write. Applications often do a read-modify-write sequence instead of independent atomic writes. If two clients read the same version of data, modify it and write back concurrently, the latest update will silently override the first one in the atomic writes model. This behavior can be semantically inappropriate (for example, if both clients add a value to a list). A database can offer at least two solutions:
      • Conflict prevention. Read-modify-write can be thought as a particular case of transaction, so distributed locking or consensus protocols like PAXOS [20, 21] are both a solution.  This is a generic technique that can support both atomic read-modify-write semantics and arbitrary isolated transactions. An alternative approach is to prevent distributed concurrent writes entirely and route all writes of a particular data item to a single node (global master or shard master).  To prevent conflicts, a database must sacrifice availability in case of network partitioning and stop all but one partition. This approach is used in many systems with strong consistency guarantees (e.g. most RDBMSs, HBase, MongoDB).
      • Conflict detection. A database track concurrent conflicting updates and either rollback one of the conflicting updates or preserve both versions for resolving on the client side. Concurrent updates are typically tracked by using vector clocks [19] (which can be though as a generalization of the optimistic locking) or by preserving an entire version history. This approach is used in systems like Riak, Voldemort, CouchDB.

写一致性复杂一些, 在并发写的情况下, 各种写操作很可能会发生冲突和互相覆盖.

第一种比较简单的case, 独立的写操作, 写的时候不用care之前的值, 单纯的状态更新. 这种情况唯一要考虑的问题是时序问题, 必须保证“most recent” version被更新, 但由于network failures and delays, “most recent” version反而可能后到. 通常的方法是通过比如timestamps或application-specific metric来保证这点.

第二种比较复杂一些, Read-modify-write, 如果不控制, 在这个过程中, 很可能有其他并发写把这个值给update了, 或者是同时两个client读到这个值, 并执行Read-modify-write,  这样就会发生写冲突.

解决方法有两种,

  • 事前预防(悲观锁), 保证高一致性, 用分布式lock或Paxos协议, 来保证一致性. 另一种思路, 使用master, 由master来协调所有并发写的顺序, 比如HBase, MongoDB, 当然这样会带来单点问题, 好处是简单
  • 事后detection(乐观锁), 高可用性, 先各自存各自的版本, 这样当版本发生conflict时, 再由client side resolving, 比如Dynamo, CouchDB, 都是使用这个方法

 

 

Now let’s take a closer look at commonly used replication techniques and classify them in accordance with the described properties. The first figure below depicts logical relationships between different techniques and their coordinates in the system of the consistency-scalability-availability-latency tradeoffs. The second figure illustrates each technique in detail.

上面给出分布式系统设计需要考虑的属性, consistency-scalability-availability-latency, 而不同的设计就是在各个属性之间的tradeoffs, 下面第一张图就表示具体的tradeoff的情况, 而第二张图描绘出具体的设计思想.

image

image

Replication factor 4. It is assumed that read/write coordinator can be either an external client or a proxy node within a database.

Let’s go through all these techniques moving from weak to strong consistency guarantees:

  • (A, Anti-Entropy) Weakest consistency guarantees are provided by the following strategy. Writer updates any arbitrary selected replica. Reader reads any replica and sees the old data until a new version is not propagated via background anti-entropy protocol (more on anti-entropy protocols in the next section). The main properties of this approach are:
    • High propagation latency makes it quite impractical for data synchronization, so it is typically used only as an auxiliary background process that detects and repairs unplanned inconsistencies. However, databases like Cassandra use anti-entropy as a primary way to propagate information about database topology and other metadata.
    • Consistency guarantees are poor: write-write conflicts and read-write discrepancies are very probable even in absence of failures.
    • Superior availability and robustness against network partitions. This schema provides good performance because individual updates are replaced by asynchronous batch processing.
    • Persistence guarantees are weak because new data are initially stored on a single replica.
  • (B) An obvious improvement of the previous schema is to send an update to all (available) replicas asynchronously as soon as the update request hits any replica. It can be considered as a kind of targeted anti-entropy.
    • In comparison with pure anti-entropy, this greatly improves consistency with a relatively small performance penalty. However, formal consistency and persistence guarantees remain the same.
    • If some replica is temporary unavailable due to network failures or node failure/replacement, updates should be eventually delivered to it by the anti-entropy process.
  • (C) In the previous schema, failures can be handled better using the hinted handoff technique [8]. Updates that are intended for unavailable nodes are recorded on the coordinator or any other node with a hint that they should be delivered to a certain node as soon as it will become available. This improves persistence guarantees and replica convergence time.
  • (D, Read One Write One) Since the carrier of hinted handoffs can fail before deferred updates were propagated, it makes sense to enforce consistency by so-called read repairs. Each read (or randomly selected reads) triggers an asynchronous process that requests a digest (a kind of signature/hash) of the requested data from all replicas and reconciles inconsistencies if detected.

We use term ReadOne-WriteOne for combination of techniques A, B, C and D – they all do not provide strict consistency guarantees, but are efficient enough to be used in practice as an self-contained approach.

A, B, C, D可以称为ReadOne-WriteOne, 通过tradeoff consistency, 来获取available, r/w latency, 和扩展性

A是特点最鲜明的, 只保证最低的consistency, 而获取最高的可用性. 只更新任意一replica, 然后完全依靠anti-entropy去传播更新.

B, 为了降低propagation latency, 会把更新异步的发送给所有复本, 这样提高了传播效率, 代价就说略微牺牲了r/w latency, 和扩展性, 需要获取所有复本的location信息并发送.

在B中, 只是异步的将更新发给所有复本, 但并不保证更新成功, 如果有replic fail, 只有后面通过anti-entropy去同步, 所以是没有牺牲可用性的.

C, 提供hinted handoff technique来提高fail节点同步效率, 以提高persistence和replica convergence time.

hinted handoff technique, 说白了就是把更新暂时放在coordinator or any other node, 然后不断侦听fail node, 一旦恢复, 自动将更新同步. hinted意思就是这个handoff对client透明的, 暗示的. 真是会起名字, 怎么想到这么诡异的名字的

D, 读任意一复本时, 对其他复本请求digest, 然后再reconcile不一致, 这个应该是对读consistency比较大的提高, 但也较大的牺牲了available, r/w latency.

 

  • (E, Read Quorum Write Quorum) The strategies above are heuristic enhancements that decrease replicas convergence time. To provide guarantees beyond eventual consistency, one has to sacrifice availability and guarantee an overlap between read and write sets. A common generalization is to write synchronously W replicas instead of one and touch R replicas during reading.
    • First, this allows one to manage persistence guarantees setting W>1.
    • Second, this improves consistency for R+W>N because synchronously written set will overlap with the set that is contacted during reading (in the figure above W=2, R=3, N=4), so reader will touch at least one fresh replica and select it as a result. This guarantees consistency if read and write requests are issued sequentially (e.g. by one client, read-your-writes consistency), but do not guarantee global read-after-read consistency. Consider an example in the figure below to see why reads can be inconsistent. In this example R=2, W=2, N=3. However, writing of two replicas is not transactional, so clients can fetch both old and new values until writing is not completed:

image

    • Different values of R and W allows to trade write latency and persistence to read latency and vice versa.
    • Concurrent writers can write to disjoint quorums if W<=N/2. Setting W>N/2 guarantees immediate conflict detection in Atomic Read-modify-write with rollbacks model.
    • Strictly speaking, this schema is not tolerant to network partitions, although it tolerates failures of separate nodes. In practice, heuristics like sloppy quorum [8] can be used to sacrifice consistency provided by a standard quorum schema in favor of availability in certain scenarios. 
      "sloppy quorum”, “马虎的quorum”,会把通过Hinted Handoff 写成功的临时节点也计算在成功写入数中, 解决临时部分节点fail的问题
  • (F, Read All Write Quorum) The problem with read-after-read consistency can be alleviated by contacting all replicas during reading (reader can fetch data or check digests). This ensures that a new version of data becomes visible to the readers as soon as it appears on at least one node. Network partitions of course can lead to violation of this guarantee.

E, F可以称为Read Quorum Write Quorum, 这种设计对consistency和available的tradeoff做了比较好的balance, 在高可用性的前提下, 又能保证eventual consistency, Amazon Dynamo就是用的这种方案.

只要R+W>N, 就可以保证读操作至少可以读到一个最新的replica. 同时通过调整R,W的值可以trade write latency和read latency.

保证W>N/2, 可以立即发现write conflict, 并rollback, 但是否要在write的时候去消除conflict, 也是策略问题, Dynamo就为了保证永远可写, 没有采用这种策略, 而将conflict交给client在读的时候解决.

为了保证分区容错, 可以采用sloppy quorum技术.

当然采取这样的策略, 当write过程没有完成时, 去读数据是有可能读不到new数据的, 见上图, 如果要解决这个问题, 可以用Read All Write Quorum

 

  • (G, Master-Slave) The techniques above are often used to provide either Atomic Writes or Read-modify-write withConflict Detection consistency levels. To achieve a Conflict Prevention level, one has to use a kind of centralization or locking. A simplest strategy is to use master-slave asynchronous replication. All writes for a particular data item are routed to a central node that executes write operations sequentially. This makes master a bottleneck, so it becomes crucial to partition data into independent shards to be scalable.
  • (H, Transactional Read Quorum Write Quorum and Read One Write All) Quorum approach can also be reinforced by transactional techniques to prevent write-write conflicts. A well-known approach is to use two-phase commit protocol. However, two-phase commit is not perfectly reliable because coordinator failures can cause resource blocking. PAXOS commit protocol [20, 21] is a more reliable alterative, but with a price or performance penalty. A small step forward and we end up with the Read One Write All approach where writes update all replicas in a transactional fashion. This approach provides strong fault-tolerant consistency but with a price of performance and availability.

 A~F都是高可用性优先, 最多实现eventual consistency, 而G, H都是强一致性的方案

 简单的强一致性方法, Master-Slave, 通过master来统一安排, 避免conflict, HBase和MongoDB的方案, 当然无法避免master的单点问题

 对于无Master的去中心化的并发写, 要保证强一致性, 最基本的就通过two-phase commit protocol, 考虑到coordinator failures的情况, 可以使用PAXOS commit protocol (支持leader选举)

 同时这儿也可以使用Read One Write All approach或者Quorum approach

 

总结,

作者谈一致性, 谈的还是比较透彻的,

对于Read-Write consistency, 基本上是通过Quorum approach来解决, 如Read Quorum Write Quorum. 之所以是Quorum而不是All, 考虑到r/w latency和available的tradeoff

对于Write-Write consistency, 主要是Read-modify-write问题, 要么采用可用性优先的Conflict Detection, 要么就使用一致性优先的Conflict Prevention


本文章摘自博客园,原文发布日期:2012-11-24

目录
相关文章
|
3天前
|
数据库 索引
深入探索数据库索引技术:回表与索引下推解析
【10月更文挑战第15天】在数据库查询优化的领域中,回表和索引下推是两个核心概念,它们对于提高查询性能至关重要。本文将详细解释这两个术语,并探讨它们在数据库操作中的作用和影响。
15 3
|
3天前
|
数据库 索引
深入理解数据库索引技术:回表与索引下推详解
【10月更文挑战第23天】 在数据库查询性能优化中,索引的使用是提升查询效率的关键。然而,并非所有的索引都能直接加速查询。本文将深入探讨两个重要的数据库索引技术:回表和索引下推,解释它们的概念、工作原理以及对性能的影响。
16 3
|
11天前
|
存储 缓存 监控
数据库优化技术:提升性能与效率的关键策略
【10月更文挑战第15天】数据库优化技术:提升性能与效率的关键策略
43 8
|
20天前
|
存储 监控 NoSQL
九大核心NoSQL数据库及使用场景详解
【10月更文挑战第6天】在当今大数据与云计算飞速发展的时代,NoSQL数据库以其灵活的数据模型、可扩展性和高性能,成为了众多应用场景下的首选。本文将为您详细介绍九大核心NoSQL数据库及其典型使用场景,帮助您在工作和学习中更好地选择和应用。
46 3
|
9天前
|
存储 NoSQL 关系型数据库
数据库技术深度解析:从基础到进阶
【10月更文挑战第17天】数据库技术深度解析:从基础到进阶
24 0
|
2天前
|
负载均衡 网络协议 数据库
选择适合自己的数据库多实例负载均衡技术
【10月更文挑战第23天】选择适合自己的数据库多实例负载均衡技术需要全面考虑多种因素。通过深入的分析和评估,结合自身的实际情况,能够做出明智的决策,为数据库系统的高效运行提供有力保障。
|
2天前
|
缓存 负载均衡 监控
数据库多实例的负载均衡技术深入
【10月更文挑战第23天】数据库多实例负载均衡技术是确保数据库系统高效运行的重要手段。通过合理选择负载均衡策略、实时监控实例状态、不断优化调整,能够实现资源的最优分配和系统性能的提升。在实际应用中,需要根据具体情况灵活运用各种负载均衡技术,并结合其他相关技术,以满足不断变化的业务需求。
|
2天前
|
Java 数据库连接 数据库
优化之路:Java连接池技术助力数据库性能飞跃
在Java应用开发中,数据库操作常成为性能瓶颈。频繁的数据库连接建立和断开增加了系统开销,导致性能下降。本文通过问题解答形式,深入探讨Java连接池技术如何通过复用数据库连接,显著减少连接开销,提升系统性能。文章详细介绍了连接池的优势、选择标准、使用方法及优化策略,帮助开发者实现数据库性能的飞跃。
14 4
|
2天前
|
SQL Java 数据库连接
打破瓶颈:利用Java连接池技术提升数据库访问效率
在Java应用中,数据库访问常成为性能瓶颈。连接池技术通过预建立并复用数据库连接,避免了频繁的连接建立和断开,显著提升了数据库访问效率。常见的连接池库包括HikariCP、C3P0和DBCP,它们提供了丰富的配置选项和强大的功能,帮助优化应用性能。
16 2
|
5天前
|
存储 SQL JSON
介绍一下RDBMS和NoSQL数据库之间的区别
【10月更文挑战第21天】介绍一下RDBMS和NoSQL数据库之间的区别
23 2