日期:2014-05-16 浏览次数:20475 次
?
云存储服务是云计算的重要组成部分。技术上,云存储属于大型分布式在线存储范畴。云存储是一大类特殊的共享存储。作为提供存储资源的服务,云存储需要保证用户存放的数据可靠,不丢失。同时,云存储必须确保实时在线,任何宕机都会给用户造成损失。因而,云存储的基本要求是高可靠和高可用。此外,云存储是海量数据的存储,规模巨大。而且,出于成本和现金流量的考虑,云存储的集群规模必须随着用户数据量的不断增加而扩展。云存储的架构,设计和技术运用都是围绕这四个基本要求展开。反之,无论多么漂亮先进的技术,只要可能影响这些目标的实现,都不能应用于云存储。
在我开始接触存储的时候,一致性哈希(以及著名的Dynamo )是非常热门的技术。技术上一致性哈希很漂亮,简洁,并且高效。但在实际应用中,却是另一种表现。本文将对集中式的元数据存储方案和一致性哈希作对比分析,以期说明元数据是更加适合云存储的选择。
1. 对象存储,块存储
实用的云存储可以分作两类:对象存储和块存储。对象存储存储是地道的数据仓储,仅仅存放key/value数据:用户有一个数据对象,需要存储起来,他就给这个对象起一个名字(key),然后将对象连同名字一起存放入对象存储。当需要的时候,用这个名字作为key,向存储系统索要。而对象存储系统必须在需要的时候将数据返还给用户,除非用户已将此数据从存储系统中删除。
块存储则是充当操作系统底下的块设备(笼统地说,就是磁盘),供系统使用。块存储实际上就是一种SAN(Storage Attach Network),将集群的存储空间分配给用户,挂载到操作系统,作为磁盘使用。因为块存储需要模拟磁盘的行为,因此必须确保低延迟。
尽管两种云存储有完全不同的目标、用途和特性,但在分布式存储基本特性方面都面临着相同的问题,这里的讨论对两者都有意义。为了简便起见,这里只讨论对象存储的情况。但很多内容和结论可以外推到块存储。
2. 存储的基础
云存储功能非常简单,存储用户的数据而已。但简单归简单,几个要点还是需要做的。当用户将一个key-value对上传至存储时,存储系统必须找合适的服务器,保存数据。通常会保存在多台服务器上,以防止数据丢失。这叫多副本。
于是,一个关键的问题就是如何选择存放数据的服务器。服务器的选择是很有技术含量的事,需要兼顾到几个要点:首先,数据必须在服务器之间平衡。不能把数据集中到少数几台服务器,造成一部分服务器撑死,而另一部分饿死。其次,在用户读取数据时,可以方便快捷定位。随后,满足云存储服务高可靠高可用大规模的特点。最后,尽可能简单。
于是,对于每个对象,都有一个key到数据存储位置的映射: key->pos。映射方式很多,最直接的,就是将每一个对象的key->pos数据对保存下来。这些数据通常被称为"元数据"。
但还有一些更巧妙的方式:根据key的特征,将key空间划分成若干分组,并将这些分组对应到不同的存储节点上。这种方式可以笼统地成为”Sharding"。如此,可以直接按照一个简单规则定位到服务器。常用的分组方式之一是按key的区间划分,比如a开头的是一组,b开头的是一组等等。而另一种更具"现代感"的分组方式,就是对key哈希后取模。哈希方案实际上就是哈希表的自然延伸,将桶分布到多台服务器中。
这两大类映射方式实质上是在不同的粒度上进行映射。"元数据"在对象粒度上,而sharding则是在一组对象的粒度。这两种不同的粒度,决定了它们有着完全不同的特性。也决定了它们在实际应用中的表现。
3. 元数据和一致性哈希
于是,在云存储方案中产生了两大流派:元数据模型和Sharding模型。而Sharding模型中,一致性哈希最为流行。一致性哈希本身很难直接用作实际使用,进而产生了很多衍生方案,其中包括著名的"Dynamo"。这里用“一致性哈希方案”指代所有基于一致性哈希的设计。
元数据方案是对象级别的key->pos映射,也就是一个会无休止增长的"map"。每多一个对象,就会多一条元数据。通常会将元数据保存在一组数据库中,方便检索和查询。元数据方案没有什么特别的地方,其核心是元数据存储部分。这部分设计的好坏,关系到系统整体的特性。关于元数据存储的设计不是本文的重点,本文将集中探讨元数据方案和一致性哈希方案的比较。
标准的一致性哈希模型 是对key进行哈希运算,然后投射到一个环形的数值空间上。与此同时,对节点(存储服务器)进行编码,然后也做哈希运算,并投射到哈希环上。理论上,只要哈希算法合适,节点可以均匀地分布在哈希环上。节点根据自身在哈希环上的位置,占据一个哈希值区间,比如从本节点到下一个节点间的区间。所有落入这个区间的key,都保存到该节点上。
在这个模型中,key到数据存储逻辑位置的映射不通过存储,而是通过算法直接得到。但是,逻辑位置(哈希环上的位置)到物理位置(节点)的转换无法直接得到。标准的做法是任选一个节点,然后顺序寻找目标节点,或者采用二分法在节点之间跳转查找。这种查找方式在实际的存储系统中是无法忍受的。所以,实用的存储系统往往采用的是一个混合模型(暂且称之为“混合方案”):系统维护一个哈希区间-&