软件篇
亚数据库
我发明的新概念,就是称不上数据库但有一些数据库的特征。可以指缓存。
MemCached
Memcached是danga.com(运营LiveJournal的技术团队)开发的一套分布式内存对象缓存系统,用于在动态系统中减少数据库 负载,提升性能。
特点
协议简单
基于libevent的事件处理
内置内存存储方式
memcached不互相通信的分布式
Memcached处理的原子是每一个(key,value)对(以下简称kv对),key会通过一个hash算法转化成hash-key,便于查找、对比以及做到尽可能的散列。同时,memcached用的是一个二级散列,通过一张大hash表来维护。
Memcached有两个核心组件组成:服务端(ms)和客户端(mc),在一个memcached的查询中,mc先通过计算key的hash值来 确定kv对所处在的ms位置。当ms确定后,客户端就会发送一个查询请求给对应的ms,让它来查找确切的数据。因为这之间没有交互以及多播协议,所以 memcached交互带给 络的影响是最小化的。
内存分配
默认情况下,ms是用一个内置的叫“块分配器”的组件来分配内存的。舍弃c++标准的malloc/free的内存分配,而采用块分配器的主要目的 是为了避免内存碎片,否则操作系统要花费更多时间来查找这些逻辑上连续的内存块(实际上是断开的)。用了块分配器,ms会轮流的对内存进行大块的分配,并 不断重用。当然由于块的大小各不相同,当数据大小和块大小不太相符的情况下,还是有可能导致内存的浪费。
同时,ms对key和data都有相应的限制,key的长度不能超过250字节,data也不能超过块大小的限制 — 1MB。
因为mc所使用的hash算法,并不会考虑到每个ms的内存大小。理论上mc会分配概率上等量的kv对给每个ms,这样如果每个ms的内存都不太一样,那 可能会导致内存使用率的降低。所以一种替代的解决方案是,根据每个ms的内存大小,找出他们的最大公约数,然后在每个ms上开n个容量=最大公约数的 instance,这样就等于拥有了多个容量大小一样的子ms,从而提供整体的内存使用率。
缓存策略
当ms的hash表满了之后,新的插入数据会替代老的数据,更新的策略是LRU(最近最少使用),以及每个kv对的有效时限。Kv对存储有效时限是在mc端由app设置并作为参数传给ms的。
同时ms采用是偷懒替代法,ms不会开额外的进程来实时监测过时的kv对并删除,而是当且仅当,新来一个插入的数据,而此时又没有多余的空间放了,才会进行清除动作。
缓存数据库查询
现在memcached最流行的一种使用方式是缓存数据库查询,下面举一个简单例子说明:
App需要得到userid=xxx的用户信息,对应的查询语句类似:
“SELECT * FROM users WHERE userid = xxx”
App先去问cache,有没有“user:userid”(key定义可预先定义约束好)的数据,如果有,返回数据;如果没有,App会从数据库中读取数据,并调用cache的add函数,把数据加入cache中。
当取的数据需要更新,app会调用cache的update函数,来保持数据库与cache的数据同步。
从上面的例子我们也可以发现,一旦数据库的数据发现变化,我们一定要及时更新cache中的数据,来保证app读到的是同步的正确数据。当然我们可 以通过定时器方式记录下cache中数据的失效时间,时间一过就会激发事件对cache进行更新,但这之间总会有时间上的延迟,导致app可能从 cache读到脏数据,这也被称为狗洞问题。(以后我会专门描述研究这个问题)
数据冗余与故障预防
从设计角度上,memcached是没有数据冗余环节的,它本身就是一个大规模的高性能cache层,加入数据冗余所能带来的只有设计的复杂性和提高系统的开支。
当一个ms上丢失了数据之后,app还是可以从数据库中取得数据。不过更谨慎的做法是在某些ms不能正常工作时,提供额外的ms来支持cache,这样就不会因为app从cache中取不到数据而一下子给数据库带来过大的负载。
同时为了减少某台ms故障所带来的影响,可以使用“热备份”方案,就是用一台新的ms来取代有问题的ms,当然新的ms还是要用原来ms的IP地址,大不了数据重新装载一遍。
另外一种方式,就是提高你ms的节点数,然后mc会实时侦查每个节点的状态,如果发现某个节点长时间没有响应,就会从mc的可用server列表里 删除,并对server节点进行重新hash定位。当然这样也会造成的问题是,原本key存储在B上,变成存储在C上了。所以此方案本身也有其弱点,最好 能和“热备份”方案结合使用,就可以使故障造成的影响最小化。
Memcached客户端(mc)
Memcached客户端有各种语言的版本供大家使用,包括java,c,php,.net等等,具体可参见[2]。
大家可以根据自己项目的需要,选择合适的客户端来集成。
缓存式的Web应用程序架构
有了缓存的支持,我们可以在传统的app层和db层之间加入cache层,每个app服务器都可以绑定一个mc,每次数据的读取都可以从ms中取得,如果 没有,再从db层读取。而当数据要进行更新时,除了要发送update的sql给db层,同时也要将更新的数据发给mc,让mc去更新ms中的数据。
性能测试
Memcached 写速度
平均速度: 16222 次/秒
最大速度 18799 次/秒
Memcached 读速度
平均速度: 20971 次/秒
最大速度 22497 次/秒
Memcachedb 写速度
平均速度: 8958 次/秒
最大速度 10480 次/秒
Memcachedb 读速度
平均速度: 6871 次/秒
最大速度 12542 次/秒
dbcached
● dbcached 是一款基于 Memcached 和 NMDB 的分布式 key-value 数据库内存缓存系统。
● dbcached = Memcached + 持久化存储管理器 + NMDB 客户端接口
● Memcached 是一款高性能的,分布式的内存对象缓存系统,用于在动态应用中减少数据库负载,提升访问速度。
● NMDB 是一款多协议 络数据库(dbm类)管理器,它由内存缓存和磁盘存储两部分构成,使用 QDBM 或 Berkeley DB 作为后端数据库。
● QDBM 是一个管理数据库的例程库,它参照 GDBM 为了下述三点而被开发:更高的处理速度,更小的数据库文件大小,和更简单的API。QDBM 读写速度比 Berkeley DB 要快,详细速度比较见《》。
Memcached 和 dbcached 在功能上一样吗?
● 兼容:Memcached 能做的,dbcached 都能做。除此之外,dbcached 还将“Memcached、持久化存储管理器、NMDB 客户端接口”在一个程序中结合起来,对任何原有 Memcached 客户端来讲,dbcached 仍旧是个 Memcached 内存对象缓存系统,但是,它的数据可以持久存储到本机或其它服务器上的 QDBM 或 Berkeley DB 数据库中。
● 性能:前端 dbcached 的并发处理能力跟 Memcached 相同;后端 NMDB 跟 Memcached 一样,采用了libevent 进行 络IO处理,拥有自己的内存缓存机制,性能不相上下。
● 写入:当“dbcached 的 Memcached 部分”接收到一个 set(add/replace/…) 请求并储存 key-value 数据到内存中后,“dbcached 持久化存储管理器”能够将 key-value 数据通过“NMDB 客户端接口”保存到 QDBM 或 Berkeley DB 数据库中。
● 速度:如果加上“-z”参数,采用 UDP 协议“只发送不接收”模式将 set(add/replace/…) 命令写入的数据传递给 NMDB 服务器端,对 Memcache 客户端写速度的影响几乎可以忽略不计。在千兆 卡、同一交换机下服务器之间的 UDP 传输丢包率微乎其微。在命中的情况下,读取数据的速度跟普通的 Memcached 无差别,速度一样快。
● 读取:当“dbcached 的 Memcached 部分”接收到一个 get(incr/decr/…) 请求后,如果“dbcached 的 Memcached 部分”查询自身的内存缓存未命中,则“dbcached 持久化存储管理器”会通过“NMDB 客户端接口”从 QDBM 或 Berkeley DB 数据库中取出数据,返回给用户,然后储存到 Memcached 内存中。如果有用户再次请求这个 key,则会直接从 Memcached 内存中返回 Value 值。
● 持久:使用 dbcached,不用担心 Memcached 服务器死机、重启而导致数据丢失。
● 变更:使用 dbcached,即使因为故障转移,添加、减少 Memcached 服务器节点而破坏了“key 信息”与对应“Memcached 服务器”的映射关系也不怕。
● 分布:dbcached 和 NMDB 既可以安装在同一台服务器上,也可以安装在不同的服务器上,多台 dbcached 服务器可以对应一台 NMDB 服务器。
● 特长:dbcached 对于“读”大于“写”的应用尤其适用。
● 其他:《》
列存系列 Hadoop之Hbase
: API: Java / any writer, Protocol: any write call, Query Method: MapReduce Java / any exec, Replication: HDFS Replication, Written in: Java, Concurrency: ?, Misc: Links: 3 Books [, , ]
耶鲁大学之HadoopDB
GreenPlum
FaceBook之Cassandra
: API: manyThriftlanguages, Protocol: ?, Query Method: MapReduce, Replicaton: , Written in: Java, Concurrency: eventually consistent, Misc: like “Big-Table on Amazon Dynamo alike”, initiated by Facebook, Slides , Clients
Cassandra是facebook开源出来的一个版本,可以认为是BigTable的一个开源版本,目前twitter和digg.com在使用。
Cassandra特点
灵活的schema,不需要象数据库一样预先设计schema,增加或者删除字段非常方便(on the fly)。
支持range查询:可以对Key进行范围查询。
高可用,可扩展:单点故障不影响集群服务,可线性扩展。
Cassandra的主要特点就是它不是一个数据库,而是由一堆数据库节点共同构成的一个分布式 络服务,对Cassandra的一个写操作,会 被复制到其他节点上去,对Cassandra的读操作,也会被路由到某个节点上面去读取。对于一个Cassandra群集来说,扩展性能是比较简单的事 情,只管在群集里面添加节点就可以了。我看到有文章说Facebook的Cassandra群集有超过100台服务器构成的数据库群集。
Cassandra也支持比较丰富的数据结构和功能强大的查询语言,和MongoDB比较类似,查询功能比MongoDB稍弱一些,twitter的平台架构部门领导Evan Weaver写了一篇文章介绍Cassandra:,有非常详细的介绍。
Cassandra以单个节点来衡量,其节点的并发读写性能不是特别好,有文章说评测下来Cassandra每秒大约不到1万次读写请求,我也看 到一些对这个问题进行质疑的评论,但是评价Cassandra单个节点的性能是没有意义的,真实的分布式数据库访问系统必然是n多个节点构成的系统,其并 发性能取决于整个系统的节点数量,路由效率,而不仅仅是单节点的并发负载能力。
Keyspace
Cassandra中的最大组织单元,里面包含了一系列Column family,Keyspace一般是应用程序的名称。你可以把它理解为Oracle里面的一个schema,包含了一系列的对象。
Column family(CF)
CF是某个特定Key的数据集合,每个CF物理上被存放在单独的文件中。从概念上看,CF有点象数据库中的Table.
Key
数据必须通过Key来访问,Cassandra允许范围查询,例如:start => ‘10050’, :finish => ‘10070’
Column
在Cassandra中字段是最小的数据单元,column和value构成一个对,比如:name:“jacky”,column是name,value是jacky,每个column:value后都有一个时间戳:timestamp。
和数据库不同的是,Cassandra的一行中可以有任意多个column,而且每行的column可以是不同的。从数据库设计的角度,你可以理解 为表上有两个字段,第一个是Key,第二个是长文本类型,用来存放很多的column。这也是为什么说Cassandra具备非常灵活schema的原 因。
Super column
Super column是一种特殊的column,里面可以存放任意多个普通的column。而且一个CF中同样可以有任意多个Super column,一个CF只能定义使用Column或者Super column,不能混用。下面是Super column的一个例子,homeAddress这个Super column有三个字段:分别是street,city和zip: homeAddress: {street: “binjiang road”,city: “hangzhou”,zip: “310052”,}
Sorting
不同于数据库可以通过Order by定义排序规则,Cassandra取出的数据顺序是总是一定的,数据保存时已经按照定义的规则存放,所以取出来的顺序已经确定了,这是一个巨大的性能优势。有意思的是,Cassandra按照column name而不是column value来进行排序,它 定义了以下几种选项:BytesType, UTF8Type, LexicalUUIDType, TimeUUIDType, AsciiType, 和LongType,用来定义如何按照column name来排序。实际上,就是把column name识别成为不同的类型,以此来达到灵活排序的目的。UTF8Type是把column name转换为UTF8编码来进行排序,LongType转换成为64位long型,TimeUUIDType是按照基于时间的UUID来排序。例如:
我们看到一个叫Twitter的keyspace,包含若干个CF,其中StatusRelationships和 UserRelationships被定义为包含Super column的CF,CompareWith定义了column的排序规则,CompareSubcolumnsWith定义了subcolumn的排序 规则,这里使用了两种:TimeUUIDType和UTF8Type。我们没有看到任何有关column的定义,这意味着column是可以灵活变更的。
为了方便大家理解,我会尝试着用关系型数据库的建模方法去描述Twitter的Schema,但千万不要误认为这就是Cassandra的数据模型,对于Cassandra来说,每一行的colunn都可以是任意的,而不是象数据库一样需要在建表时就创建好。
Users CF记录用户的信息,Statuses CF记录tweets的内容,StatusRelationships CF记录用户看到的tweets,UserRelationships CF记录用户看到的followers。我们注意到排序方式是TimeUUIDType,这个类型是按照时间进行排序的UUID字段,column name是用UUID函数产生(这个函数返回了一个UUID,这个UUID反映了当前的时间,可以根据这个UUID来排序,有点类似于timestamp 一样),所以得到结果是按照时间来排序的。使用过twitter的人都知道,你总是可以看到自己最新的tweets或者最新的friends.
存储
Cassandra是基于列存储的(Bigtable也是一样),这个和基于列的数据库是一个道理。
API
我对Cassandra数据模型的理解:
1.column name存放真正的值,而value是空。因为Cassandra是按照column name排序,而且是按列存储的,所以往往利用column name存放真正的值,而value部分则是空。例如:“jacky”:“null”,“fenng”:”null”
2.Super column可以看作是一个索引,有点象关系型数据库中的外键,利用super column可以实现快速定位,因为它可以返回一堆column,而且是排好序的。
3.排序在定义时就确定了,取出的数据肯定是按照确定的顺序排列的,这是一个巨大的性能优势。
4. 非常灵活的schema,column可以灵活定义。实际上,colume name在很多情况下,就是value(是不是有点绕)。
5.每个column后面的timestamp,我并没有找到明确的说明,我猜测可能是数据多版本,或者是底层清理数据时需要的信息。
最后说说架构,我认为架构的核心就是有所取舍,不管是CAP还是BASE,讲的都是这个原则。架构之美在于没有任何一种架构可以完美的解决各种问题,数据库和NoSQL都有其应用场景,我们要做的就是为自己找到合适的架构。
Hypertable
: (can you help?) Open-Source Google BigTable alike.
它是搜索引擎公司Zvents根据Google的9位研究人员在2006年发表的一篇论文《》 开发的一款开源分布式数据储存系统。Hypertable是按照1000节点比例设计,以 C++撰写,可架在 HDFS 和 KFS 上。尽管还在初期阶段,但已有不错的效能:写入 28M 列的资料,各节点写入速率可达7MB/s,读取速率可达 1M cells/s。Hypertable目前一直没有太多高负载和大存储的应用实例,但是最近,Hypertable项目得到了的赞助支持,相信其会有更好的发展。
Google之BigTable
研究Google的产品总是感激Google给了自己那么多方便,真心喜欢之。
Google AppEngine Datastore 是在BigTable之上建造出来的,是Google的内部存储系统,用于处理结构化数据。AppEngine Datastore其自身及其内部都不是直接访问BigTable的实现机制,可被视为BigTable之上的一个简单接口。
AppEngine Datastore所支持的项目的数据类型要比SimpleDB丰富得多,也包括了包含在一个项目内的数据集合的列表型。
如果你打算在Google AppEngine之内建造应用的话,几乎可以肯定要用到这个数据存储。然而,不像SimpleDB,使用谷歌 络服务平台之外的应用,你并不能并发地与AppEngine Datastore进行接口 (或通过BigTable)。
Yahoo之PNUTS
Yahoo!的PNUTS是一个分布式的数据存储平台,它是Yahoo!云计算平台重要的一部分。它的上层产品通常也称为Sherpa。按照官方的 描述,”PNUTS, a massively parallel and geographically distributed database system for Yahoo!’s web applications.” PNUTS显然就深谙CAP之道,考虑到大部分web应用对一致性并不要求非常严格,在设计上放弃了对强一致性的追求。代替的是追求更高的 availability,容错,更快速的响应调用请求等。
特点
地理分布式,分布在全球多个数据中心。由于大部分Web应用都对响应时间要求高,因此最好服务器部署在离用户最近的本地机房。
可扩展,记录数可支持从几万条到几亿条。数据容量增加不会影响性能。
schema-free,即非固定表结构。实际使用key/value存储的,一条记录的多个字段实际是用json方式合并存在value中。因此delete和update必须指定primary key。但也支持批量查询。
高可用性及容错。从单个存储节点到整个数据中心不可用都不会影响前端Web访问。
适合存相对小型的记录,不适合存储大文件,流媒体等。
弱一致性保证。
PNUTS实现 Record-level mastering 记录级别主节点
每一条记录都有一个主记录。比如一个印度的用户保存的记录master在印度机房,通常修改都会调用印度。其他地方如美国用户看这个用户的资料调用 的是美国数据中心的资料,有可能取到的是旧版的数据。非master机房也可对记录进行修改,但需要master来统一管理。每行数据都有自己的版本控 制,如下图所示。
PNUTS的结构
每个数据中心的PNUTS结构由四部分构成
Storage Units (SU) 存储单元
物理的存储服务器,每个存储服务器上面含有多个tablets,tablets是PNUTS上的基本存储单元。一 个tablets是一个yahoo内部格式的hash table的文件(hash table)或是一个MySQL innodb表(ordered table)。一个Tablet通常为几百M。一个SU上通常会存在几百个tablets。
Routers
每个tablets在哪个SU上是通过查询router获得。一个数据中心内router通常可由两台双机备份的单元提供。
Tablet Controller
router的位置只是个内存快照,实际的位置由Tablet Controller单元决定。
Message Broker
与远程数据的同步是由YMB提供,它是一个pub/sub的异步消息订阅系统。
Tablets寻址与切分
存储分hash和ordered data store。
以hash为例介绍,先对所有的tablets按hash值分片,比如1-10,000属于tablets 1, 10,000到20,000属于tablets 2,依此类推分配完所有的hash范围。一个大型的IDC通常会存在100万以下的tablets, 1,000台左右的SU。tablets属于哪个SU由routers全部加载到内存里面,因此router访问速度极快,通常不会成为瓶颈。按照官方的 说法,系统的瓶颈只存在磁盘文件hash file访问上。
当某个SU访问量过大,则可将SU中部分tablets移到相对空闲的SU,并修改tablet controller的偏移记录。router定位tablet失效之后会自动通过tablet controller重新加载到内存。所以切分也相对容易实现。
Tim也曾经用MySQL实现过类似大规模存储的系统,当时的做法是把每条记录的key属于哪个SU的信息保存到 一个字典里面,好处是切分可以获得更大的灵活性,可以动态增加新的tablets,而不需要切分旧的tablets。但缺点就是字典没法像router这 样,可以高效的全部加载到内存中。所以比较而言,在实际的应用中,按段分片会更简单,且已经足够使用。
Write调用示意图
PNUTS感悟 2006年Greg Linden就说
详细资料:
http://timyang.net/architecture/yahoo-pnuts/
微软之SQL数据服务
是微软 络服务平台的一部分。该SDS服务也是处于测试阶段,因此也是免费的,但对数据库大小有限制。 SQL数据服务其自身实际上是一项处在许多SQL服务器之上的应用,这些SQL服务器组成了SDS平台底层的数据存储。你不需要访问到它们,虽然底层的数 据库可能是关系式的;SDS是一个键/值型仓储,正如我们迄今所讨论过的其它平台一样。
微软看起来不同于前三个供应商,因为虽然键/值存储对于可扩性???言非常棒,相对于RDBMS,在数据管理上却很困难。微软的方案似乎是入木三分,在实现可扩性和分布机制的同时,随着时间的推移,不断增加特性,在键/值存储和关系数据库平台的鸿沟之间搭起一座桥梁。
非云服务竞争者
在云之外,也有一些可以独立安装的键/值数据库软件产品。大部分都还很年轻,不是alpha版就是beta版,但大都是开源的;通过看看它的代码,比起在非开源供应商那里,你也许更能意识到潜在的问题和限制。
文档存储 CouchDB
: API: JSON, Protocol: REST, Query Method: MapReduceR of Java Funcs, Replication: Master Master, Written in: Erlang, Concurrency: MVCC, Misc:
Links: 3 CouchDB books , Couch Lounge (partitioning / clusering), …
它是Apache 区基于 Erlang/OTP 构建的高性能、分布式容错非关系型数据库系统(NRDBMS)。它充分利用 Erlang 本身所提供的高并发、分布式容错基础平台,并且参考 Lotus Notes 数据库实现,采用简单的文档数据类型(document-oriented)。在其内部,文档数据均以 JSON 格式存储。对外,则通过基于 HTTP 的 REST 协议实现接口,可以用十几种语言进行自由操作。
CouchDB一种半结构化面向文档的???布式,高容错的数据库系统,其提供RESTFul HTTP/JSON接口。其拥有MVCC特性,用户可以通过自定义Map/Reduce函数生成对应的View。
在CouchDB中,数据是以JSON字符的方式存储在文件中。
特性
RESTFul API:HTTP GET/PUT/POST/DELETE + JSON
基于文档存储,数据之间没有关系范式要求
每个数据库对应单个个文件(以JSON保存),Hot backup
MVCC(Multi-Version-Concurrency-Control),读写均不锁定数据库
用户自定义View
内建备份机制
支持附件
使用Erlang开发(更多的特性)
应用场景 在我们的生活中,有很多document,比如信件,账单,笔记等,他们只是简单的信息,没有关系的需求,我们可能仅仅需要存储这些数据。 这样的情况下,CouchDB应该是很好的选择。当然其他使用关系型数据库的环境,也可以使用CouchDB来解决。
根据CouchDB的特性,在某些偶 尔连接 络的应用中,我们可以用CouchDB暂存数据,随后进行同步。也可以在Cloud环境中,作为分布式的数据存储。CouchDB提供给予 HTTP的API,这样所有的常见语言都可以使用CouchDB。
使用CouchDB,意味着我们不需要在像使用RMDBS一样,在设计应用前首先设计负责数据Table。我们的开发更加快速,灵活。
详细参见:
http://www.javaeye.com/topic/319839
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是 类似json的bjson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语 言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
Mongo主要解决的是海量数据的访问效率问题,根据官方的文档,当数据量达到50GB以上的时候,Mongo的数据库访问速度是MySQL的 10倍以上。Mongo的并发读写效率不是特别出色,根据官方提供的性能测试表明,大约每秒可以处理0.5万-1.5次读写请求。对于Mongo的并发读 写性能,我(robbin)也打算有空的时候好好测试一下。
因为Mongo主要是支持海量数据存储的,所以Mongo还自带了一个出色的分布式文件系统GridFS,可以支持海量的数据存储,但我也看到有些评论认为GridFS性能不佳,这一点还是有待亲自做点测试来验证了。
最后由于Mongo可以支持复杂的数据结构,而且带有强大的数据查询功能,因此非常受到欢迎,很多项目都考虑用MongoDB来替代MySQL来实现不是特别复杂的Web应用,比方说就是一个真实的从MySQL迁移到MongoDB的案例,由于数据量实在太大,所以迁移到了Mongo上面,数据查询的速度得到了非常显著的提升。
MongoDB也有一个ruby的项目,是模仿Merb的DataMapper编写的MongoDB的接口,使用起来非常简单,几乎和DataMapper一模一样,功能非常强大易用。
Key Value / Tuple 存储 Amazon之SimpleDB
: Misc: not open source, Book
SimpleDB有几方面的限制。首先,一次查询最多只能执行5秒钟。其次,除了字符串类型,别无其它数据类型。一切都以字符串形式被存储、获取和 比较,因此除非你把所有日期都转为ISO8601,否则日期比较将不起作用。第三,任何字符串长度都不能超过1024字节,这限制了你在一个属性中能存储 的文本的大小(比如说产品描述等)。不过,由于该模式动态灵活,你可以通过追加“产品描述1”、“产品描述2”等来绕过这类限制。一个项目最多可以有 256个属性。由于处在测试阶段,SimpleDB的域不能大于10GB,整个库容量则不能超过1TB。
SimpleDB的一项关键特性是它使用一种。 这个一致性模型对并发性很有好处,但意味着在你改变了项目属性之后,那些改变有可能不能立即反映到随后的读操作上。尽管这种情况实际发生的几率很低,你也 得有所考虑。比如说,在你的演出订票系统里,你不会想把最后一张音乐会门票卖给5个人,因为在售出时你的数据是不一致的。
Redis是一个很新的项目,刚刚发布了1.0版本。Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库统 统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存。因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过 10万次读写操作,是我知道的性能最快的Key-Value DB。
Redis的出色之处不仅仅是性能,Redis最大的魅力是支持保存List链表和Set集合的数据结构,而且还支持对List进行各种操作,例 如从List两端push和pop数据,取List区间,排序等等,对Set支持各种集合的并集交集操作,此外单个value的最大限制是1GB,不像 memcached只能保存1MB的数据,因此Redis可以用来实现很多有用的功能,比方说用他的List来做FIFO双向链表,实现一个轻量级的高性 能消息队列服务,用他的Set可以做高性能的tag系统等等。另外Redis也可以对存入的Key-Value设置expire时间,因此也可以被当作一 个功能加强版的memcached来用。
Redis的主要缺点是数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,并且它没有原生的可扩展机制,不具有scale(可扩展) 能力,要依赖客户端来实现分布式读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。目前使用Redis的 站有 github,Engine Yard。
它是日本最大的SNS 交 站mixi.jp开发的 Tokyo Cabinet key-value数据库 络接口。它拥有Memcached兼容协议,也可以通过HTTP协议进行数据交换。对任何原有Memcached客户端来讲, 可以将Tokyo Tyrant看成是一个Memcached,但是,它的数据是可以持久存储的。Tokyo Tyrant 具有故障转移、日志文件体积小、大数据量下表现出色等优势,详见:http://blog.s135.com/post/362.htm
Tokyo Cabinet 2009年1月18日发布的新版本(Version 1.4.0)已经实现 Table Database,将key-value数据库又扩展了一步,有了MySQL等关系型数据库的表和字段的概念,相信不久的将来,Tokyo Tyrant 也将支持这一功能。值得期待。
TC除了支持Key-Value存储之外,还支持保存Hashtable数据类型,因此很像一个简单的数据库表,并且还支持基于column的条 件查询,分页查询和排序功能,基本上相当于支持单表的基础查询功能了,所以可以简单的替代关系数据库的很多操作,这也是TC受到大家欢迎的主要原因之一, 有一个Ruby的项目将TT的hashtable的操作封装成和ActiveRecord一样的操作,用起来非常爽。
TC/TT在mixi的实际应用当中,存储了2000万条以上的数据,同时支撑了上万个并发连接,是一个久经考验的项目。TC在保证了极高的并发 读写性能的同时,具有可靠的数据持久化机制,同时还支持类似关系数据库表结构的hashtable以及简单的条件,分页和排序操作,是一个很棒的 NoSQL数据库。
这个是Tim Yang做的一个
它是新浪互动 区事业部为在Memcached基础上,增加Berkeley DB存储层而开发一款支持高并发的分布式持久存储系统,对任何原有Memcached客户端来讲,它仍旧是个Memcached,但是,它的数据是可以持久存储的。
Flare
TC是日本第一大SNS 站mixi开发的,而Flare是日本第二大SNS 站green.jp开发的,有意思吧。Flare简单的说就是给 TC添加了scale功能。他替换掉了TT部分,自己另外给TC写了 络服务器,Flare的主要特点就是支持scale能力,他在 络服务端之前添加了 一个node server,来管理后端的多个服务器节点,因此可以动态添加数据库服务节点,删除服务器节点,也支持failover。如果你的使用场景必须要让TC可 以scale,那么可以考虑flare。
flare唯一的缺点就是他只支持memcached协议,因此当你使用flare的时候,就不能使用TC的table数据结构了,只能使用TC的key-value数据结构存储。
最终一致性Key Value存储 Amazon之Dynamo
: Misc: not open source (see KAI below)
功能特色
高可用
可扩展
总是可写
可以根据应用类型优化(可用性,容错性,高效性配置)
架构特色
BeansDB 简介
BeansDB 是一个主要针对大数据量、高可用性的分布式KeyValue存储系统,采用HashTree和简化的版本 来快速同步保证最终一致性(弱),一个简化版的Dynamo。
它采用类似memcached的去中心化结构,在客户端实现数据路由。目前只提供了Python版本的客户端,其它语言的客户端可以由memcached的客户端稍加改造得到。
Google Group:
更新
2009.12.29 第一个公开版本 0.3
特性
高可用:通过多个可读写的用于备份实现高可用
最终一致性:通过哈希树实现快速完整数据同步(短时间内数据可能不一致)
容易扩展:可以在不中断服务的情况下进行容量扩展。
高性能:异步IO和高性能的KeyValue数据TokyoCabinet 可配置的
可用性和一致性:通过N,W,R进行配置 简单协议:Memcache兼容协议,大量可用客户端
性能
Nuclear
人人 研发中的数据库
详见:
http://ugc.renren.com/2010/01/21/ugc-nuclear-guide-use/
http://ugc.renren.com/2010/01/28/ugc-nuclear-guide-theory/
两个设计上的Tips
1. 万事皆异步
我们在编码的过程中走了一些弯路,同步的操作在高并发的情况下带来的性能下降是非常恐怖的,于是乎,Nuclear系统中任何的高并发操作都消除了Block。no waiting, no delay。
2. 根据系统负载控制后台线程的资源占用
Nuclear系统中有不少的后台线程默默无闻的做着各种辛苦的工作,但是它们同样会占用系统资源,我们的解决方案是根据系统负载动态调整线程的运行和停止,并达到平衡。
Voldemort
:(can you help)
Voldemort是个和Cassandra类似的面向解决scale问题的分布式数据库系统,Cassandra来自于Facebook这个 SNS 站,而Voldemort则来自于Linkedin这个SNS 站。说起来SNS 站为我们贡献了n多的NoSQL数据库,例如 Cassandar,Voldemort,Tokyo Cabinet,Flare等等。Voldemort的资料不是很多,因此我没有特别仔细去钻研,Voldemort官方给出Voldemort的并发读 写性能也很不错,每秒超过了1.5万次读写。
其实现在很多公司可能都面临着这个抽象架构图中的类似问题。以 Hadoop 作为后端的计算集群,计算得出来的数据如果要反向推到前面去,用什么方式存储更为恰当? 再放到 DB 里面的话,构建索引是麻烦事;放到 Memcached 之类的 Key-Value 分布式系统中,毕竟只是在内存里,数据又容易丢。算是一个不错的改良方案。
值得借鉴的几点:
键(Key)结构的设计,有点技巧;
架构师熟知硬件结构是有用的。越大的系统越是如此。
用好并行。以后出现的场合会更多。
详细:
http://www.dbanotes.net/arch/voldemort_key-value.html
http://project-voldemort.com/blog/2009/06/building-a-1-tb-data-cycle-at-linkedin-with-hadoop-and-project-voldemort/
Dynomite
:(can you help)
Kai
: Open Source Amazon Dnamo implementation, Misc: ,
未分类 Skynet
全新的Ruby MapReduce实现
2004年,Google提出用于分布式数据处理的MapReduce设计模式,同时还提供了第一个C++的实现。现在,一个名为Skynet的Ruby实现已经由Adam Pisoni发布。
Skynet是可适配、可容错的、可自我更新的,而且完全
是分布式的系统,不存在单一的失败节点。
Skynet和Google在设计上有两点重要的区别:
Skynet的使用和设置都很容易,这也正是MapReduce这个概念的真正优势。Skynet还扩展了ActiveRecord,加入了MapReduce的特性,比如distributed_find。
你要为Starfish编写一些小程序,它们的代码是你将要构建其中的。如果我没有弄错的话,你无法在同一台机器上运行多种类型的MapReduce作业。Skynet是一个更全面的MR系统,可以运行多种类型的多个作业,比如,各种不同的代码。
什 么是map_data流?大多数时候,在你准备启动一个map_reduce作业时,必须提供一个数据的队列,这些数据已经被分离并将被并行处理。如果队 列过大,以至于无法适应于内存怎么办?在这种情况下,你就要不能再用队列,而应该使用枚举(Enumerable)。Skynet知道去对象的调 用:next或者:each方法,然后开始为“每一个(each)”分离出map_task来。通过这样的方式,不会有人再试图同时创建大量的数据结构。
还 有很多特性值得一提,不过最想提醒大家的是,Skynet能够与你现有的应用非常完美地集成到一起,其中自然包括Rails应用。Skynet甚 至还提供了一个ActiveRecord的扩展,你可以在模型中以分布式的形式执行一些任务。在Geni中,我们使用这项功能来运行特别复杂的移植,它通 常涉及到在数百万的模型上执行Ruby代码。
Drizzle
Drizzle可 被认为是键/值存储要解决的问题的反向方案。Drizzle诞生于MySQL(6.0)关系数据库的拆分。在过去几个月里,它的开发者已经移走了大量非核 心的功能(包括视图、触发器、已编译语句、存储过程、查询缓冲、ACL以及一些数据类型),其目标是要建立一个更精简、更快的数据库系统。Drizzle 仍能存放关系数据;正如MySQL/Sun的Brian Aker所说那样:“没理由泼洗澡水时连孩子也倒掉”。它的目标就是,针对运行于16核(或以上)系统上的以 络和云为基础的应用,建立一个半关系型数据 库平台。
比较 可扩展性
数据和查询模型
当你需要查询或更新一个值的一部分时,Key/value模型是最简单有效实现。
面向文本数据库是Key/value的下一步, 允许内嵌和Key关联的值. 支持查询这些值数据,这比简单的每次返回整个blob类型数据要有效得多。
Neo4J是唯一的存储对象和关系作为数学图论中的节点和边. 对于这些类型数据的查询,他们能够比其他竞争者快1000s
Scalaris是唯一提供跨越多个key的分布式事务。
持久化设计
内存数据库是非常快的,(Redis在单个机器上可以完成每秒100,000以上操作)但是数据集超过内存RAM大小就不行. 而且 Durability (服务器当机恢复数据)也是一个问题
Memtables和SSTables缓冲 buffer是在内存中写(“memtable”), 写之前先追加一个用于durability的日志中.
但有足够多写入以后,这个memtable将被排序然后一次性作为“sstable.”写入磁盘中,这就提供了近似内存性能,因为没有磁盘的查询seeks开销, 同时又避免了纯内存操作的durability问题.(个人点评 其实Java中的Terracotta早就实现这两者结合)
B-Trees提供健壮的索引,但是性能很差,一般和其他缓存结合起来。
微信扫一扫
关注该微信
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!