当前位置:首页 » 服务存储 » 存储系统一致满足的条件
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

存储系统一致满足的条件

发布时间: 2022-11-05 10:18:47

‘壹’ 在多级结构的存储器系统中,何谓信息的一致性原则和包含性原则

一致性原则:同一个信息会同时存放在几个级别的存储器中,此时,这一信息在几个级别 的存在.

‘贰’ 存储器的主要功能是什么为什么要把存储系统分成若干个不同层次

一、存储器的主要功能:

1、随机存取存储器(RAM)。

2、只读存储器(ROM)。

3、闪存(Flash Memory)。

4、先进先出存储器(FIFO)。

5、先进后出存储器(FILO)。

二、存储器分为若干个层次主要原因:

1、合理解决速度与成本的矛盾,以得到较高的性能价格比。

磁盘存储器价格较便宜,可以把容量做得很大,但存取速度较慢,因此用作存取次数较少,且需存放大量程序、原始数据(许多程序和数据是暂时不参加运算的)和运行结果的外存储器。

2、使用磁盘作为外存,不仅价格便宜,可以把存储容量做得很大,而且在断电时它所存放的信息也不丢失,可以长久保存,且复制、携带都很方便。

(2)存储系统一致满足的条件扩展阅读:

存储器可做处理器,未来装置有望更加轻薄短小:

有一群跨国研究团队做了实验,并真的成功运用存储器执行一般电脑芯片的运算任务,倘若技术成熟,将有望使手机与电脑等装置更加轻薄。

新加坡南洋理工大学、德国亚琛阿亨工业大学和欧洲最大的跨学科研究中心德国尤利希研究中心组成的研究团队发现,在调整算法后,存储器能如英特尔、高通等传统处理器一般,进行运算处理。

目前市面上的装置或电脑都是透过CPU从存储器提取资讯进行运算处理,以二进制0跟1来实现指令,如字母A是用“01000001”这样8位元的形式来处理或纪录。而存储器ReRAM透过不同电阻态代表0或1的数据状态储存资讯,其实还可实现更高基数的数据状态记录。

研究团队就将ReRAM原型(prototype)调整为0、1、2的三进制,透过这样的高基数运算系统可加速运算任务,并于存储器就可进行逻辑运算。也节省了处理器与存储器间数据传输的时间与功耗的消耗。

研究参与人之一、南洋理工大学资讯工程学系助理教授Chattopadhyay解释,这就像一段很长的会话却只用一个极小的翻译器来转换,是一段耗时且费力的过程,团队所做的就是增加这个小型翻译器的处理容量,使其能更有效的处理数据。

‘叁’ 什么是存储系统

存储系统是指计算机中由存放程序和数据的各种存储设备、控制部件及管理信息调度的设备(硬件)和算法(软件)所组成的系统。计算机的主存储器不能同时满足存取速度快、存储容量大和成本低的要求,在计算机中必须有速度由慢到快、容量由大到小的多级层次存储器,以最优的控制调度算法和合理的成本,构成具有性能可接受的存储系统。

‘肆’ 作为一个存储元必须满足哪些条件

存储单元:多个存储元的集合

一般应具有存储数据和读写数据的功能,以8位二进制作为一个存储单元,也就是一个字节。每个单元有一个地址,是一个整数编码,可以表示为二进制整数。程序中的变量和主存储器的存储单元相对应。变量的名字对应着存储单元的地址,变量内容对应着单元所存储的数据。存储地址一般用十六进制数表示,而每一个存储器地址中又存放着一组二进制(或十六进制)表示的数,通常称为该地址的内容。

存储单位:在存储器中有大量的存储元,把它们按相同的位划分为组,组内所有的存储元同时进行读出或写入操作,这样的一组存储元称为一个存储单元。一个存储单元通常可以存放一个字节;存储单元是CPU访问存储器的基本单位。

存储单元
在计算机中最小的信息单位是bit,也就是一个二进制位,8个bit组成一个Byte,也就是字节。一个存储单元可以存储一个字节,也就是8个二进制位。计算机的存储器容量是以字节为最小单位来计算的,对于一个有128个存储单元的存储器,可以说它的容量为128字节。如果有一个1KB的存储器则它有1024个存储单元,它的编号为从0-1023。存储器被划分成了若干个存储单元,每个存储单元都是从0开始顺序编号,如一个存储器有128个存储单元,则它的编号就是从0-127。

存储地址一般用十六进制数表示,而每一个存储器地址中又存放着一组二进制(或十六进制)表示的数,通常称为该地址的内容。值得注意的是,存储单元的地址和地址中的内容两者是不一样的。前者是存储单元的编号,表示存储器中的一个位置,而后者表示这个位置里存放的数据。正如一个是房间号码,一个是房间里住的人一样。
存放一个机器字的存储单元,通常称为字存储单元,相应的单元地址叫字地址。而存放一个字节的单元,称为字节存储单元,相应的地址称为字节地址。如果计算机中可以编址的最小单元是字存储单元,则该计算机称为按字寻址的计算机。如果计算机中可编址的最小单位是字节,则该计算机称为按字节寻址的计算机。如果机器字长等于存储器单元的位数,一个机器字可以包含数个字节,所以一个存储单元也可以包含数个能够单独编址的字节地址。例如一个16位二进制的字存储单元可存放两个字节,可以按字地址寻址,也可以按字节地址寻址。当用字节地址寻址时,16位的存储单元占两个字节地址

‘伍’ 大数据对存储平台有哪些特殊要求

伴随着安防大数据时代的来临,安防行业原有的存储技术已经无法满足行业发展新需求,尤其是公共安全视频监控建设联网应用工作对数据联网共享提出了更高的要求,同时以“实战”为根本的公安业务中,大数据深度挖掘极度依赖数据存储系统对非结构化数据分析再处理。云存储技术的出现,在安防行业大数据发展时代无异于革命性的应用,不断地解决了安防存储难题,同时也为视频监控的深度应用与发展提供强大的驱动力。

当今世界,每个人的一言一行都在产生着数据,并且被记录着。各行各业爆炸式增长的数据,正推动人类进入大数据时代。根据相关统计,2017年全球的数据总量为21.6ZB,目前全球数据的增长速度在每年40%左右,预计到2020年全球的数据总量将达到40ZB。数据增长在安防行业表现得尤为明显,在近两年“平安城市”、“ 智能交通”、“ 雪亮工程”等不断开展和深入的过程中,以视频监控为核心代表的行业发展正朝着超高清、智能化和融合应用的方向迈进,系统性工程中现有视频监控系统数据采集量正在呈线性增长。海量数据的出现对高效、及时的存储和处理的要求不断提升。  

从目前行业来看,大数据时代的到来,系统性工程中视频监控系统对存储主要有以下几方面的需求:  

一是海量数据及时高效存储,根据现行的技防法规及标准,一般应用领域视频监控系统数据采集是7x24小时不间断的,系统采集的音视频信息资料留存时限不得少于30日,针对案(事)件信息以及一些特殊应用领域视音频资料存放时间更长,甚至长期保留,数据量随时间增加呈线性增长。  

二是监控数据存储系统需要具备可扩展性,不但满足海量数据持续增加,还需要满足采集更高分辨率或更多采集点的数据需要。  

三是对存储系统的性能要求高。与其他领域不同,视频监控主要是视频码流的存储,在多路并发存储的情况下,对带宽、数据能力、缓存等都有很高的要求,需要有专门针对视频性能的优化处理。  

四是大数据应用需要数据存储的集中管理分析。但现实情况却恰恰相反,一方面是系统性工程在分期建设的过程中,采购的设备并不能保证为同一品牌,实际项目中多种品牌、多种型号比比皆是,给视频监控的存储集中管理带来很大难度。同时,在一些大型的项目中,例如特大城市“天网工程”,高速公路中道路监控所跨区域较大,集中存储较为困难。另外,受网络带宽及老旧设备影响,系统难以形成统一存储、统一监控的中心体系架构,导致数据在应用中调取不及时。  

总体来看,随着系统性安防项目的深入开展以及物联网建设初露峥嵘,大规模联网监控的建设和高清监控的逐步普及,海量视频数据已经呈现井喷式地增长,并冲击着传统的存储系统,遗憾的是原有的存储系统无法满足大数据时代提出的新要求,亟需新的存储技术支撑现有业务模式,同时为人工智能技术在安防领域施展拳脚拓展新的空间。

‘陆’ 构造虚拟储存器必须具备哪些条件

cache存储器、主存和辅存是构成虚拟存储器的重要部分,cache和主存构成了系统的内存,而主存和辅存依靠辅助软硬件的支持构成了虚拟存储器。
一、异构体系

从虚存的概念可以看出,主存-辅存的访问机制与cache-主存的访问机制是类似的。这是由cache存储器、主存和辅存构成的三级存储体系中的两个层次。cache和主存之间以及主存和辅存之间分别有辅助硬件和辅助软硬件负责地址变换与管理,以便各级存储器能够组成有机的三级存储体系。cache和主存构成了系统的内存,而主存和辅存依靠辅助软硬件的支持构成了虚拟存储器。
在三级存储体系中,cache-主存和主存-辅存这两个存储层次有许多相同点:
(1)出发点相同:二者都是为了提高存储系统的性能价格比而构造的分层存储体系,都力图使存储系统的性能接近高速存储器,而价格和容量接近低速存储器。
(2)原理相同:都是利用了程序运行时的局部性原理把最近常用的信息块从相对慢速而大容量的存储器调入相对高速而小容量的存储器。
但cache-主存和主存-辅存这两个存储层次也有许多不同之处:
(1)侧重点不同:cache主要解决主存与CPU的速度差异问题;而就性能价格比的提高而言,虚存主要是解决存储容量问题,另外还包括存储管理、主存分配和存储保护等方面。
(2)数据通路不同:CPU与cache和主存之间均有直接访问通路,cache不命中时可直接访问主存;而虚存所依赖的辅存与CPU之间不存在直接的数据通路,当主存不命中时只能通过调页解决,CPU最终还是要访问主存。
(3)透明性不同:cache的管理完全由硬件完成,对系统程序员和应用程序员均透明;而虚存管理由软件(操作系统)和硬件共同完成,由于软件的介入,虚存对实现存储管理的系统程序员不透明,而只对应用程序员透明(段式和段页式管理对应用程序员"半透明")。
(4)未命中时的损失不同:由于主存的存取时间是cache的存取时间的5~10倍,而主存的存取速度通常比辅存的存取速度快上千倍,故主存未命中时系统的性能损失要远大于cache未命中时的损失。
二、关键问题

(1)调度问题:决定哪些程序和数据应被调入主存。
(2)地址映射问题:在访问主存时把虚地址变为主存物理地址(这一过程称为内地址变换);在访问辅存时把虚地址变成辅存的物理地址(这一过程称为外地址变换),以便换页。此外还要解决主存分配、存储保护与程序再定位等问题。
(3)替换问题:决定哪些程序和数据应被调出主存。
(4)更新问题:确保主存与辅存的一致性。
在操作系统的控制下,硬件和系统软件为用户解决了上述问题,从而使应用程序的编程大大简化。
三、工作原理

虚拟存储器是由硬件和操作系统自动实现存储信息调度和管理的。它的工作过程包括6个步骤:
①中央处理器访问主存的逻辑地址分解成组号a和组内地址b,并对组号a进行地址变换,即将逻辑组号a作为索引,查地址变换表,以确定该组信息是否存放在主存内。
②如该组号已在主存内,则转而执行④;如果该组号不在主存内,则检查主存中是否有空闲区,如果没有,便将某个暂时不用的组调出送往辅存,以便将这组信息调入主存。
③从辅存读出所要的组,并送到主存空闲区,然后将那个空闲的物理组号a和逻辑组号a登录在地址变换表中。
④从地址变换表读出与逻辑组号a对应的物理组号a。
⑤从物理组号a和组内字节地址b得到物理地址。
⑥根据物理地址从主存中存取必要的信息。

‘柒’ 作为一个存储元必须满足哪些条件

1,动态性
当数据对象从数据库中以任何给定顺序的命令,如插入或删除时,存取方法应该可以持续地保持其变迁轨迹。
2.第二/第三级的存储管理
尽管主存在不断增长,但在主存中不可能存放整个数据库。因此,存取方法需具备自动访问第二/三级存储设备的能力。
3。支持多种运算
存取方法应不支持有损其他运算(如删除)的运算(如查询)。
4.输入数据的独立性
当输入数据有偏差时,存取方法应保持它们的效率。这一点对在不同维上分布不同的数据是非常重要的。
5简单性
在特殊情况下,错综复杂的访问方法经常会出错,因此在大规模的应用中不要求有足够的鲁棒性。
6.扩展性
存取方法应适应未来数据库的增长。
7.时间效率
空间查找应当是快速的。一个主要的设计目标是需要满足一维B一树的性能特征:首先,忽略数据的插入顺序,对于所有可能的输入数据的分布,存取方法应当在最坏情况下的查找性能保证是对数级的。其次,最坏条件的性能应当对所有d维属性的任意组合都能保持一致。
8空间效率
一个索引占用的空间应比索引指向的存储数据所占用的空间要小,因此可保证存储数据的有效应用。
9.同步性和恢复性
在现代数据库中,多个用户同时在对数据库更新、恢复及插入数据,存取方法应提供鲁棒性的技术对这些处理予以支持,这时高效率就处于次要地位。
10 最小的影响
将访问方法集成到一个数据库系统中,对系统中的现有功能影响最小。

‘捌’ 浅析 Haystack 图片存储系统

Facebook在2010年的时候发表过一篇在分布式存储系统领域很有名的一篇文章《Finding a needle in Haystack》来描述他们的图片存储系统,Haystack 存储了超过2600亿张图片,大约占了20TB的数据,用户每周都会上传10亿张图片,高峰时期的并发量在100万以上(这是2010年的数据,现在很有可能上了一个数量级)。

在这个数量级之下,需要考虑的问题不仅仅是高吞吐,低延时,保证数据的一致性,还要考虑如何能节省流量,容易扩展,容错等等。下面我们就来看下Haystack是怎样满足这些分布式系统的要素的。

图片存储系统的最大特点是数据只写一次,读取频繁,不会修改,很少删除。Facebook 一开始的存储系统是基于NFS的NAS(Network Attached Storage), 但这种基于 POSIX 的文件系统无法支撑如此大的负载。其中主要的问题在于在图片寻址的过程中会产生过多的磁盘操作。

我们知道从传统文件系统里面读取一个文件需要至少三次磁盘操作,第一次从硬盘中读取目录的 metadata 到内存中,然后读取inode到内存,最后才从磁盘中读取文件内容。

再者这些metadata里面包含了大量比如权限控制这些对于图片存储系统来说无用的信息,也浪费了大量的磁盘空间。当像图片这样的静态资源服务出现瓶颈的时候,自然就会想到使用 CDN (Content Delivery Networks) 系统。在传统的设计中,一个图片的 HTTP 请求发送后, 如果 CDN 有这个资源的缓存,就会立马返回,反之 ,CDN 会将根据请求的 URL 从存储系统里面读取图片,更新缓存,然后再返回。在这样的设计中,CDN 确实可以很有效地处理热点图片的请求。

但像 Facebook 这样的社交网络中,有大量的请求是针对那些非热点或者老内容的,用户在请求那些长尾 (long tail) 内容时将没有优化。当然,有些同学会说,那我可以将所有的图片都缓存到 CDN,那确实会解决这个问题,但将会极大地增加资源的开销。

为了减少那些直接 hit 到存储系统的请求的磁盘操作,他们想到在第一次读取文件的时候把filename到 file handle 的映射缓存到内存,在下一次读取文件的时候,会调用自定义的open_by_filehandle来减少磁盘操作,但这对于long tail的读取问题依然存在,因为这些文件的映射关系没有提前放在内存中。

于是,Facebook 决定从头研发图片存储系统,从前面我们可以看出,Haystack 的核心任务就是在处理每一次的请求中尽可能地减少磁盘操作。我们先来描述下 Haystack 读取和上传图片流程是怎样的,然后再来看其中的细节是如何处理的。

当发起一次图片读取请求的时候会通过一个事先构建好的 URL

http://///这个 URL 实际上显示出了访问的顺序,先从外部 CDN 读取,如果没有,访问内部 Cache,如果还是没有,就直接访问 Store Machine.(URL最后一部分提供了图片的唯一标识)

用户上传图片的时候先会上传到 web 服务器, 然后服务器从Directory中找到一个可写的physical volume,最后服务器会给这个图片生成一个唯一ID, 然后写入到这个logical volume 所对应的所有physical volume中。

上面的过程中出现了几个陌生的名词,别着急,我们一个个来看。我们先来介绍 Haystack 的三个主要组件:

Store,Directory,Cache.

Store 是核心组件,负责图片的存储。Store 的容量决定了这个存储系统的容量,整个 Store 组件由很多个 store machine 组成,store machine 的容量又由一系列的 physical volume 决定。

例:要提供 10TB容量,我们可分摊到 100 个 physical volume,每个 physical volume 提供 100 GB 的容量。这时候有的同学会问,那么数据冗余是怎么解决的呢?Haystack 借鉴了普通硬盘中的 logical volume 的概念,将不同机器上的多个 physical

volume 组成了一个虚拟的 logical volume。

当存储一张图片的时候,实际上是存储到了 logical volume 对应的所有 physical volume中。它们之间的映射关系连同其它的metadata都存储在 Directory组件中。每个physicalvolume 中都存储了上百万张图片,可以把它想象成一个巨大的 append-only 文件,然后通过 offset 来访问文件。

我们来详细看下这个文件到底是如何存放的,如何来达到减少磁盘操作目的的。对于每个这样超大的文件,都由一个 superblock 和一系列的 needles 组成,每个 needle 就是每张图片的信息。看下下面这张图,它的结构就一目了然了。

每个needle包含的细节信息有图片ID,图片大小,图片数据等等,还会有数据校验的属性。每个 store machine 都有若干个physical volume大文件, 为了提高检索needles 的速度,在内存里为每个physical volume都维护了一张图片I 到needle之间的映射表。

当store machine接收到读取请求时,首先从内存映射表中找到相应的metadata, 然后通过offset从硬盘中读取到整个needle, 通过数据校验后返回。如果接收到的是上传请求,会把组织好的needle追加到所有对应的physical volume文件中,并且更新内存里的映射表。如果是删除操作的话,我们注意到下图中有个Flags标志位其实就是用来标记是否是删除的状态,这样一来就很简单,直接在这个位置标记好,系统会在后面执行compaction 操作回收这些空间。

讲到这里,一个正常流程的存储过程已经很清楚了。这时候我们就需要考虑分布式系统一个必不可少的特性:容错性。当一个 store machine 宕机的时候,理论上我们可以读取所有的 physical volume 来重新构建内存映射表,但这就需要从磁盘重新读取 TB 级别的数据,显然是非常耗时和不高效的。为了解决这个问题,每个 store machine 为每个 physical volume 都维护了一个索引文件。这个索引文件类似于游戏中的存档点 (checkpoint),它的结构和 physical volume 文件类似,保存了查找每个 needle 所需的属性。为了性能,索引文件是异步更新的(写的时候异步更新,删的时候压根不会更新),这就会带来一个问题:索引文件有可能不是最新的。之前我们提到过,physical volume 文件是一个 append-only 的文件,索引文件也是。所以我们只需要在重启 store machine 的时候,从后向前扫描 physical volume 文件找到那几个没有被索引的文件,加到索引里去就行了。对于被删除的文件,在真正读取完整 needle 数据的时候,通过检查删除标志位来更新内存映射表。

我们之前提到可以使用 CDN 来缓解系统压力,但它无法很好地解决非热点图片的问题,并且如果 CDN 节点出现故障的话,没有 Cache 这一层会对底层的存储系统 Store 产生巨大的压力。Cache 组件主要缓存了最近上传的图片,它的概念很简单,实际上是一个分布式 hash table,通过图片的 ID 为 key 可以找到对应的数据。Cache 接收从 CDN 或者浏览器直接发来的 HTTP 请求,但只有在以下两个条件都满足的情况下才会缓存图片:

1) 请求来自用户浏览器而不是来自 CDN

2) 请求的 store machine 是可写的

这听上去有些费解,条件 1 的原因是如果一个请求在 CDN 缓存中 miss 其实也会在 Cache 中 miss (如果一张图片成为热门的话,那也能在 CDN 找到),条件 2 的原因则是避免让可写的 store machine 进行大量读操作,因为图片通常在刚刚上传后会被大量读取,文件系统通常在只读或者只写而不是既读又写的时候性能比较好。

如果没有 Cache 的话,可写的 store machine 将会同时处理写操作以及大量的读操作,会导致性能的急剧下降。

现在我们只剩下 Directory 组件没有讲了。除了之前我们提到的存储了 physical volume 到 logical volume 的映射关系以及图片 ID 到 logical physical 的映射关系,它还提供负载均衡服务以及为每个操作选择具体的 volume (因为写操作的对象是 logical volume,读操作的对象是 physical volume), 它还决定了一个请求是被 CDN 处理还是被 Cache 处理。Directory 还可以标记逻辑卷的状态,在运维需要或者空间满了的时候可以标记为只读状态。当往 Store 加新机器的时候,这些机器就会标记成可写的,只有可写的机器才能接受图片上传请求。这里有一个细节需要注意,图片 ID 到 logical physical 的映射表肯定无法存放在单机内存,文章中也没有交代具体实现。我们猜想可以使用 MySQL 分片集群和加上 Memcached 集群来实现。总的来讲,Directory 实际上根据 metadata,然后结合各种策略,实现了整个系统的调度器。

本文描述了 Haystack 图片存储系统的主要脉络,当然还有许多细节没有提到,比如整个系统的容错机制,如何实现批量写操作等等。经过这几年的发展,我们相信 Haystack 肯定也进行了更多的优化,现在一些开源的分布式存储系统也被应用到实际的生产系统中,比如淘宝的 TFS,MooseFS 等等。我们会在后续的文章中比较这些系统之间的异同,总结出解决其中典型问题的通用方法。

‘玖’ 存储器是怎么存储东西的 到现在都不明白存储器是怎么存储的 现在都不知道为什么

硬盘是现在计算机上最常用的存储器之一。我们都知道,计算机之所以神奇,是因为它具有高速分析处理数据的能力。而这些数据都以文件的形式存储在硬盘里。不过,计算机可不像人那么聪明。在读取相应的文件时,你必须要给出相应的规则。这就是分区概念。分区从实质上说就是对硬盘的一种格式化。当我们创建分区时,就已经设置好了硬盘的各项物理参数,指定了硬盘主引导记录(即Master Boot Record,一般简称为MBR)和引导记录备份的存放位置。而对于文件系统以及其他操作系统管理硬盘所需要的信息则是通过以后的高级格式化,即Format命令来实现。

面、磁道和扇区

硬盘分区后,将会被划分为面(Side)、磁道(Track)和扇区(Sector)。需要注意的是,这些只是个虚拟的概念,并不是真正在硬盘上划轨道。先从面说起,硬盘一般是由一片或几片圆形薄膜叠加而成。我们所说,每个圆形薄膜都有两个“面”,这两个面都是用来存储数据的。按照面的多少,依次称为0面、1面、2面……由于每个面都专有一个读写磁头,也常用0头(head)、1头……称之。按照硬盘容量和规格的不同,硬盘面数(或头数)也不一定相同,少的只有2面,多的可达数十面。各面上磁道号相同的磁道合起来,称为一个柱面(Cylinder)(如图1)。(图)

上面我们提到了磁道的概念。那么究竟何为磁道呢?由于磁盘是旋转的,则连续写入的数据是排列在一个圆周上的。我们称这样的圆周为一个磁道。(如图2)如果读写磁头沿着圆形薄膜的半径方向移动一段距离,以后写入的数据又排列在另外一个磁道上。根据硬盘规格的不同,磁道数可以从几百到数千不等;一个磁道上可以容纳数KB的数据,而主机读写时往往并不需要一次读写那么多,于是,磁道又被划分成若干段,每段称为一个扇区。一个扇区一般存放512字节的数据。扇区也需要编号,同一磁道中的扇区,分别称为1扇区,2扇区……

计算机对硬盘的读写,处于效率的考虑,是以扇区为基本单位的。即使计算机只需要硬盘上存储的某个字节,也必须一次把这个字节所在的扇区中的512字节全部读入内存,再使用所需的那个字节。不过,在上文中我们也提到,硬盘上面、磁道、扇区的划分表面上是看不到任何痕迹的,虽然磁头可以根据某个磁道的应有半径来对准这个磁道,但怎样才能在首尾相连的一圈扇区中找出所需要的某一扇区呢?原来,每个扇区并不仅仅由512个字节组成的,在这些由计算机存取的数据的前、后两端,都另有一些特定的数据,这些数据构成了扇区的界限标志,标志中含有扇区的编号和其他信息。计算机就凭借着这些标志来识别扇区

硬盘的数据结构

在上文中,我们谈了数据在硬盘中的存储的一般原理。为了能更深入地了解硬盘,我们还必须对硬盘的数据结构有个简单的了解。硬盘上的数据按照其不同的特点和作用大致可分为5部分:MBR区、DBR区、FAT区、DIR区和DATA区。我们来分别介绍一下:

1.MBR区

MBR(Main Boot Record 主引导记录区)�位于整个硬盘的0磁道0柱面1扇区。不过,在总共512字节的主引导扇区中,MBR只占用了其中的446个字节,另外的64个字节交给了DPT(Disk Partition Table硬盘分区表)(见表),最后两个字节“55,AA”是分区的结束标志。这个整体构成了硬盘的主引导扇区。(图)

主引导记录中包含了硬盘的一系列参数和一段引导程序。其中的硬盘引导程序的主要作用是检查分区表是否正确并且在系统硬件完成自检以后引导具有激活标志的分区上的操作系统,并将控制权交给启动程序。MBR是由分区程序(如Fdisk.exe)所产生的,它不依赖任何操作系统,而且硬盘引导程序也是可以改变的,从而实现多系统共存。

下面,我们以一个实例让大家更直观地来了解主引导记录:

例:80 01 01 00 0B FE BF FC 3F 00 00 00 7E 86 BB 00

在这里我们可以看到,最前面的“80”是一个分区的激活标志,表示系统可引导;“01 01 00”表示分区开始的磁头号为01,开始的扇区号为01,开始的柱面号为00;“0B”表示分区的系统类型是FAT32,其他比较常用的有04(FAT16)、07(NTFS);“FE BF FC”表示分区结束的磁头号为254,分区结束的扇区号为63、分区结束的柱面号为764;“3F 00 00 00”表示首扇区的相对扇区号为63;“7E 86 BB 00”表示总扇区数为12289622。

2.DBR区

DBR(Dos Boot Record)是操作系统引导记录区的意思。它通常位于硬盘的0磁道1柱面1扇区,是操作系统可以直接访问的第一个扇区,它包括一个引导程序和一个被称为BPB(Bios Parameter Block)的本分区参数记录表。引导程序的主要任务是当MBR将系统控制权交给它时,判断本分区跟目录前两个文件是不是操作系统的引导文件(以DOS为例,即是Io.sys和Msdos.sys)。如果确定存在,就把它读入内存,并把控制权 交给该文件。BPB参数块记录着本分区的起始扇区、结束扇区、文件存储格式、硬盘介质描述符、根目录大小、FAT个数,分配单元的大小等重要参数。DBR是由高级格式化程序(即Format.com等程序)所产生的。

3.FAT区

在DBR之后的是我们比较熟悉的FAT(File Allocation Table文件分配表)区。在解释文件分配表的概念之前,我们先来谈谈簇(Cluster)的概念。文件占用磁盘空间时,基本单位不是字节而是簇。一般情况下,软盘每簇是1个扇区,硬盘每簇的扇区数与硬盘的总容量大小有关,可能是4、8、16、32、64……

同一个文件的数据并不一定完整地存放在磁盘的一个连续的区域内,而往往会分成若干段,像一条链子一样存放。这种存储方式称为文件的链式存储。由于硬盘上保存着段与段之间的连接信息(即FAT),操作系统在读取文件时,总是能够准确地找到各段的位置并正确读出。

为了实现文件的链式存储,硬盘上必须准确地记录哪些簇已经被文件占用,还必须为每个已经占用的簇指明存储后继内容的下一个簇的簇号。对一个文件的最后一簇,则要指明本簇无后继簇。这些都是由FAT表来保存的,表中有很多表项,每项记录一个簇的信息。由于FAT对于文件管理的重要性,所以FAT有一个备份,即在原FAT的后面再建一个同样的FAT。初形成的FAT中所有项都标明为“未占用”,但如果磁盘有局部损坏,那么格式化程序会检测出损坏的簇,在相应的项中标为“坏簇”,以后存文件时就不会再使用这个簇了。FAT的项数与硬盘上的总簇数相当,每一项占用的字节数也要与总簇数相适应,因为其中需要存放簇号。FAT的格式有多种,最为常见的是FAT16和FAT32。

4.DIR区

DIR(Directory)是根目录区,紧接着第二FAT表(即备份的FAT表)之后,记录着根目录下每个文件(目录)的起始单元,文件的属性等。定位文件位置时,操作系统根据DIR中的起始单元,结合FAT表就可以知道文件在硬盘中的具体位置和大小了。

5.数据(DATA)区

数据区是真正意义上的数据存储的地方,位于DIR区之后,占据硬盘上的大部分数据空间。

磁盘的文件系统
经常听高手们说到FAT16、FAT32、NTFS等名词,朋友们可能隐约知道这是文件系统的意思。可是,究竟这么多文件系统分别代表什么含义呢?今天,我们就一起来学习学习:

1.什么是文件系统?
所谓文件系统,它是操作系统中借以组织、存储和命名文件的结构。磁盘或分区和它所包括的文件系统的不同是很重要的,大部分应用程序都基于文件系统进行操作,在不同种文件系统上是不能工作的。

2.文件系统大家族
常用的文件系统有很多,MS-DOS和Windows 3.x使用FAT16文件系统,默认情况下Windows 98也使用FAT16,Windows 98和Me可以同时支持FAT16、FAT32两种文件系统,Windows NT则支持FAT16、NTFS两种文件系统,Windows 2000可以支持FAT16、FAT32、NTFS三种文件系统,Linux则可以支持多种文件系统,如FAT16、FAT32、NTFS、Minix、ext、ext2、xiafs、HPFS、VFAT等,不过Linux一般都使用ext2文件系统。下面,笔者就简要介绍这些文件系统的有关情况:

(1)FAT16
FAT的全称是“File Allocation Table(文件分配表系统)”,最早于1982年开始应用于MS-DOS中。FAT文件系统主要的优点就是它可以允许多种操作系统访问,如MS-DOS、Windows 3.x、Windows 9x、Windows NT和OS/2等。这一文件系统在使用时遵循8.3命名规则(即文件名最多为8个字符,扩展名为3个字符)。

(2)VFAT
VFAT是“扩展文件分配表系统”的意思,主要应用于在Windows 95中。它对FAT16文件系统进行扩展,并提供支持长文件名,文件名可长达255个字符,VFAT仍保留有扩展名,而且支持文件日期和时间属性,为每个文件保留了文件创建日期/时间、文件最近被修改的日期/时间和文件最近被打开的日期/时间这三个日期/时间。

(3)FAT32
FAT32主要应用于Windows 98系统,它可以增强磁盘性能并增加可用磁盘空间。因为与FAT16相比,它的一个簇的大小要比FAT16小很多,所以可以节省磁盘空间。而且它支持2G以上的分区大小。朋友们从附表中可以看出FAT16与FAT32的一不同。

(4)HPFS
高性能文件系统。OS/2的高性能文件系统(HPFS)主要克服了FAT文件系统不适合于高档操作系统这一缺点,HPFS支持长文件名,比FAT文件系统有更强的纠错能力。Windows NT也支持HPFS,使得从OS/2到Windows NT的过渡更为容易。HPFS和NTFS有包括长文件名在内的许多相同特性,但使用可靠性较差。

(5)NTFS
NTFS是专用于Windows NT/2000操作系统的高级文件系统,它支持文件系统故障恢复,尤其是大存储媒体、长文件名。NTFS的主要弱点是它只能被Windows NT/2000所识别,虽然它可以读取FAT文件系统和HPFS文件系统的文件,但其文件却不能被FAT文件系统和HPFS文件系统所存取,因此兼容性方面比较成问题。

ext2
这是Linux中使用最多的一种文件系统,因为它是专门为Linux设计,拥有最快的速度和最小的CPU占用率。ext2既可以用于标准的块设备(如硬盘),也被应用在软盘等移动存储设备上。现在已经有新一代的Linux文件系统如SGI公司的XFS、ReiserFS、ext3文件系统等出现。

小结:虽然上面笔者介绍了6种文件系统,但占统治地位的却是FAT16/32、NTFS等少数几种,使用最多的当然就是FAT32啦。只要在“我的电脑”中右击某个驱动器的属性,就可以在“常规”选项中(图)看到所使用的文件系统。

明明白白识别硬盘编号
目前,电子市场上硬盘品牌最让大家熟悉的无非是IBM、昆腾(Quantum)、希捷(Seagate),迈拓(Maxtor)等“老字号”。而这些硬盘型号的编号则各不相同,令人眼花缭乱。其实,这些编号均有一定的规律,表示一些特定?的含义。一般来说,我们可以从其编号来了解硬盘的性能指标,包括接口?类型、转速、容量等。作为DIY朋友来说,只有自己真正掌握正确识别硬盘编号,在选购硬盘时,就方便得多(以致不被“黑”),至少不会被卖的人说啥是啥。以下举例说明,供朋友们参考。

一、IBM
IBM是硬盘业的巨头,其产品几乎涵盖了所有硬盘领域。而且IBM还是去年硬盘容量、价格战的始作蛹者。我们今天能够用得上经济上既便宜,而且容量又大的硬盘可都得感谢IBM。
IBM的每一个产品又分为多个系列,它的命名方式为:产品名+系列代号+接口类型+盘片尺寸+转速+容量。以Deskstar 22GXP的13.5GB硬盘为例,该硬盘的型号为:DJNA-371350,字母D代表Deskstar产品,JN代表Deskstar25GP与22GP系列,A代表ATA接口,3代表3寸盘片,7是7200转产品,最后四位数字为硬盘容量13.5GB。IBM系列代号(IDE)含义如下:
TT=Deskstar 16GP或14GXP JN=Deskstar 25GP或22GXP RV=Ultrastar 18LZX或36ZX
接口类型含义如下:A=ATA
S与U=Ultra SCSI、Ultra SCSI Wide、Ultra SCSI SCA、增强型SCSI、
增强扩展型SCSI(SCA)
C=Serial Storage Architecture连续存储体系SCSI L=光纤通道SCSI

二、MAXTOR(迈拓)
MAXTOR是韩国现代电子美国公司的一个独立子公司,以前该公司的产品也覆盖了IDE与SCSI两个方面,但由于SCSI方面的产品缺乏竟争力而最终放弃了这个高端市场从而主攻IDE硬盘,所以MAXTOR公司应该是如今硬盘厂商中最专一的了。
MAXTOR硬盘编号规则如下:首位+容量+接口类型+磁头数,MAXTOR?从钻石四代开始,其首位数字就为9,一直延续到现在,所以大家如今能在电子市场上见到的MAXTOR硬盘首位基本上都为9。另外比较特殊的是MAXTOR编号中有磁头数这一概念,因为MAXTOR硬盘是大打单碟容量的发起人,所以其硬盘的型号中要将单碟容量从磁头数中体现出来。单碟容量=2*硬盘总容量/磁头数。
现以金钻三代(DiamondMax Plus6800)10.2GB的硬盘为例说明:该硬盘?型号为91024U3,9是首位,1024是容量,U是接口类型UDMA66,3代表该硬盘有3个磁头,也就是说其中的一个盘片是单面有数据。这个单碟容量就为2*10.2/3=6.8GB。MAXTOR硬盘接口类型字母含义如:
A=PIO模式 D=UDMA33模式 U=UDMA66模式

三、SEAGATE(希捷)
希捷科技公司(Seagate Technology)是世界上最大的磁盘驱动器、磁?盘和读写磁头生产厂家,该公司是一直是IBM、COMPAQ、SONY等业界大户的硬盘供应商。希捷还保持着业界第一款10000转硬盘的记录(積架Cheetah系列SCSI)与最大容量(積架三代73GB)的记录,公司的实力由此可见一斑。但?由于希捷一直是以高端应用为主(例如SCSI硬盘),而并不是特别重视低端家用产品的开发,从而导致在DIY一族心目中的地位不如昆腾等硬盘供应商?。好在希捷公司及时注意到了这个问题,不久前投入市场的酷鱼(Barracuda)系列就一扫希捷硬盘以往在单碟容量、转速、噪音、非正常外频下工作稳?定性、综合性能上的劣势。
希捷的硬盘系列从低端到高端的产品名称分别为:U4系列、Medalist(金牌)系列、U8系列、Medalist Pro(金牌Pro)系列、Barracuda(酷鱼)系列。其中Medalist Pro与Barracuda系列是7200转的产品,其他的是5400转的产品。硬盘的型号均以ST开头,现以酷鱼10.2GB硬盘为例来说明。该硬盘的型号是:ST310220A,在ST后第一位数字是代表硬盘的尺寸,3就是该硬盘采用3寸盘片,如今其他规格的硬盘已基本上没有了,所以大家能够见到?的绝大多数硬盘该位数字均不3,3后面的1022代表的是该硬盘的格式化容量是10.22GB,最后一位数字0是代表7200转产品。这一点不要混淆与希捷以前的入门级产品Medalist ST38420A混淆。多数希捷的Medalist Pro系列开始,以结尾的产品均代表7200转硬盘,其它数字结尾(包括1、2)代表5400转的产品。位于型号最后的字母是硬盘的接口类型。希捷硬盘的接口类型字母含义如下:
A=ATA UDMA33或UDMA66 IDE接口 AG为笔记本电脑专用的ATA接口硬盘。
W为ULTRA Wide SCSI,
其数据传输率为40MB每秒 N为ULTRA Narrow SCSI,其数据传输率为20MB每秒。
而ST34501W/FC和ST19101N/FC中的FC(Fibre Channel)表示光纤通道,可提供高达每秒100MB的数据传输率,并且支持热插拔。

硬盘及接口标准的发展历史
一、硬盘的历史
说起硬盘的历史,我们不能不首先提到蓝色巨人IBM所发挥的重要作用,正是IBM发明了硬盘,并且为硬盘的发展做出了一系列重大贡献。在发明磁盘系统之前,计算机使用穿孔纸带、磁带等来存储程序与数据,这些存储方式不仅容量低、速度慢,而且有个大缺陷:它们都是顺序存储,为了读取后面的数据,必须从头开始读,无法实现随机存取数据。
在1956年9月,IBM向世界展示了第一台商用硬盘IBM 350 RAMAC(Random Access Method of Accounting and Control),这套系统的总容量只有5MB,却是使用了50个直径为24英寸的磁盘组成的庞然大物。而在1968年IBM公司又首次提出了“温彻斯特”Winchester技术。“温彻斯特”技术的精髓是:“使用密封、固定并高速旋转的镀磁盘片,磁头沿盘片径向移动,磁头磁头悬浮在高速转动的盘片上方,而不与盘片直接接触”,这便是现代硬盘的原型。在1973年IBM公司制造出第一台采用“温彻期特”技术制造的硬盘,从此硬盘技术的发展有了正确的结构基础。1979年,IBM再次发明了薄膜磁头,为进一步减小硬盘体积、增大容量、提高读写速度提供了可能。70年代末与80年代初是微型计算机的萌芽时期,包括希捷、昆腾、迈拓在内的许多着名硬盘厂商都诞生于这一段时间。1979年,IBM的两位员工Alan Shugart和Finis Conner决定要开发像5.25英寸软驱那样大小的硬盘驱动器,他们离开IBM后组建了希捷公司,次年,希捷发布了第一款适合于微型计算机使用的硬盘,容量为5MB,体积与软驱相仿。
PC时代之前的硬盘系统都具有体积大、容量小、速度慢和价格昂贵的特点,这是因为当时计算机的应用范围还太小,技术与市场之间是一种相互制约的关系,使得包括存储业在内的整个计算机产业的发展都受到了限制。 80年代末期IBM对硬盘发展的又一项重大贡献,即发明了MR(Magneto Resistive)磁头,这种磁头在读取数据时对信号变化相当敏感,使得盘片的存储密度能够比以往20MB每英寸提高了数十倍。1991年IBM生产的3.5英寸的硬盘使用了MR磁头,使硬盘的容量首次达到了1GB,从此硬盘容量开始进入了GB数量级的时代 。1999年9月7日,迈拓公司(Maxtor)_宣布了首块单碟容量高达10.2GB的ATA硬盘,从而把硬盘的容量引入了一个新里程碑。

二、接口标准的发展
(1)IDE和EIDE的由来
最早的IBM PC并不带有硬盘,它的BIOS及DOS 1.0操作系统也不支持任何硬盘,因为系统的内存只有16KB,就连软驱和DOS都是可选件。后来DOS 2引入了子目录系统,并添加了对“大容量”存储设备的支持,于是一些公司开始出售供IBM PC使用的硬盘系统,这些硬盘与一块控制卡、一个独立的电源被一起装在一个外置的盒子里,并通过一条电缆与插在扩展槽中的一块适配器相连,为了使用这样的硬盘,必须从软驱启动,并加载一个专用设备驱动程序。
1983年IBM公司推出了PC/XT,虽然XT仍然使用8088 CPU,但配置却要高得多,加上了一个10MB的内置硬盘,IBM把控制卡的功能集成到一块接口控制卡上,构成了我们常说的硬盘控制器。其接口控制卡上有一块ROM芯片,其中存有硬盘读写程序,直到基于80286处理器的PC/AT的推出,硬盘接口控制程序才被加入到了主板的BIOS中。
PC/XT和PC/AT机器使用的硬盘被称为MFM硬盘或ST-506/412硬盘,MFM(Modified Frequency Molation)是指一种编码方案,而ST-506/412则是希捷开发的一种硬盘接口,ST-506接口不需要任何特殊的电缆及接头,但是它支持的传输速度很低,因此到了1987年左右这种接口就基本上被淘汰了。
迈拓于1983年开发了ESDI(Enhanced Small Drive Interface)接口。这种接口把编解码器放在了硬盘本身之中,它的理论传输速度是ST-506的2~4倍。但由于成本比较高,九十年代后就逐步被淘汰掉了。
IDE(Integrated Drive Electronics)实际上是指把控制器与盘体集成在一起的硬盘驱动器,这样减少了硬盘接口的电缆数目与长度,数据传输的可靠性得到了增强,硬盘制造起来变得更容易,对用户而言,硬盘安装起来也更为方便。IDE接口也叫ATA(Advanced Technology Attachment)接口。
ATA接口最初是在1986年由CDC、康柏和西部数据共同开发的,他们决定使用40芯的电缆,最早的IDE硬盘大小为5英寸,容量为40MB。ATA接口从80年代末期开始逐渐取代了其它老式接口。
80年代末期IBM发明了MR(Magneto Resistive)磁阻磁头,这种磁头在读取数据时对信号变化相当敏感,使得盘片的存储密度能够比以往的20MB/in2提高数十上百倍。1991年,IBM生产的3.5英寸硬盘0663-E12使用了MR磁头,容量首次达到了1GB,从此硬盘容量开始进入了GB数量级,直到今天,大多数硬盘仍然采用MR磁头。
人们在谈论硬盘时经常讲到PIO模式和DMA模式,它们是什么呢?目前硬盘与主机进行数据交换的方式有两种,一种是通过CPU执行I/O端口指令来进行数据的读写;另外,一种是不经过CPU的DMA方式。
PIO模式即Programming Input/Output Model。这种模式使用PC I/O端口指令来传送所有的命令、状态和数据。由于驱动器中有多个缓冲区,对硬盘的读写一般采用I/O串操作指令,这种指令只需一次取指令就可以重复多次地完成I/O操作,因此,达到高的数据传输率是可能的。
DMA即Direct Memory Access。它表示数据不经过CPU,而直接在硬盘和内存之间传送。在多任务操作系统内,如OS/2、Linux、Windows NT等,当磁盘传输数据时,CPU可腾出时间来做其它事情,而在DOS/Windows3.X环境里,CPU不得不等待数据传输完毕,所以在这种情况下,DMA方式的意义并不大。
DMA方式有两种类型:第三方DMA(third-party DMA)和第一方DMA(first-party DMA)(或称总线主控DMA,Busmastering DMA)。第三方DMA通过系统主板上的DMA控制器的仲裁来获得总线和传输数据。而第一方DMA,则完全由接口卡上的逻辑电路来完成,当然这样就增加了总线主控接口的复杂性和成本。现在,所有较新的芯片组均支持总线主控DMA。
(2)SCSI接口
(Small Computer System Interface小型计算机系统接口)是一种与ATA完全不同的接口,它不是专门为硬盘设计的,而是一种总线型的系统接口,每个SCSI总线上可以连接包括SCSI控制卡在内的8个SCSI设备。SCSI的优势在于它支持多种设备,传输速率比ATA接口快得多但价格也很高,独立的总线使得它对CPU的占用率很低。 最早的SCSI是于1979年由美国的Shugart公司(Seagate希捷公司的前身)制订的,90年代初,SCSI发展到了SCSI-2,1995年推出了SCSI-3,其俗称Ultra SCSI, 1997年推出了Ultra 2 SCSI(Fast-40),其采用了LVD(Low Voltage Differential,低电平微分)传输模式,16位的Ultra2SCSI(LVD)接口的最高传输速率可达80MB/S,允许接口电缆的最长为12米,大大增加了设备的灵活性。1998年,更高数据传输率的Ultra160/m SCSI(Wide下的Fast-80)规格正式公布,其最高数据传输率为160MB/s,昆腾推出的Atlas10K和Atlas四代等产品支持Ultra3 SCSI的Ultra160/m传输模式。
SCSI硬盘具备有非常优秀的传输性能。但由于大多数的主板并不内置SCSI接口,这就使得连接SCSI硬盘必须安装相应的SCSI卡,目前关于SCSI卡有三个正式标准,SCSI-1,SCSI-2和SCSI-3,以及一些中间版本,要使SCSI硬盘获得最佳性能就必须保证SCSI卡与SCSI硬盘版本一致(目前较新生产的SCSI硬盘和SCSI卡都是向前兼容的,不一定必须版本一致)。
(3)IEEE1394:IEEE1394又称为Firewire(火线)或P1394,它是一种高速串行总线,现有的IEEE1394标准支持100Mbps、200Mbps和400Mbps的传输速率,将来会达到800Mbps、1600Mbps、3200Mbps甚至更高,如此高的速率使得它可以作为硬盘、DVD、CD-ROM等大容量存储设备的接口。IEEE1394将来有望取代现有的SCSI总线和IDE接口,但是由于成本较高和技术上还不够成熟等原因,目前仍然只有少量使用IEEE1394接口的产品,硬盘就更少了。

‘拾’ 分布式存储中,怎样使用paxos算法保证数据的一致性

在分布式系统中,我们经常遇到多数据副本保持一致的问题,在我们所能找到的资料中该问题讲的很笼统,模模糊糊的,把多个问题或分类糅合在一起,难以理解。在思考和翻阅资料后,通俗地把一致性的问题可分解为2个问题:
1、任何一次修改保证数据一致性。
2、多次数据修改的一致性。
在弱一致性的算法,不要求每次修改的内容在修改后多副本的内容是一致的,对问题1的解决比较宽松,更多解决问题2,该类算法追求每次修改的高度并发性,减少多副本之间修改的关联性,以获得更好的并发性能。例如最终一致性,无所谓每次用户修改后的多副本的一致性及格过,只要求在单调的时间方向上,数据最终保持一致,如此获得了修改极大的并发性能。
在强一致性的算法中,强调单次修改后结果的一致,需要保证了对问题1和问题2要求的实现,牺牲了并发性能。本文是讨论对解决问题1实现算法,这些算法往往在强一致性要求的应用中使用。
解决问题1的方法,通常有两阶段提交算法、采用分布式锁服务和采用乐观锁原理实现的同步方式,下面分别介绍这几种算法的实现原理。

两阶段提交算法

在两阶段提交协议中,系统一般包含两类机器(或节点):一类为协调者(coordinator),通常一个系统中只有一个;另一类为事务参与者(participants,cohorts或workers),一般包含多个,在数据存储系统中可以理解为数据副本的个数。两阶段提交协议由两个阶段组成,在正常的执行下,这两个阶段的执行过程如下所述:
阶段1:请求阶段(commit-request phase,或称表决阶段,voting phase)。
在请求阶段,协调者将通知事务参与者准备提交或取消事务,然后进入表决过程。在表决过程中,参与者将告知协调者自己的决策:同意(事务参与者本地作业执行成功)或取消(本地作业执行故障)。
阶段2:提交阶段(commit phase)。
在该阶段,协调者将基于第一个阶段的投票结果进行决策:提交或取消。当且仅当所有的参与者同意提交事务协调者才通知所有的参与者提交事务,否则协调者将通知所有的参与者取消事务。参与者在接收到协调者发来的消息后将执行响应的操作。
举个例子:A组织B、C和D三个人去爬长城:如果所有人都同意去爬长城,那么活动将举行;如果有一人不同意去爬长城,那么活动将取消。用2PC算法解决该问题的过程如下:
首先A将成为该活动的协调者,B、C和D将成为该活动的参与者。
阶段1:A发邮件给B、C和D,提出下周三去爬山,问是否同意。那么此时A需要等待B、C和D的邮件。B、C和D分别查看自己的日程安排表。B、C发现自己在当日没有活动安排,则发邮件告诉A它们同意下周三去爬长城。由于某种原因,D白天没有查看邮件。那么此时A、B和C均需要等待。到晚上的时候,D发现了A的邮件,然后查看日程安排,发现周三当天已经有别的安排,那么D回复A说活动取消吧。
阶段2:此时A收到了所有活动参与者的邮件,并且A发现D下周三不能去爬山。那么A将发邮件通知B、C和D,下周三爬长城活动取消。此时B、C回复A“太可惜了”,D回复A“不好意思”。至此该事务终止。
两阶段提交算法在分布式系统结合,可实现单用户对文件(对象)多个副本的修改,多副本数据的同步。其结合的原理如下:
1、客户端(协调者)向所有的数据副本的存储主机(参与者)发送:修改具体的文件名、偏移量、数据和长度信息,请求修改数据,该消息是1阶段的请求消息。
2、存储主机接收到请求后,备份修改前的数据以备回滚,修改文件数据后,向客户端回应修改成功的消息。 如果存储主机由于某些原因(磁盘损坏、空间不足等)不能修改数据,回应修改失败的消息。
3、客户端接收发送出去的每一个消息回应,如果存储主机全部回应都修改成功,向每存储主机发送确认修改的提交消息;如果存在存储主机回应修改失败,或者超时未回应,客户端向所有存储主机发送取消修改的提交消息。该消息是2阶段的提交消息。
4、存储主机接收到客户端的提交消息,如果是确认修改,则直接回应该提交OK消息;如果是取消修改,则将修改数据还原为修改前,然后回应取消修改OK的消息。
5、 客户端接收全部存储主机的回应,整个操作成功。
在该过程中可能存在通信失败,例如网络中断、主机宕机等诸多的原因,对于未在算法中定义的其它异常,都认为是提交失败,都需要回滚,这是该算法基于确定的通信回复实现的,在参与者的确定回复(无论是回复失败还是回复成功)之上执行逻辑处理,符合确定性的条件当然能够获得确定性的结果哲学原理。

分布式锁服务

分布式锁是对数据被外界修改持保守态度,在整个数据处理过程中将数据处于锁定状态,在用户修改数据的同时,其它用户不允许修改。
采用分布式锁服务实现数据一致性,是在操作目标之前先获取操作许可,然后再执行操作,如果其他用户同时尝试操作该目标将被阻止,直到前一个用户释放许可后,其他用户才能够操作目标。分析这个过程,如果只有一个用户操作目标,没有多个用户并发冲突,也申请了操作许可,造成了由于申请操作许可所带来的资源使用消耗,浪费网络通信和增加了延时。
采用分布式锁实现多副本内容修改的一致性问题, 选择控制内容颗粒度实现申请锁服务。例如我们要保证一个文件的多个副本修改一致, 可以对整个文件修改设置一把锁,修改时申请锁,修改这个文件的多个副本,确保多个副本修改的一致,修改完成后释放锁;也可以对文件分段,或者是文件中的单个字节设置锁, 实现更细颗粒度的锁操作,减少冲突。
常用的锁实现算法有Lamport bakery algorithm (俗称面包店算法), 还有Paxos算法。下面对其原理做简单概述。

Lamport面包店算法

是解决多个线程并发访问一个共享的单用户资源的互斥问题的算法。 由Leslie Lamport(英语:Leslie Lamport)发明。
Lamport把这个并发控制算法可以非常直观地类比为顾客去面包店采购。面包店只能接待一位顾客的采购。已知有n位顾客要进入面包店采购,安排他们按照次序在前台登记一个签到号码。该签到号码逐次加1。根据签到号码的由小到大的顺序依次入店购货。完成购买的顾客在前台把其签到号码归0. 如果完成购买的顾客要再次进店购买,就必须重新排队。
这个类比中的顾客就相当于线程,而入店购货就是进入临界区独占访问该共享资源。由于计算机实现的特点,存在两个线程获得相同的签到号码的情况,这是因为两个线程几乎同时申请排队的签到号码,读取已经发出去的签到号码情况,这两个线程读到的数据是完全一样的,然后各自在读到的数据上找到最大值,再加1作为自己的排队签到号码。为此,该算法规定如果两个线程的排队签到号码相等,则线程id号较小的具有优先权。
把该算法原理与分布式系统相结合,即可实现分步锁。

Paxos算法

该算法比较热门,参见WIKI,http://zh.wikipedia.org/wiki/Paxos%E7%AE%97%E6%B3%95
Paxos算法解决的问题是一个分布式系统如何就某个值(决议)达成一致。一个典型的场景是,在一个分布式数据库系统中,如果各节点的初始状态一致,每个节点都执行相同的操作序列,那么他们最后能得到一个一致的状态。为保证每个节点执行相同的命令序列,需要在每一条指令上执行一个“一致性算法”以保证每个节点看到的指令一致。一个通用的一致性算法可以应用在许多场景中,是分布式计算中的重要问题。节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing)。Paxos算法就是一种基于消息传递模型的一致性算法。BigTable使用一个分布式数据锁服务Chubby,而Chubby使用Paxos算法来保证备份的一致性。

采用乐观锁原理实现的同步

我们举个例子说明该算法的实现原理。如一个金融系统,当某个操作员读取用户的数据,并在读出的用户数据的基础上进行修改时(如更改用户帐户余额),如果采用前面的分布式锁服务机制,也就意味着整个操作过程中(从操作员读出数据、开始修改直至提交修改结果的全过程,甚至还包括操作员中途去煮咖啡的时间),数据库记录始终处于加锁状态,可以想见,如果面对几百上千个并发,这样的情况将导致怎样的后果。
乐观锁机制在一定程度上解决了这个问题。乐观锁,大多是基于数据版本( Version)记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个 “version” 字段来实现。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。
对于上面修改用户帐户信息的例子而言,假设数据库中帐户信息表中有一个 version 字段,当前值为 1 ;而当前帐户余额字段( balance )为 $100 。
操作员 A 此时将其读出(version=1 ),并从其帐户余额中扣除 $50($100-$50 )。
在操作员 A 操作的过程中,操作员B也读入此用户信息( version=1 ),并从其帐户余额中扣除 $20 ( $100-$20 )。
操作员 A 完成了修改工作,将数据版本号加一( version=2 ),连同帐户扣除后余额( balance=$50 ),提交至数据库更新,此时由于提交数据版本大于数据库记录当前版本,数据被更新,数据库记录 version 更新为 2 。
操作员 B 完成了操作,也将版本号加一( version=2 )试图向数据库提交数据( balance=$80 ),但此时比对数据库记录版本时发现,操作员 B 提交的数据版本号为 2 ,数据库记录当前版本也为 2 ,不满足 “ 提交版本必须大于记录当前版本才能执行更新 “ 的乐观锁策略,因此,操作员 B 的提交被驳回。这样,就避免了操作员 B 用基于 version=1 的旧数据修改的结果覆盖操作员A 的操作结果的可能。
乐观锁机制与分布式系统相结合上, 我整理了伪代码如下:
obj 操作的目标
vlaue 修改的值
atom_update_ver 每个目标上的版本,每次修改该值递增
set( obj, value)
{
//从每个节点上取出修改前的对象版本
get original_ver = obj.atom_update_ver from each node;
//将值赋到每个节点的obj目标
set obj = value from each node;
//条件修改每个节点的obj版本,目标版本加一
//比较和修改操作是原子操作
result = (set obj.atom_update_ver = original_ver + 1
where original_ver + 1 > obj.atom_update_ver
for each node);
if(result == ok)
return set_ok;
else
return set(obj, value);//不成功递归修改

该算法未考虑节点下线、失效等问题,在后续我将分析采用乐观锁原理实现一致性算法,解决问题2、节点失效、通信失败等问题。