参考:http://blog.nosqlfan.com/html
随着互联网web2.0网站的兴起,非关系型的数据库如今成了一个极其热门的新领域,非关系数据库产品的发展很是迅速。而传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了不少难以克服的问题,例如:
一、High performance - 对数据库高并发读写的需求
web2.0网站要根据用户个性化信息来实时生成动态页面和提供动态信息,因此基本上没法使用动态页面静态化技术,所以数据库并发负载很是高,每每要达到每秒上万次读写请求。关系数据库应付上万次SQL查询还勉强顶得住,可是应付上万次SQL写数据请求,硬盘IO就已经没法承受了。其实对于普通的BBS网站,每每也存在对高并发写请求的需求,例如像JavaEye网站的实时统计在线用户状态,记录热门帖子的点击次数,投票计数等,所以这是一个至关广泛的需求。
二、Huge Storage - 对海量数据的高效率存储和访问的需求
相似Facebook,twitter,Friendfeed这样的SNS网站,天天用户产生海量的用户动态,以Friendfeed为例,一个月就达到了2.5亿条用户动态,对于关系数据库来讲,在一张2.5亿条记录的表里面进行SQL查询,效率是极其低下乃至不可忍受的。再例如大型web网站的用户登陆系统,例如腾讯,盛大,动辄数以亿计的账号,关系数据库也很难应付。
三、High Scalability && High Availability- 对数据库的高可扩展性和高可用性的需求
在基于web的架构当中,数据库是最难进行横向扩展的,当一个应用系统的用户量和访问量与日俱增的时候,你的数据库却没有办法像web server和app server那样简单的经过添加更多的硬件和服务节点来扩展性能和负载能力。对于不少须要提供24小时不间断服务的网站来讲,对数据库系统进行升级和扩展是很是痛苦的事情,每每须要停机维护和数据迁移,为何数据库不能经过不断的添加服务器节点来实现扩展呢?
在上面提到的“三高”需求面前,关系数据库遇到了难以克服的障碍,而对于web2.0网站来讲,关系数据库的不少主要特性却每每无用武之地,例如:
一、数据库事务一致性需求
不少web实时系统并不要求严格的数据库事务,对读一致性的要求很低,有些场合对写一致性要求也不高。所以数据库事务管理成了数据库高负载下一个沉重的负担。
二、数据库的写实时性和读实时性需求
对关系数据库来讲,插入一条数据以后马上查询,是确定能够读出来这条数据的,可是对于不少web应用来讲,并不要求这么高的实时性,比方说我(JavaEye的robbin)发一条消息以后,过几秒乃至十几秒以后,个人订阅者才看到这条动态是彻底能够接受的。
三、对复杂的SQL查询,特别是多表关联查询的需求
任何大数据量的web系统,都很是忌讳多个大表的关联查询,以及复杂的数据分析类型的复杂SQL报表查询,特别是SNS类型的网站,从需求以及产品设计角度,就避免了这种状况的产生。每每更多的只是单表的主键查询,以及单表的简单条件分页查询,SQL的功能被极大的弱化了。
所以,关系数据库在这些愈来愈多的应用场景下显得不那么合适了,为了解决这类问题的非关系数据库应运而生,如今这两年,各类各样非关系数据库,特别是键值数据库(Key-Value Store DB)风起云涌,多得让人眼花缭乱。前不久国外刚刚举办了 NoSQL Conference,各路NoSQL数据库纷纷亮相,加上未亮相可是名声在外的,起码有超过10个开源的NoSQLDB,例如:
Redis,Tokyo Cabinet,Cassandra,Voldemort,MongoDB,Dynomite,HBase,CouchDB,Hypertable, Riak,Tin, Flare, Lightcloud, KiokuDB,Scalaris, Kai, ThruDB, ......
这些NoSQL数据库,有的是用C/C++编写的,有的是用Java编写的,还有的是用Erlang编写的,每一个都有本身的独到之处,看都看不过来了, 我(robbin)也只能从中挑选一些比较有特点,看起来更有前景的产品学习和了解一下。这些NoSQL数据库大体能够分为如下的三类:
1、知足极高读写性能需求的Kye-Value数据库:Redis,Tokyo Cabinet, Flare
高性能Key-Value数据库的主要特色就是具备极高的并发读写性能,Redis,Tokyo Cabinet, Flare,这3个Key-Value DB都是用C编写的,他们的性能都至关出色,但出了出色的性能,他们还有本身独特的功能:
一、 Redis
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。
二、 Tokyo Cabinet和Tokoy Tyrant
TC和TT的开发者是日本人Mikio Hirabayashi,主要被用在日本最大的SNS网站mixi.jp上,TC发展的时间最先,如今已是一个很是成熟的项目,也是Kye-Value数据库领域最大的热点,如今被普遍的应用在不少不少网站上。TC是一个高性能的存储引擎,而TT提供了多线程高并发服务器,性能也很是出色,每秒能够处理4-5万次读写操做。
TC除了支持Key-Value存储以外,还支持保存Hashtable数据类型,所以很像一个简单的数据库表,而且还支持基于column的条件查询,分页查询和排序功能,基本上至关于支持单表的基础查询功能了,因此能够简单的替代关系数据库的不少操做,这也是TC受到你们欢迎的主要缘由之一,有一个Ruby的项目 miyazakiresistance将TT的hashtable的操做封装成和ActiveRecord同样的操做,用起来很是爽。
TC/TT在mixi的实际应用当中,存储了2000万条以上的数据,同时支撑了上万个并发链接,是一个久经考验的项目。TC在保证了极高的并发读写性能的同时,具备可靠的数据持久化机制,同时还支持相似关系数据库表结构的hashtable以及简单的条件,分页和排序操做,是一个很棒的NoSQL数据库。
TC的主要缺点是在数据量达到上亿级别之后,并发写数据性能会大幅度降低, NoSQL: If Only It Was That Easy提到,他们发如今TC里面插入1.6亿条2-20KB数据的时候,写入性能开始急剧降低。看来是当数据量上亿条的时候,TC性能开始大幅度降低,从TC做者本身提供的mixi数据来看,至少上千万条数据量的时候尚未遇到这么明显的写入性能瓶颈。
这个是Tim Yang作的一个 Memcached,Redis和Tokyo Tyrant的简单的性能评测,仅供参考
三、 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数据结构存储。
2、知足海量存储需求和访问的面向文档的数据库:MongoDB,CouchDB
面向文档的非关系数据库主要解决的问题不是高性能的并发读写,而是保证海量数据存储的同时,具备良好的查询性能。MongoDB是用C++开发的,而CouchDB则是Erlang开发的:
一、 MongoDB
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构很是松散,是相似json的bjson格式,所以能够存储比较复杂的数据类型。Mongo最大的特色是他支持的查询语言很是强大,其语法有点相似于面向对象的查询语言,几乎能够实现相似关系数据库单表查询的绝大部分功能,并且还支持对数据创建索引。
Mongo主要解决的是海量数据的访问效率问题,根据官方的文档,当数据量达到50GB以上的时候,Mongo的数据库访问速度是MySQL的10倍以上。Mongo的并发读写效率不是特别出色,根据官方提供的性能测试代表,大约每秒能够处理0.5万-1.5次读写请求。对于Mongo的并发读写性能,我(robbin)也打算有空的时候好好测试一下。
由于Mongo主要是支持海量数据存储的,因此Mongo还自带了一个出色的分布式文件系统GridFS,能够支持海量的数据存储,但我也看到有些评论认为GridFS性能不佳,这一点仍是有待亲自作点测试来验证了。
最后因为Mongo能够支持复杂的数据结构,并且带有强大的数据查询功能,所以很是受到欢迎,不少项目都考虑用MongoDB来替代MySQL来实现不是特别复杂的Web应用,比方说 why we migrated from MySQL to MongoDB就是一个真实的从MySQL迁移到MongoDB的案例,因为数据量实在太大,因此迁移到了Mongo上面,数据查询的速度获得了很是显著的提高。
MongoDB也有一个ruby的项目 MongoMapper,是模仿Merb的DataMapper编写的MongoDB的接口,使用起来很是简单,几乎和DataMapper如出一辙,功能很是强大易用。
二、CouchDB
CouchDB如今是一个很是有名气的项目,彷佛不用多介绍了。可是我却对CouchDB没有什么兴趣,主要是由于CouchDB仅仅提供了基于HTTP REST的接口,所以CouchDB单纯从并发读写性能来讲,是很是糟糕的,这让我马上抛弃了对CouchDB的兴趣。
3、知足高可扩展性和可用性的面向分布式计算的数据库:Cassandra,Voldemort
面向scale能力的数据库其实主要解决的问题领域和上述两类数据库还不太同样,它首先必须是一个分布式的数据库系统,由分布在不一样节点上面的数据库共同构成一个数据库服务系统,而且根据这种分布式架构来提供online的,具备弹性的可扩展能力,例如能够不停机的添加更多数据节点,删除数据节点等等。所以像Cassandra经常被当作是一个开源版本的Google BigTable的替代品。Cassandra和Voldemort都是用Java开发的:
一、 Cassandra
Cassandra项目是Facebook在2008年开源出来的,随后Facebook本身使用Cassandra的另一个不开源的分支,而开源出来的Cassandra主要被Amazon的Dynamite团队来维护,而且Cassandra被认为是Dynamite2.0版本。目前除了Facebook以外,twitter和digg.com都在使用Cassandra。
Cassandra的主要特色就是它不是一个数据库,而是由一堆数据库节点共同构成的一个分布式网络服务,对Cassandra的一个写操做,会被复制到其余节点上去,对Cassandra的读操做,也会被路由到某个节点上面去读取。对于一个Cassandra群集来讲,扩展性能是比较简单的事情,只管在群集里面添加节点就能够了。我看到有文章说Facebook的Cassandra群集有超过100台服务器构成的数据库群集。
Cassandra也支持比较丰富的数据结构和功能强大的查询语言,和MongoDB比较相似,查询功能比MongoDB稍弱一些,twitter的平台架构部门领导Evan Weaver写了一篇文章介绍Cassandra: http://blog.evanweaver.com/articles/2009/07/06/up-and-running-with-cassandra/,有很是详细的介绍。
Cassandra以单个节点来衡量,其节点的并发读写性能不是特别好,有文章说评测下来Cassandra每秒大约不到1万次读写请求,我也看到一些对这个问题进行质疑的评论,可是评价Cassandra单个节点的性能是没有意义的,真实的分布式数据库访问系统必然是n多个节点构成的系统,其并发性能取决于整个系统的节点数量,路由效率,而不只仅是单节点的并发负载能力。
二、 Voldemort
Voldemort是个和Cassandra相似的面向解决scale问题的分布式数据库系统,Cassandra来自于Facebook这个SNS网站,而Voldemort则来自于Linkedin这个SNS网站。提及来SNS网站为咱们贡献了n多的NoSQL数据库,例如Cassandar,Voldemort,Tokyo Cabinet,Flare等等。Voldemort的资料不是不少,所以我没有特别仔细去钻研,Voldemort官方给出Voldemort的并发读写性能也很不错,每秒超过了1.5万次读写。
从Facebook开发Cassandra,Linkedin开发Voldemort,咱们也能够大体看出国外大型SNS网站对于分布式数据库,特别是对数据库的scale能力方面的需求是多么殷切。前面我(robbin)提到,web应用的架构当中,web层和app层相对来讲都很容易横向扩展,惟有数据库是单点的,极难scale,如今Facebook和Linkedin在非关系型数据库的分布式方面探索了一条很好的方向,这也是为何如今Cassandra这么热门的主要缘由。
现在,NoSQL数据库是个使人很兴奋的领域,老是不断有新的技术新的产品冒出来,改变咱们已经造成的固有的技术观念,我本身(robbin)稍微了解了一些,就感受本身深深的沉迷进去了,能够说NoSQL数据库领域也是博大精深的,我(robbin)也只能浅尝辄止,我(robbin)写这篇文章既是本身一点点钻研心得,也是抛砖引玉,但愿吸引对这个领域有经验的朋友来讨论和交流。
从我(robbin)我的的兴趣来讲,分布式数据库系统不是我能实际用到的技术,所以不打算花时间深刻,而其余两个数据领域(高性能NoSQLDB和海量存储NoSQLDB)都是我很感兴趣的,特别是Redis,TT/TC和MongoDB这3个NoSQL数据库,所以我接下来将写三篇文章分别详细介绍这3个数据库node