文章归档

NoSQL生态系统

NoSQL 生态系统

By Jonathan Ellis,系统架构师, Translated by Jametong

空前的数据量正在驱动商业寻找传统关系型数据库的替代方案,它已经为我们服务30多年了(今年5月份ACM刚刚给关系型数据庆祝40岁生日).总体来讲,这些替代方案就是目前知名的“NoSQL数据库.”

关系型数据库的基本问题是无法处理许多现代的工作负载.有三个具体的问题领域:向外扩展(Scale out)类似于Digg(3TB的绿色徽章数据)或Facebook(50T的收件箱搜索数据)或Ebay(总共2PB的数据)的数据集,单机性能限制以及僵化的概要设计.

商业上(包含Rackspace Cloud公司)需要寻找新的方式来存储并扩展大规模的数据.我最近写了一篇关于Cassandra的文章,一个我们投入了资源的非关系型数据库.还有另外一些正在运作中的非关系型数据库,它们汇总在一起被我们称为”NoSQL运动”.

“NoSQL”这个术语实际上是由一个Rackspace的员工Eric Evans最先提出的,当时来自Last.fm网站的Johan Oskarsson提议组织一次开源分布式数据库的研讨会.这个名称与概念就一起流行了起来.

有些人反对NoSQL这个说法,因为它听起来像是仅仅表明了我们不做什么,而不是我们在做什么. 事实确实是这样,我也基本同意此说法,但是这个术语仍然有其价值,因为当关系型数据库是你所知道的唯一工具时,每个问题看起来都像个拇指(俗语,如果你手里有一个锤子,你看到什么都是钉子,译者补充).NoSQL这个术语起码让人们知道还有其他的选项可供选择.但是,当关系型数据库是解决问题的最佳工具时,我们并不是反关系型数据库者;它的涵义应该是“不仅仅有SQL(Not Only SQL)”而不是“不再有SQL(No SQL at all)”.

有关NoSQL名称的一个真实的忧虑是,它是如此大的一个概念,以致于差异巨大的设计都可以涵盖其中.如果在讨论各种产品时没有搞清楚这一点,就会导致概念混乱.因此,我建议大家沿着下面三个维度来思考这些数据库选项: 可伸缩性(scalability)、数据模型与查询模型(data and query model)以及持久化设计(persistence design).

我选择了10种NoSQL数据库作为示例.这不是一份详尽的清单,但是这里讨论的概念对于评估其他的NoSQL数据库也至关重要.

可伸缩性(Scalability)

通过使用复制, 就可以轻易扩展读的规模,因此,每当我在此文中谈到规模伸缩(scaling),都是表示通过自动分区将数据分布到多台机器以扩展写的规模.我们将做这种事情的系统称为“分布式数据库”.它们包括Cassandra、HBase、Riak、Scalaris、Voldemort以及其他很多类似的系统.如果你的写容量或写数据大小已经无法在一台机器上进行处理,如果你不想自己手工来管理分区的话,这些就是你的唯一选项了.(你不会这么做吧?)

人们使用分布式数据库主要关注两件事情: 1) 是否支持多个数据中心以及2) 能否在对应用透明的前提下往正在运行的集群中添加新机器的能力.

非分布式NoSQL数据库包括CouchDB、MongoDB、Neo4j、Redis以及Tokyo Cabinet.它们可作为分布式系统的持久层; MongoDB提供了受限制的数据分片(Sharding)功能,CouchDB也有一个独立的Lounge项目来支持做类似的分片功能,Tokyo Cabinet可用作Voldemort的存储引擎.

数据模型与查询模型

NoSQL数据库之间的数据模型与查询API千差万别.

(相关链接: Thrift, map/reduce views, Thrift, Cursor, Graph, Collection, Nested hashes, get/put, get/put, get/put)

部分重点内容介绍:

Cassandra与HBase共同使用的ColumnFamily模型都是受到Google的Bigtable论文第2节的启发. (Cassandra丢弃了历史版本,并增加了超级列(SuperColumn)的概念).在这两个系统中,都有与你之前看到的关系型数据库类似的行/列概念,但是此处的行是稀疏的行:你想要一行有多少列,一行就可以有多少列,这些列并不需要事先定义好.

键值(Key/value)模型是最简单也最容易实现的模型,但是,如果你仅想对值(Value)的一部分进行查询/更新时,它的效率会比较低.要想在一个分布式的键值上,实现更加复杂的结构也会非常困难.

文档数据库实际上是更高级的键/值(Key/Value)数据库,允许在每个键上关联嵌套的值.相对于每次简单地返回整个BLOB(二进制大对象)来讲,文档数据库支持更高效的查询.

Neo4j拥有一个非常独特的数据模型,它以节点与边的形式在图中存储对象与关系.对于适合这个模型(例如,分层数据)的查询,它的性能可能会达到其替代选项的1000倍.

Scalaris的独特之处在于,它可以提供跨越多个键的分布式事务.(关于一致性与可用性的权衡的讨论超出了本文的范围,但是,在评估分布式系统时,它也是需要记住的一方面.)

持久化设计

关于持久化设计,我的意思是“数据在内部是如何存储的?”

持久化模型可以为我们提供大量关于这些数据库适合处理多大工作负载的信息.

内存数据库非常非常快(单台机器上的Redis可以处理100,000次操作/秒),但是无法处理超过可用内存的数据集.持久性(Durability,数据不会由于服务器崩溃或停电而丢失)也是个问题; 在两次刷新到磁盘的时间间隔内预期数据丢失量可能非常大.Scalaris是我们此列表中唯一的内存数据库,它通过复制来解决持久性的问题,但是,由于它不支持跨越多个数据中心,因此,如果遇到类似电源故障一类的问题数据仍将非常脆弱.

在为了持久性写入一个仅可追加的提交日志之后,Memtable与SSTable会缓冲内存中的写操作.在接受了足够多的写操作之后(Memtable达到一定的阈值),就会对memtable中的数据进行排序,并一次性写入到磁盘,写入的文件就是一个“sstable.” 这样它就可以提供接近于内存处理的性能,因为它不涉及任何检索操作,同时又可以避免纯粹在内存中的方法那样遭遇持久性问题.(在前面引用的Bigtable论文的第5.3与5.4两节,以及论文日志结构的合并树(The Log-Structured merge-tree)中对此都有详细的描述)

几乎从有数据库开始,B-树就开始在数据库中使用了.它们提供健壮的索引支持,但是在旋转磁盘(仍然是目前最经济实用的存储介质)上, 它的性能表现比较差,因为它读写任何内容都会涉及到多次磁盘检索.

CouchDB的仅可做追加操作的B-树(Append-Only B-tree)是一个比较有趣的变体,它以限制CouchDB并发写(one write at a time)的代价避免了其检索的开销.

结论

NoSQL运动在2009年取得了爆发性的效果,因为越来越多的企业需要处理大规模的数据.Rackspace Cloud公司很高兴在NoSQL运动扮演了一个较早期的角色,还会持续为Cassandra投入资源并支持与NoSQL [...]

index rebuild online处理过程

http://forums.oracle.com/forums/thread.jspa?messageID=4269655#4269655

In principle (for 10g):

Your rebuild tries to take an exclusive (or possibly share) lock on the table and gets stuck waiting for current transactions on the table to complete.
All current transactions on the table complete, all new ones are stuck behind the rebuild lock
The rebuild gets its lock, prepares the MV log, starts the rebuild [...]

Cassandra内部机制 - 技巧

Cassandra内部运作 – 技巧
By Mike Perham Translated By Jametong

在前面的文章中,我介绍了Cassandra如何进行数据读/写.在此文中,我想要解释Cassandra中的一些技巧,Cassandra利用它们来提供一个可伸缩的分布式系统.

闲话协议(Gossip)

Cassandra是一个有单个节点组成的集群 – 其中没有“主”节点或单点故障-因此,每个节点都必须积极地确认集群中其他节点的状态。它们使用一个称为闲话(Gossip)的机制来做此事.每个节点每秒中都会将集群中每个节点的状态“以闲话的方式传播”到1-3个其他节点.系统为闲话数据添加了版本,因此一个节点的任何变更都会快速地传播遍整个集群.通过这种方式,每个节点都能知道任一其他节点的当前状态:是在正在自举呢, 还是正常运行呢,等等.

提示移交(Hinted Handoff)

在关于写操作的文章中,我提到Cassandra会存储数据的拷贝到N个节点.客户端可以根据数据的重要性选择一个一致性级别(Consistency level),例如, ConsistencyLevel.QUORUM表示,只有这N个节点中的多数返回成功才表示这个写操作成功.

如果这些节点中的一个宕机了,会发生什么呢?写操作稍后将如何传递到此节点呢?Cassandra使用了一种称为提示移交(Hinted Handoff)的技术来解决此问题,其中数据会被写入并保存到另一个随机节点X,并提示这些数据需要被保存到节点Y,并在节点重新在线时进行重放(记住,当节点Y变成在线时,闲话机制会快速通知X节点).提示移交可以确保节点Y可以快速的匹配上集群中的其他节点.注意,如果提示移交由于某种原因没有起作用,读修复最终仍然会“修复”这些过期数据,不过只有当客户端访问这些数据时才会进行读修复.

提示的写是不可读的(因为节点X并不是这N份拷贝的其中一个正式节点),因此,它们并不会记入写一致性.如果Cassandra的配置了3份拷贝,而其中的两个节点不可用,就不可能实现一个ConsistencyLevel.QUORUM的写操作.

逆熵(Anti-Entropy)

Cassandra的最后一个众所周知的秘密武器是逆熵(Anti-entropy).逆熵明确保证集群中的节点一致认可当前数据.如果由于默认情况,读修复(read repair)与提示移交(hinted handoff)都没有生效,逆熵会确保节点达到最终一致性.逆熵服务是在“主压缩”(等价与关系数据库中的重建表)时运行的,因此,它是一个相对重量级但运行不频繁的进程.逆熵使用Merkle树(也称为散列树)来确定节点在列族(column family)数据树内的什么位置不能一致认可,接着修复该位置的每一个分支.

这是我介绍Cassandra系列的最后一篇文章. 我希望你能喜欢它们.如果你有什么问题, 或者我上面的描述有什么错误,请留下你的建议.

Cassandra内部机制 : 读操作

Cassandra内部机制 : 读操作
By Mike Perham Translated By Jametong

在上一篇文章中,我介绍了Cassandra中的写操作是如何工作的,以及写操作为什么能够如此之快.下面,我将介绍读操作以及为何它是如此之慢.

读操作与一致性

Brewer的CAP定理是分布式系统中的一个基本定理:分布式系统可以有一致性(Consistency)、可用性(Availability)以及分区容错性(Partition-tolerance)这三种属性,但是只能同时确保其中的两个属性.在Cassandra中,他们保证AP并弱化一致性为众所周知的最终一致性(Eventual Consistency). 考虑下面这种情况,读操作与写操作在时间上非常接近.假设你拥有一个Key “A”,它的值在你的集群中为“123”.现在,你将“A”更新为“456”.写操作被发送到N个不同的节点,每个节点都耗费部分时间来写这个值.现在,你发送一个读取Key “A”的请求.这些节点中的某些节点中这个Key对应的值可能仍然为“123”,而同时节点中的其他节点此Key的值为“456”.他们最终都会返回“456”,但并不能保证什么时候可以做到(在实践中,通常是几个毫秒的时间).接下来你就会发现为什么这一点很重要.

在你的客户端,读操作与写操作类似,客户端发送一个读请求到Cassandra集群中的任一随机节点(也就是存储代理,Storage Proxy).这个代理确定持有需要被读取数据的N份拷贝所在的环上的节点(根据复制放置策略),并对每一个节点发出一个读请求.由于最终一致性的限制,Cassadra允许客户端选择读一致性的强度:

单一读 – 代理返回它获得的第一份响应. 这样很可能返回过期的数据.
仲裁数读取 – 代理等待一个简单多数返回同样的数据.这样读取过期数据(除非有节点宕机)会变得更加困难,但也更慢了.

在后台,代理还会对任何不一致的响应执行读修复(read repair).代理会往任何返回较早的值的节点发送一个写请求,以确保这些节点在将来可以返回最新的值.下面是部分边缘状况,我不清楚Cassandra是如何进行处理的:

如果有偶数个节点有回应,其中一半返回值“X”而另一半返回值“Y”?由于每个列的值都有时间戳,我推测它可能会使用时间戳来做最后的裁判.
如果有两个包含旧时间戳的节点返回“X”而一个有新时间戳的节点返回“Y”,Cassandra该如何处理? 多数会覆盖时钟吗?
如果集群的节点的始终不同步,Cassandra会如何操作?

扫描范围

作为键值存储(Key/value store),Cassandra运转良好:给定一个键(Key),它就会为你返回这个键(Key)对应的值(Value).但这通常还不足以回答关键的问题:如果我想要读取所有姓(last name)从Z开始用户?或者读取所有在2010年2月1日到2010年3月1日之间下的订单?要回答这些问题,Cassandra必须知道如何来确定持有这些相关值的节点.这个工作是由分割器(Partitioner)来完成的.默认情况下,Cassandra会使用RandomPartitioner(随机分割器),它可以确保将负载均匀地分布在集群上,但是无法使用它来做范围扫描.作为替代,一个列族(Column Family)可以配置使用OrderPreservingPartitioner(保留顺序的分割器),它知道如何将一个范围的键(Key)映射(map)到一个或多个节点上.实际上,它知道哪个(些)节点持有你的按字母排序的用户的数据以及哪个(些)节点持有二月份的订单.

单一节点上的读取操作

因此,将分布式系统的所有胡说八道都放在一边,当执行读操作时每个节点在做什么? 回想一下, Cassandra有两个级别的存储:Memtable与SSTable. 从Memtable中读取相对无痛 – 我们是在内存中进行操作,数据量也相对较小,在这些内容中循环查找尽可能很快.扫描SSTable时,Cassandra使用一个更低级别的列索引与布隆过滤器(bloom filter)来查找磁盘上的必要的数据块,对数据进行反序列化(deserialize),并确定需要返回的真实数据. 这里会发生大量的磁盘IO,因此最终造成的读延时会比类似的DBMS还要高. Cassandra提供了部分行缓存(row caching),它确实解决大部分的延时.

这篇文章时一个Cassandra的读取路径的旋风之旅. 要想知道更多关于此主题的内容,请参考存储配置(StorageConfiguration)的维基文章. 我将在下篇文章中介绍Cassandra中的部分技巧(诀窍), Cassandra用它们来解决分布式系统内置的无数边缘状况.

google存储: 它到底是什么

Google存储: 它到底是什么
By Royans Tharakan Translated By Jametong

昨天Google在Google I/O上向我们中的部分人(5000个?) 宣布了Google Storage.下面是我从我参与的多个不同的讨论/讲座中看到的要点.

在开始之前,我要指出,Google打算提供的服务没有任何新意.Amazon一直在通过它的S3(Simple Storage Service)提供此项服务.关键的区别是,如果你是个Google的客户,你不再需要到其他地方去寻找与此类似的存储服务了.

下面就开始讨论技术细节吧:

它试图实现强一致性模型(CAP中的CA:一致性与可用性),这意味着你存储进去的数据将自动以一种一致的方式在多个数据中心之间进行复制.

当前,它复制到美国境内的多处数据中心.将来,它计划将其复制到全球的多个数据中心.
当前,没有控制接口来控制如何复制以及复制到何处.他们计划从Beta测试阶段的使用状况中学习,并在将来开发出控制接口.

每个对象有两个基本的组成部分

Buckets – Containers (桶 – 容器)

所有的对象都存储在扁平的容器中.不过,此工具可以理解”/”与”*”(通配符),使用正确的化可以做正确的事情.

Objects – 对象/文件保存在此容器中.

实现RESTful API接口 (GET/PUT/POST/DELETE/HEAD/等等)

所有的资源通过一个URI来识别

理论上,桶(Bucket)或者容器(Container)没有大小限制.然而,在Beta测试阶段,每个账户将实施一个100GB的大小限制.
当然,它是构建在Google测试充分的、可扩展的、高可用的基础设施之上.
它提供多种灵活的认证与共享模型

支持标准的基于公钥/私钥的认证方式
也将与多个不同的组织(group)进行集成,以支持通过多重身份来共享对象或由多重身份来控制此对象
桶(Bucket)与对象上都可以应用访问控制列表(ACL, Access Control List)

桶(Bucket)

控制谁可以查看此对象列表
谁可以创建/删除对象
谁可以从桶中读取或往桶中写入

对象

谁可以读取对象
谁可以读/写对象

工具

讲座中提到了两种工具

GS Manager看上去像一个web应用,允许管理员来管理此服务.
GS util 更像AWS(Amazon Web service)为S3所提供的shell工具

前面我已经提到GS util接收通配符

因此,像下面这样的命令是可能出现的

gsutil cp gs://gs2010/* /home/rkt/gs2000

“解放数据”是Google创造此服务的其中一个目标.如前面的命令所示,它通过仅仅一行的代码来将你的所有数据转移出来.
目前还没有断点续传(resume)功能(当上传大量数据时出现网络中断),不过这个功能已经在开发计划中了.
还没有多版本(Versioning)功能.还不确定它是否在开发计划中,以及还需多久才能实现此功能.

部分其他想法.

当前,Google提供gmail/docs的存储,还不确定这两个存储服务与”Storage Service(存储服务)”有何关系.据我了解,这两个功能与存储服务没有关系,并且Google也没有计划对它们进行整合.
在Beta测试阶段,此服务对所有具有登陆权限的开发人员免费开放,但是,当它正式发布时,将采用此行业其他竞争者(S3)类似的定价模型.定价模型已经公布在Google Storage Service的网站上了.
发言人与产品经理对关于来自google app engine的存储访问是否收费(或以何种费率收费)没有发表评论.
他们通过对对象使用MD5签名的方式来确认客户端的对象是否与服务端的对象一致,但并不用它来存储文件本身.(因此MD5冲突问题并不会影响文件的存储)
美国海军已经使用此服务,并在Google Storage上存储了大约80TB的数据,我听说,他们谈到此服务时看似很满意.

我怀疑,这个产品在正式发布并对外开放之前,将保持由较长的一段Beta测试时间.