数据一致性理论
数据一致性名词解释

数据一致性名词解释
数据一致性是指为了确保数据可靠而采取的一种有效措施。
它是所有数据储存和检索技术都必须遵循的最重要原则。
数据一致性能够帮助确保系统中的数据在任何特定时间保持一致。
这就是所谓的“ACID”(原子性,一致性,隔离性,持久性)原则的概念。
数据的一致性是建立在一组规则或标准之上的,这些规则规定了要求数据被做什么样的变化,根据什么样的机制,以及在什么时候完成变化。
这些规则被称为一致性约束,它们确保数据一直处于同一状态,并且保持准确性。
在现代应用程序中,数据一致性是至关重要的,因为在大多数情况下,这样可以确保应用程序和数据之间没有冲突或问题,允许用户更加准确快速地获取信息,这是本质上可靠提供信息的最佳方式。
此外,数据一致性还有助于维护数据完整性和可靠性。
数据完整性代表着数据的完整性可以建立和维护,以确保应用程序的稳定性和可靠性。
而可靠性则保证任何时候都能够访问到可以完整,一致且准确的信息。
总而言之,数据一致性是确保数据可靠性的关键。
它是所有数据存储和访问技术必须遵守的最重要规则,能够保证数据正确性,完整性和可靠性,从而提高系统的效率和可靠性。
数据库中的数据一致性

数据库中的数据一致性随着互联网的快速发展,各种应用程序和软件系统的数量急剧增加,这些系统中存储的数据也随之增加。
每个软件系统都有自己的数据库,其中包含了各种各样的数据,如用户的账户信息、商品的信息和订单信息等。
但是,如何确保这些数据在不同的系统中的一致性呢?这就需要数据库中的数据一致性来保证。
一、数据库中的数据一致性概述1.1 什么是数据库中的数据一致性?数据库中的数据一致性是指数据在不同的系统中的一致性,也就是说,当一个用户在一个系统中修改了数据后,其他系统中存储的数据也应该相应地进行更新。
例如,当一个用户在一个电商平台上购买商品时,他的订单信息应该保存在订单系统中,商品的信息应该保存在商品系统中,账户信息应该保存在账户系统中。
如果这些系统中的数据不一致,可能会导致严重的问题,如商品被重复购买或订单被错误地处理。
1.2 数据库中的数据一致性问题数据库中的数据一致性问题主要包括以下两方面:1.2.1 数据复制问题在分布式数据库中,数据通常会被存储在多个节点中,这些节点之间需要进行数据复制,以确保数据在不同的节点中的一致性。
然而,在数据复制过程中,可能会出现数据丢失、数据不一致和数据干扰等问题,从而导致数据一致性问题。
1.2.2 并发访问问题在数据库中,多个用户可以同时访问同一份数据,这就会导致并发访问问题。
并发访问问题主要包括以下两个方面:(1)读写冲突:当多个用户同时尝试修改同一份数据时,可能会出现读写冲突,从而导致数据的更新丢失或数据不一致。
(2)脏读:当一个用户读取一个未提交的数据时,可能会导致脏读问题,从而导致数据的更新丢失或数据不一致。
二、数据库中的数据一致性解决方案2.1 数据分片数据分片是指将数据库中的数据分成多个分片(或分区),每个分片都存储在不同的节点上。
当多个用户同时访问同一份数据时,可以将其分配到不同的分片中,从而避免了读写冲突和脏读问题。
同时,数据分片也可以提高系统的性能和可扩展性。
简述cap理论

简述cap理论CAP理论(ConsistencyAvailabilityPartitiontolerance)是由美国计算机科学家EricBrewer提出的,关于分布式系统中数据一致性模型的一种理论。
CAP理论是一个模型,用于决定分布式系统中的数据一致性如何,也就是说,它给予了开发者在系统中的策略,以便在满足系统要求的情况下实现数据一致性。
CAP理论提出了三个核心概念:一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)。
根据CAP 理论,任何分布式系统可以满足下列两种状态:(1)强一致性和可用性(CA),即系统中的所有节点都必须保持一致,并且在任何时候都能实现最高可用性;(2)系统要能够容忍部分故障,这是分区容错性(CP)。
在CAP理论的框架下,开发者可以根据具体的系统需求,来决定数据一致性的策略。
有时,开发者会选择CA,即将可用性和一致性作为主要目标,这种情况下,通常使用的是2PC(两阶段提交)或Paxos 算法;有时,开发者可能会选择CP,至少在相关服务不可用的情况下,也能满足项目要求,这种情况下,一般会使用到复制策略。
CAP理论在分布式系统中的实施非常重要,因为它可以帮助系统能够保持数据一致性,同时也尽可能地实现最高可用性。
虽然CAP理论可以帮助开发者在系统中实现数据一致性,但它有一些局限性。
最常见的是,CAP理论假设系统在特定的时间段内不会发生故障,而实际上,系统中随时可能发生某些无法预料的故障,这可能会影响到系统的正常运行。
此外,由于CAP理论中只涉及到三个核心概念,因此,它不能完整地表述分布式系统中更复杂的情况,而且在实际应用中,也会受到许多因素的影响,如网络连接的延迟、系统的复杂度和负载均衡等。
由于CAP理论的重要性,目前有许多研究正在努力突破CAP理论的局限,比如,在一致性和可用性之间增加更多的平衡,来实现对故障的更强的容错性;或是研究出新的一致性算法,用于提高系统的性能和可用性;或是开发出新的算法,用于改善系统中数据一致性的实施。
数据库技术中的数据一致性与数据完整性(四)

数据库技术中的数据一致性与数据完整性引言:在当今信息时代,数据无处不在,数据库技术的发展也日益成熟。
而对于数据库来说,数据的一致性与完整性是其中两个至关重要的方面。
本文将从理论和实践的角度探讨数据一致性与数据完整性在数据库技术中的重要性,以及相应的保证方法。
一、数据一致性的重要性数据一致性指的是数据库中的数据始终保持更新的状态,并能在多个副本之间保持一致。
在分布式数据库环境下,数据的一致性变得尤为重要。
如果数据不一致,将可能导致错误的计算结果、系统崩溃等问题,严重影响企业的正常运营。
因此,保持数据一致性是数据库技术中不可或缺的一项要求。
二、保证数据一致性的方法1. 事务的使用在数据库操作中,事务是一种重要的概念,它可以将一系列操作作为一个不可分割的单位进行执行。
通过使用事务,在多个操作中保持数据一致性变得更加可靠。
事务支持ACID(原子性、一致性、隔离性和持久性)的特性,通过对数据的加锁、回滚、提交等操作,确保了数据操作的可靠性和一致性。
2. 锁机制锁机制是保证数据一致性的重要手段之一。
通过在数据操作时对相应的数据对象加锁,在进行更新操作时,只有持有锁的事务才能进行操作。
这样可以避免多个事务同时对同一个数据对象进行修改,导致数据出现冲突和不一致的情况。
3. 影子复制在分布式数据库中,影子复制是一种常用的保证数据一致性的方法。
它通过在多个副本之间进行数据同步,使得多个副本的数据始终保持一致。
当某个副本发生故障时,可以通过备份的副本来恢复数据,避免数据丢失或不一致的情况。
三、数据完整性的重要性数据完整性是指数据库中存储的数据符合预期的规则和要求,不存在破坏数据完整性的行为。
保持数据完整性是数据库技术中的另一个重要任务。
如果数据不完整,会导致错误的计算结果,以及对企业或个人的决策产生误导,进而影响业务的正常运行。
四、保证数据完整性的方法1. 约束数据库中的约束是一种限制数据的规则或条件,用于确保数据满足特定的要求。
分布式系统中的一致性:CAP定理和BASE理论的应用

分布式系统中的一致性:CAP定理和BASE理论的应用随着网络技术的发展,分布式系统越来越成为了一个普遍存在的现象。
然而,在分布式系统中,数据的一致性一直以来都是一个重要的问题。
为了解决这个问题,CAP定理和BASE理论应运而生。
CAP定理:在分布式系统中,CAP定理是最为重要的一条定理。
它指出:在一个分布式系统中,一致性(Consistency)、可用性(Availability)和分区容错性(Partition Tolerance)无法同时保证。
它意味着随着系统的增加,我们需要牺牲其中之一。
在CAP定理中,“一致性”指的是在分布式系统中的数据一致性,即当多个节点访问同一数据时,各个节点所看到的数据都应该是一致的。
这里的“可用性”指的是系统能够在合理的时间内处理请求,即系统能够正常运作,并向用户提供服务。
最后,“分区容错性”指的是系统能够容忍网络分区的情况,即在分布式系统中,有些节点无法与其它节点通信时,仍能够继续工作。
CAP定理指出了在分布式系统中需要牺牲某一方面的情况。
一般来说,为了保证分布式系统的高可用性和分区容错性,通常需要牺牲掉数据的一致性。
因此,一般情况下我们只能在一致性和可用性之间做出权衡。
随着技术的不断改进,我们可以采用多种策略来保证分布式系统的一致性和可用性。
例如,引入数据分片技术、采用异步复制等技术,从而提高分布式数据库的可用性和分区容错性。
BASE理论:另一方面,BASE理论是对CAP定理的补充。
它指出,最终一致性是可以被接受的,而不是强一致性。
而“BASE”其实是三个英文单词的缩写:Basically Available(基本可用)、Soft-state(软状态)和Eventually Consistent(最终一致性)。
它是为了解决ACID模型无法解决的高可扩展性和高性能的问题,而被引入的一个适用于大规模分布式系统的数据存储架构理论。
在BASE理论中,基本可用指的是系统在没有故障的前提下,可以保证基本的可用性,即响应时间不会无限延长,能够正常的响应请求。
数据一致性算法

数据⼀致性算法最近⼯作中遇到了数据⼀致性问题,为⽅便以后使⽤,特学习记录⼀下:⽬前遇到现象:(1)缓存与数据库数据不⼀致情况(2)分布式系统中各节点数据不⼀致情况原因:并发情况下,执⾏顺序会引起写请求和读请求拿到的数据不⼀致,导致脏读、幻读等。
解决⽅案:(1)针对本地缓存与数据库数据不⼀致问题,可以通过先更新数据库后删除缓存+读写分离来解决,具体可参考另⼀篇⽂章《》<1>缓存失效<2>请求A读缓存失败,读数据库<3>请求A写缓存<4>请求B写数据库,删除缓存<5>下个请求读缓存失败,写缓存为什么不会出现3/4步骤对调的情况,主要是数据库的读操作远快于写操作且读写分离的⼀个实现。
如果还有担⼼会对调可⽤消息中间件进⾏处理。
(2)针对分布式数据不⼀致问题,⼀致性哈希算法,将数据存储在不同的机器上原理1)⼀致性哈希将整个哈希值空间组织成⼀个虚拟的圆环,如某哈希函数H的值空间为0-2^32-1(即哈希值是⼀个32位⽆符号整形),整个哈希空间环起点和终点分别是0和2^32-1。
2)空间制定:整个空间按顺时针⽅向组织。
0和232-1在零点中⽅向重合。
3)服务器节点位置:将分布式各个服务器使⽤Hash进⾏⼀个哈希,具体可以选择服务器的ip或主机名作为关键字进⾏哈希,这样每台机器就能确定其在哈希环上的位置。
数据倾斜问题优化:可对每个服务器进⾏多个hash以保证机器节点的均衡分布。
4)数据节点位置:将数据key使⽤相同的函数Hash计算出哈希值,并确定此数据在环上的位置,从此位置沿环顺时针“⾏⾛”,第⼀台遇到的服务器就是其应该定位到的服务器。
实操1. hash值计算:通过⽀持MD5与MurmurHash两种计算⽅式。
2. ⼀致性的实现:通过java的TreeMap来模拟环状结构,实现均匀分布 1.hash计算⽅法:MD5import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;/** 实现⼀致性哈希算法中使⽤的哈希函数,使⽤MD5算法来保证⼀致性哈希的平衡性*/public class HashFunction {private MessageDigest md5 = null;public long hash(String key) {if (md5 == null) {try {md5 = MessageDigest.getInstance("MD5");} catch (NoSuchAlgorithmException e) {throw new IllegalStateException("no md5 algrithm found");}}md5.reset();md5.update(key.getBytes());byte[] bKey = md5.digest();//具体的哈希函数实现细节--每个字节 & 0xFF 再移位long result = ((long) (bKey[3] & 0xFF) << 24)| ((long) (bKey[2] & 0xFF) << 16| ((long) (bKey[1] & 0xFF) << 8) | (long) (bKey[0] & 0xFF));return result & 0xffffffffL;}}2.环的定义for (int i = 0; i < numberOfReplicas; i++) {// 对于⼀个实际机器节点 node, 对应 numberOfReplicas 个虚拟节点/** 不同的虚拟节点(i不同)有不同的hash值,但都对应同⼀个实际机器node* 虚拟node⼀般是均衡分布在环上的,数据存储在顺时针⽅向的虚拟node上*/circle.put(hashFunction.hash(node.toString() + i), node);}3.数据hash映射关系确定if (!circle.containsKey(hash)) {//数据映射在两台虚拟机器所在环之间,就需要按顺时针⽅向寻找机器SortedMap<Long, T> tailMap = circle.tailMap(hash);hash = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey();}4.测试package erbuss;import java.util.*;public class ConsistentHash<T> {private HashFunction hashFunction;private int numberOfReplicas;// 节点的复制因⼦,实际节点个数 * numberOfReplicas = 虚拟节点个数private final SortedMap<Long, T> circle = new TreeMap<Long, T>();// 存储虚拟节点的hash值到真实节点的映射 public ConsistentHash(HashFunction hashFunction, int numberOfReplicas,Collection<T> nodes) {this.hashFunction = hashFunction;this.numberOfReplicas = numberOfReplicas;for (T node : nodes) {add(node);}}public void add(T node) {for (int i = 0; i < numberOfReplicas; i++)// 对于⼀个实际机器节点 node, 对应 numberOfReplicas 个虚拟节点/** 不同的虚拟节点(i不同)有不同的hash值,但都对应同⼀个实际机器node* 虚拟node⼀般是均衡分布在环上的,数据存储在顺时针⽅向的虚拟node上*/circle.put(hashFunction.hash(node.toString() + i), node);}public void remove(T node) {for (int i = 0; i < numberOfReplicas; i++)circle.remove(hashFunction.hash(node.toString() + i));}/** 获得⼀个最近的顺时针节点,根据给定的key 取Hash* 然后再取得顺时针⽅向上最近的⼀个虚拟节点对应的实际节点* 再从实际节点中取得数据*/public T get(Object key) {if (circle.isEmpty())return null;long hash = hashFunction.hash((String) key);// node ⽤String来表⽰,获得node在哈希环中的hashCodeif (!circle.containsKey(hash)) {//数据映射在两台虚拟机器所在环之间,就需要按顺时针⽅向寻找机器SortedMap<Long, T> tailMap = circle.tailMap(hash);hash = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey();}return circle.get(hash);}public long getSize() {return circle.size();}/** 查看MD5算法⽣成的hashCode值---表⽰整个哈希环中各个虚拟节点位置*/public void testBalance(){Set<Long> sets = circle.keySet();//获得TreeMap中所有的KeySortedSet<Long> sortedSets= new TreeSet<Long>(sets);//将获得的Key集合排序System.out.println("[1]节点为: ----");for(Long hashCode : sortedSets){System.out.print(hashCode);System.out.print(",");}System.out.println("----");System.out.println("[2]节点间距为: ----");/** 查看⽤MD5算法⽣成的long hashCode 相邻两个hashCode的差值*/Iterator<Long> it = sortedSets.iterator();Iterator<Long> it2 = sortedSets.iterator();if(it2.hasNext())it2.next();long keyPre, keyAfter;while(it.hasNext() && it2.hasNext()){keyPre = it.next();keyAfter = it2.next();System.out.print(keyAfter - keyPre);System.out.print(",");}System.out.println("----");}//根据key查找对应的节点public String getNodeForKey(String key) {long hash = hashFunction.hash(key);if (!circle.containsKey(hash)) {//数据映射在两台虚拟机器所在环之间,就需要按顺时针⽅向寻找机器SortedMap<Long, T> tailMap = circle.tailMap(hash);hash = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey();}return circle.get(hash)+",hash为:"+hash;}public static void main(String[] args) {Set<String> nodes = new HashSet<String>();nodes.add("A");nodes.add("B");nodes.add("C");ConsistentHash<String> consistentHash = new ConsistentHash<String>(new HashFunction(), 2, nodes); System.out.println("hash circle size: " + consistentHash.getSize());consistentHash.testBalance();System.out.println("[3]数据分配情况为: ----");for (int i = 0; i < 10; i++){String Key="user_" + i;System.out.println("Key:"+i+"分配到的Server为:"+consistentHash.getNodeForKey(Key));}//新加⼀节点consistentHash.add("D");System.out.println("hash circle size: " + consistentHash.getSize());consistentHash.testBalance();System.out.println("[3]数据分配情况为: ----");for (int i = 0; i < 10; i++){String Key="user_" + i;System.out.println("Key:"+i+"分配到的Server为:"+consistentHash.getNodeForKey(Key));}//删除⼀节点consistentHash.remove("A");System.out.println("hash circle size: " + consistentHash.getSize());consistentHash.testBalance();System.out.println("[3]数据分配情况为: ----");for (int i = 0; i < 10; i++){String Key="user_" + i;System.out.println("Key:"+i+"分配到的Server为:"+consistentHash.getNodeForKey(Key));}}}结果hash circle size: 6[1]节点为: ----748451404,769404186,1696944585,1830063320,3862426151,3864615324,----[2]节点间距为: ----20952782,927540399,133118735,2032362831,2189173,----[3]数据分配情况为: ----Key:0分配到的Server为:B,hash为:748451404Key:1分配到的Server为:B,hash为:1696944585Key:2分配到的Server为:A,hash为:1830063320Key:3分配到的Server为:A,hash为:3862426151Key:4分配到的Server为:A,hash为:3862426151Key:5分配到的Server为:B,hash为:748451404Key:6分配到的Server为:A,hash为:3862426151Key:7分配到的Server为:B,hash为:748451404Key:8分配到的Server为:B,hash为:748451404Key:9分配到的Server为:A,hash为:3862426151hash circle size: 8[1]节点为: ----748451404,769404186,1696944585,1830063320,3372629518,3766042698,3862426151,3864615324,----[2]节点间距为: ----20952782,927540399,133118735,1542566198,393413180,96383453,2189173,----[3]数据分配情况为: ----Key:0分配到的Server为:B,hash为:748451404Key:1分配到的Server为:B,hash为:1696944585Key:2分配到的Server为:A,hash为:1830063320Key:3分配到的Server为:D,hash为:3372629518Key:4分配到的Server为:D,hash为:3372629518Key:5分配到的Server为:B,hash为:748451404Key:6分配到的Server为:D,hash为:3766042698Key:7分配到的Server为:B,hash为:748451404Key:8分配到的Server为:B,hash为:748451404Key:9分配到的Server为:D,hash为:3372629518hash circle size: 6[1]节点为: ----748451404,769404186,1696944585,3372629518,3766042698,3864615324,----[2]节点间距为: ----20952782,927540399,1675684933,393413180,98572626,----[3]数据分配情况为: ----Key:0分配到的Server为:B,hash为:748451404Key:1分配到的Server为:B,hash为:1696944585Key:2分配到的Server为:D,hash为:3372629518Key:3分配到的Server为:D,hash为:3372629518Key:4分配到的Server为:D,hash为:3372629518Key:5分配到的Server为:B,hash为:748451404Key:6分配到的Server为:D,hash为:3766042698Key:7分配到的Server为:B,hash为:748451404Key:8分配到的Server为:B,hash为:748451404Key:9分配到的Server为:D,hash为:3372629518从上⾯执⾏结果可以看出哈希⼀致性算法的优势,对于删除节点或新增节点仅影响对于⽚区内的。
数据库一致性理解

数据库⼀致性理解本⽂摘⾃知乎:原⼦性:记录之前的版本,允许回滚⼀致性:事务开始和结束之间的中间状态不会被其他事务看到隔离性:适当的破坏⼀致性来提升性能与并⾏度例如:最终⼀致~=读未提交。
持久性:每⼀次的事务提交后就会保证不会丢失----------------------------------------------------------------------------------------------------------------------------------------------------------------------------讲道理定义:数据库⼀致性(Database Consistency)是指事务执⾏的结果必须是使数据库从⼀个⼀致性状态变到另⼀个⼀致性状态。
数据库状态如何变化?每⼀次数据变更就会导致数据库的状态迁移。
如果数据库的初始状态是C0,第⼀次事务T1的提交就会导致系统⽣成⼀个SYSTEM CHANGE NUMBER(SCN),这是数据库状态从C0转变成C1。
执⾏第⼆个事务T2的时候数据库状态从T1变成T2,以此类推,执⾏第Tn次事务的时候数据库状态由C(n-1)变成Cn。
定义⼀致性主要有2个⽅⾯,⼀致读和⼀致写。
⼀致写:事务执⾏的数据变更只能基于上⼀个⼀致的状态,且只能体现在⼀个状态中。
T(n)的变更结果只能基于C(n-1),C(n-2), ...C(1)状态,且只能体现在C(n)状态中。
也就是说,⼀个状态只能有⼀个事务变更数据,不允许有2个或者2个以上事务在⼀个状态中变更数据。
⾄于具体⼀致写基于哪个状态,需要判断T(n)事务是否和T(n-1),T(n-2),...T(1)有依赖关系。
⼀致读:事务读取数据只能从⼀个状态中读取,不能从2个或者2个以上状态读取。
也就是T(n)只能从C(n-1),C(n-2)... C(1)中的⼀个状态读取数据,不能⼀部分数据读取⾃C(n-1),⽽另⼀部分数据读取⾃C(n-2)。
数据可靠性与一致性:保证数据操作的正确性

数据可靠性与一致性:保证数据操作的正确性数据可靠性与一致性是数据库中非常重要的概念,用于保证数据操作的正确性。
在数据库中,数据的可靠性与一致性指的是在任何操作过程中,数据库中数据的完整性和准确性都能得到保证。
首先,数据可靠性指的是数据库中的数据能够得到保护,不会因为任何意外事件而丢失或损坏。
这包括了对数据库进行备份和恢复,以及对数据库进行错误处理和事务管理等机制。
通过定期备份数据库,可以避免因为软硬件故障或者灾难事件导致的数据丢失。
同时,在进行数据恢复的过程中,可以通过数据恢复机制保证数据的完整性和准确性。
此外,在进行错误处理和事务管理的过程中,可以通过错误处理和事务管理机制保证数据的完整性和准确性。
通过这些机制,可以保证数据库中的数据能够得到保护,不会因为任何意外事件而丢失或损坏。
其次,数据一致性指的是数据库中的数据在任何时刻都能够保持一致。
在数据库中,数据一致性主要通过数据约束和并发控制机制来实现。
数据约束是一种在数据库中定义的规则,用于限制和保护数据的完整性和准确性。
通过在数据库中定义数据约束,可以限制对数据库的非法操作,保证数据库中的数据始终保持一致。
并发控制机制是一种保证多个用户并发访问数据库时数据一致性的机制。
通过并发控制机制,可以确保多个用户的并发操作不会导致数据的冲突和不一致。
通过这些机制,可以保证数据在任何时刻都能够保持一致。
数据可靠性和一致性是数据库中非常重要的概念,对于保证数据操作的正确性具有至关重要的作用。
通过保证数据的可靠性和一致性,可以避免数据丢失和损坏,保证数据的完整性和准确性,降低数据操作的风险,提高数据的可靠性和一致性。
总结起来,数据可靠性与一致性是数据库中保证数据操作的正确性的重要概念。
数据可靠性主要通过备份恢复、错误处理和事务管理等机制来实现,数据一致性主要通过数据约束和并发控制机制来实现。
通过保证数据的可靠性和一致性,可以提高数据操作的正确性,保证数据的完整性和准确性,降低数据操作的风险,提高数据的可靠性和一致性。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2.1 数据一致性模型
一些分布式系统通过复制数据来提高系统的可靠性和容错 性,并且将数据的不同的副本存放在不同的机器,由于维护 数据副本的一致性代价高,因此许多系统采用若一致性来提 高性能,一些不同的一致性模型也相继被提出。 强一致性:要求无论更新操作是在哪一个副本执行,之后 所有的读操作都要能获得最新的数据。 弱一致性:用户读到某一操作对系统特定数据的更新需要一 段时间,我们称这段时间为“不一致性窗口”。 最终一致性:是弱一致性的一种特例,保证用户最终能够读 取到某操作对系统特定数据的更新。
ACID和BASE的比较
ACID 强一致性 隔离性 采用悲观、保守方法 难以改变
BASE 若一致性 可用性优先 采用乐观方法 适应变化、更简单、更快
2.4 数据一致性实现技术
2.4.1 Quorum系统NRW策略 这个协议有三个关键值N、R、W。 N表示数据所具有的副本数。 R表示完成读操作所需要读取的最小副本数,即一次读操作 所需参与的最小节点数目。 W表示完成写操作所需要写入的最小副本数,即一次写操作 所需要参与的最小节点数目。 该策略中,只需要保证R+W>N,就可以保证强一致性。
下面我们来说明该系统是如何满足C1和C2条件的。 对于C1条件来说,系统需要满足下面的实现规则。 IR1:对于同一节点上任意的连续事件来说,该节点上的时 钟只需要保证较晚发生事件的时钟值大于较早发生事件的时 钟值即可。 对于C2条件来说,系统需要满足下面的实现规则。 IR2:(a)如果事件a代表节点Ni发送消息m,那么消息m将 携带时间戳Tm,且Tm=Ci(a);(b)当节点Nj接收消息m后,节点 将设置该事件的时钟Cj大于或等于该节点上一事件的时钟并 且大于或等于Tm。
2.4.2 两阶段提交协议
在两阶段提交协议中,系统包含两类机器(或节点):一类 为协调者,通常一个系统中只有一个;另一类为事务参与者, 一般包含多个,在数据存储系统中可以理解为数据副本的个 数。 阶段1:请求阶段 在请求阶段,协调者将通知事务参与者准备提交或取消事务, 然后进入表决过程。在表决过程中,参与者将告知协调者自 己的决策:同意或取消。 阶段2:提交阶段 协调者将第一阶段投票结果进行表决,当且仅当所有的参与 者同意提交,事务协调者才通知所有的参与者提交事务。参 与者在接收到协调者发来的消息后将执行相应操作。
2.3 ACID与BASE
BASE方法通过牺牲一致性和孤立性来提高可用性和系统性能, 其中BASE分别代表: 基本可用(Basically Available):系统能够基本运行、 一直提供服务。 软状态(Soft-state):系统不要求一直保持强一致状态。 最终一致性(Eventual consistency):系统需要在某一 时刻后达到一致性要求。
CAP是在分布式环境中设计和部署系统时所要考虑的三个重要 的系统需求。根据CAP理论,数据共享系统只能满足这三个特 性中两个,而不能同时满足三个条件。因此系统设计者必须在 这三个特征之间做出权衡。 根据CAP理论,系统满足三个条件中不同的两个条件会具有不 同的特点。如下表所示:
序号 1 2 3 选择 C、A C、P A、P 特点 两阶段提交、缓存验证协议 悲观加锁 冲突处理、乐观 例子 oda
逻辑时钟 这里为每一进程Pi定义一个时钟Ci,该时钟能够为任意一个 事件a分配一个时钟:Ci(a)。在全局上,同样存在一个时钟 C,对于事件b,该时钟能够分配一个时钟值C(b),并且如 果事件b发生在进程Pi上,那么C(b)=Ci(b)。 时钟条件:如果对于事件a和事件b,a->b,那么C(a)<C(b)。 以下两个限制条件满足实际情况。 C1:如果事件a和事件b是同一个进程Pi中的事件,并且a在b 之前发生,那么:Ci(a)<Ci(b) C2:如果a为进程Pi上某消息发送事件,b为进程Pj上消息接 收事件,那么:Ci(a)<Ci(b)
数据一致性理论
2.1 CAP理论
CAP理论由Eric Brewer在ACM PODC会议上的主题报告中提 出,这个理论是NoSQL数据库管理系统构建的基础,如下图所 示:
其中字母“C”,”A”,”P”分别代表以下三个特征: 强一致性(Consistency)。系统在执行过某项操作后仍然 处于一致的状态。在分布式系统中,更新操作执行成功后所 有的用户都应该读取到最新值。 可用性(Availability)。每一个操作总是能够在一定时 间内返回结果。需要注意“一定时间”和“返回结果”。 “一定时间”是指,系统结果必须在给定时间内返回。 “返回结果”是指系统返回操作成功或失败的结果。 分区容错性(Partition Tolerance)。分区容错性可以理 解为系统在存在网络分区的情况下仍然可以接受请求(满足 一致性和可用性)。
R和W的设置直接影响系统的性能、扩展性与一致性。
下面为不同设置的几种特殊情况。
1.当W=1,R=N时,系统对写操作有较高的要求,但读操作会 比较慢,若N个节点中有节点发生故障,那么读操作将不能 完成。 2.当R=1,W=N时,系统对读操作有较高性能、高可用,但写 操作性能较低,用于需要大量读操作的系统,若N个节点中 有节点发生故障,那么写操作将不能完成。 3.当R=Q,W=Q(Q=N/2+1)时,系统在读写性能之间取得平衡, 兼顾了性能和可用性。
2.4.3 时间戳策略
时间戳策略在关系数据库中有广泛应用,该策略主要用于关 系数据库日志系统中记录事务操作,以及数据恢复时的 Undo/Redo等操作。在并行系统中,时间戳策略有更加广泛的 应用。 我们用分布式系统中事件的先后关系,用 “->”符号来表示, 例如:若事件a发生在事件b之前,那么a->b。 该关系需要满足下列三个条件: 如果a和b是同一进程中的事件,a在b之前发生,则a->b。 如果事件a是消息发送方,b是接受方,则a->b。 对于事件a、b、c,如果有a->b,b->c,则有a->c。
事务是用户定义的一个数据库操作序列,要么全不做,要么 全做,是一个不可分割的工作单位,ACID是事务所具有的特 性。 原子性(Atomicity):事务中的操作要么全做,要么不做。 一致性(Consistency):系统必须始终处在强一致状态下。 隔离性(Isolation):一个事务的执行不能被其他事务所 干扰。 持续性(Durability):一个已提交的事务对数据库中数 据的改变是永久性的。 保证ACID特性是传统关系型数据库中事务管理的重要任务, 也是恢复和并发控制的基本单位。