第1章 NoSQL数据库
1.1 NoSQL概述
- 自关系型数据库诞生40年以来,从理论产生发展到现实产品,例如:大家最常见的MySQL和Oracle,逐渐在数据库领域里上升到了霸主地位,形成每年高达数百亿美元的庞大产业市场。
- 但随着互联网web2.0网站的兴起,传统的关系型数据库在应付web2.0网站,特别是对于规模日益扩大的海量数据,超大规模和高并发的微博,微信,SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,例如:传统的关系型数据库IO瓶颈,性能瓶颈都难以有效突破,于是开始出现了大批针对特定场景,以高性能和使用便利为目的功能特异化的数据库产品,NoSQL(非关系型)类的数据库就是在这样的情境中诞生并得到了非常迅速的发展。
- 请同学们注意,NoSQL的本意是“Not Only SQL”指的是非关系型数据库,而不是“No SQL”的意思(没有SQL语句?)。因此,NoSQL的产生并不是要彻底地否定关系型数据库,而是作为传统关系型数据库的一个有效补充。NoSQL数据库在特定的场景下可以发挥出难以想象的高效率和高性能。
例如:(重点记忆)
- [x] 专注于key-value查询的:redis,memcached,ttserver;
- [x] 面向文档的数据库:Mongodb;
- [x] 面向列的数据库hbase和cassandra
- [x] 面向图的数据库Neo4J等等。
这些NoSQL数据库的共同特点是:
1,去除一切和高性能无关的功能。
2,追求高并发,高性能。
3,在扩展上支持集群甚至分布式。
NoSQL现在正在被越来越多的公司使用者所接受并投入实际生产环境,包括超大型著名公司:
例如:
- Facebook和360使用cassandra来存储海量社交数据
- Twitter在其url抓取系统里综合运用了Cassandra,Memcached
- Google使用BigTable
- Amazon使用Dynamo
- 新浪微博使用Redis,memcached来提高高并发高性能。
- 淘宝使用hbase,并改进研制出自己品牌的NoSQL产品Oceanbase。
- 豆瓣也自己研发了NoSQL数据库BeansDB
- 对于常规内容的存储,中小企业也会去用mongodb
Mongodb被广泛用于存储非结构化数据
- 在电信运营商的数据分析项目中,使用hbase承载从交换机上采集下来的高速数据流。
熟悉NoSQL的原理,熟知每种产品的特性和适用场景进行技术选型,熟练地实施和管理集群,这些都是新一代系统管理者,DBA和架构师们需要掌握的知识。NoSQL课程是一门IT课程,特别适合已经有一定关系型数据库(Oracle,MySQL等等)工作经验或知识基础,从事数据库管理,系统运维,数据分析,架构设计师等工作,想对NoSQL进行一定的了解,以方便日后进行技术选型和补充知识的朋友,为自己增加附加值,增强竞争力,适应新时代的变化。
1.2 NoSQL数据库可以解决哪些问题?
- 我们为什么要使用NoSQL这样非关系型数据库呢?在前面的描述中我们已经给了一个简单的答案了。
- 随着互联网web2.0网站的兴起,传统的关系型数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,例如:传统的关系型IO瓶颈,性能瓶颈都难以有效突破,于是开始出现了大批针对特定场景,以高性能和使用便利为目的的功能特异化的数据库产品,NoSQL(非关系型)类的数据库就是在这样的情景中诞生并得到了非常迅速的发展。NoSQL数据库可以比较好的解决如下几个传统关系型数据库难以解决的问题:
(1)High performance-对数据库高并发读写的需求
web2.0 网站要根据用户个性化信息来实时生成动态页面和提供动态信息,所以难以使用动态页面静态化技术,因此对数据库的并发和负载要求非常高,往往要达到每秒上万次读写请求。关系型数据库(包括分布式集群)应付上万次SQL查询还勉强顶得住,但是应付上万次SQL写数据请求,物理硬盘IO就已经无法承受了。对于普通的大型BBS网站,往往也可能存在对高并发写请求的需求。
(2)Huge Storage-海量数据的高效率存储和访问需求
对于大型的SNS网站,每天用户产生海量的用户动态数据,以国外的Friendfeed为例,一个月就达到了2.5亿条用户动态,对于关系数据库来说,在一张2.5亿条记录的表里面进行SQL查询,效率是极其低下甚至可能是不可忍受的。再例如大型web网站的用户登陆系统,例如腾讯,盛大,动辄数以亿计的账号,对于这样的关系型数据库表也很难应付。
(3)High Scalability && High Availability-高可扩展性和高可用性需求
在互联网网站的架构当中,数据库是最难横向进行扩展的,当一个应用系统的用户量和访问量与日俱增的时候,你的数据库很难像web server和app server那样简单的通过添加更多的硬件和服务节点来扩展性能和负载能力。对于很多需要提供24小时不间断服务的网站来说,对数据库系统进行升级和扩展是非常痛苦的事情,往往需要停机维护和数据迁移(例如:淘宝,支付宝就经常停机维护)。
为什么数据库不能通过不断的添加服务器节点来实现扩展呢?
在上面提到的“三高”需求面前,关系型数据库遇到了难以克服的障碍,而对于web2.0网站来说,关系数据库的很多主要特性却往往无用武之地,例如:
(1)数据库事务一致性需求
很多web实时系统并不严格要求的数据库事务,对读一致性的要求很低,有些场合对写一致性要求也不高。因此数据库事务管理成了数据库高负载下一个沉重的负担。传统关系型数据库由于要保持数据库事务一致性需求,从而无法满足高并发读写的需求。
(2)数据库的写实时性和读实时性需求
对关系数据库来说,插入一条数据之后立刻查询,是肯定可以读出来这条数据的,但是对于很多web应用来说,并不要求这么高的实时性。
(3)对复杂的SQL查询,特别是多表关联查询的需求
- 任何大数据量的web系统,都非常忌讳多个大表的关联查询,以及复杂的数据分析类型的复杂SQL报表查询,特别是SNS类型的网站,从需求以及产品设计角度,就避免了这种情况的产生。往往更多的只是单表的主键查询,以及单表的简单条件分页查询,SQL的功能被极大弱化了。
- 因此,关系型数据库在这些越来越多的应用场景下显得不那么合适了,为了解决这类问题,非关系型数据库应运而生。
- NoSQL是非关系型数据库的广义定义。它打破了长久以来关系型数据库与ACID理论大一统的局面。NoSQL数据存储不需要固定的表结构,通常也不存在连接操作。在大数据存取上具备关系型数据库无法比拟的性能优势。该术语在2009年初得到了广泛认同。
- 当今的应用体系结构需要数据存储在横向伸缩性上能够满足需求。而NoSQL存储就是为了实现这个需求。Google的BigTable与Amazon的Dynamo是非常成功的商业NoSQL实现。一些开源的NoSQL体系,如Facebook的Cassandra,Apache的HBase,也得到了广泛认同。从这些NoSQL项目的名字上看不出什么相同之处:Hadoop,Voldemort,Dynomite,还有其他很多。
1.3 NoSQL 数据库适用场景小结
我们总结NoSQL数据库在以下的这几种情况下比较适用:
- 数据模型比较简单;
- 需要灵活性更强的IT系统;
- 对数据库性能要求较高;
- 不需要高度的数据一致性;
- 对于给定key,比较容易映射复杂值的环境。
第2章 NoSQL 主流软件分类与特点
2.1 键值(Key-Value)存储数据库
- 键值数据库就像在传统语言中使用的哈希表。可以通过key来添加,查询或者删除数据,因为使用主键访问,所以会获得不错的性能及扩展性。
- 键值(Key-Value)数据库主要是使用一个哈希表,这个表中有一个特定的键和一个指针指向特定的数据。Key/Value模型对于IT系统来说的优势在于简单,易部署。
相关产品及其场景如下:
数据库产品 | Redis,MemcacheDB,Berkeley DB,memcached等 |
---|---|
典型应用 | 内容缓存,适合混合工作负载并扩展大的数据集 |
数据模型 | 一系列键值对 |
优势 | 快速查询 |
劣势 | 存储的数据缺少结构化 |
适用的场景 | 存储用户信息,比如会话,配置文件,参数,购物车等等。这些信息一般都和ID(键)挂钩,这种情景下键值数据库是个很好的选择 |
不适用场景 | 1.不通过键查询,而是通过值来查询;Key-Value数据库没有通过值查询的途径;2.需要储存数据之间的关系。在Key-Value数据库中不能通过两个或以上的键来关联数据;3.事务支持。在Key-Value数据库中故障产生时不可以进行回滚 |
企业应用 | Github(Riak),BestBuy(Riak),Twitter(Redis和Memcached),StackOverFlow(Redis),Instagram(Redis),Youtube(Memcached),sina(redis),baidu(Memcached) |
参考:http://blog.nahurst.com/visual-guide-to-nosql-systems
2.2 列存储(Column-oriented)数据库
- 列存储数据库将数据存储在列族(column family)中,一个列蔟存储经常被一起查询的相关数据。举个例子,如果我们有一个Person类,我们通常会一起查询他们的姓名和年龄而不是薪资。这种情况下,姓名和年龄就会被放入一个列蔟中,而薪资则在另一个列蔟中。
- 这部分数据库通常是用来应对分布式存储的海量数据。键仍然存在,但是它们的特点是指向了多个列。这些列是由列家族来安排的。
数据库产品 | Cassandra,HBase,Riak |
---|---|
典型应用 | 分布式的文件系统(大型门户网站) |
数据模型 | 以列簇式存储,将同一列数据存在一起 |
优势 | 查找速度快,可扩展性强,更容易进行分布式扩展 |
劣势 | 功能相对局限 |
适用场景 | 日志:因为我们可以将数据存储在不同的列中,每个应用程序可以将信息写入自己的列族中。博客平台:我们储存每个信息到不同的列族中。举个例子,标签可以储存在一个,类别可以在一个,而文章则在另一个。 |
不适用场景 | 1,事务 2,原型设计 |
企业应用 | Ebay(Cassandra),Instagram(Cassandra),NASA(Cassandra),Twitter(Cassandra and HBase),Facebook(HBase),Yahoo!(HBase),taobao(HBase),360(Cassandra) |
2.3 面向文档(Document-Oriented)数据库
- 文档型数据库的灵感是来自于Lotus Notes办公软件的,而且它同第一种键值存储相类似。该类型的数据模版是版本化的文档,半结构化的文档以特定的格式存储,比如JSON。文档型数据库可以看作是键值数据库的升级版,允许之间嵌套键值。而且文档型数据库比键值数据库的查询效率更高。
- 面向文档数据库会将数据以文档的形式储存。每个文档都是自包含的数据单元,是一系列数据项的集合。每个数据项都有一个名称与对应的值,值既可以是简单的数据类型,如字符串,数字和日期等;也可以是复杂的类型,如有序列表和关联对象。数据存储的最小单位是文档,同一个表中存储的文档属性可以是不同的,数据可以使用XML,JSON或者JSONB等多种形式存储。
相关产品及其场景如下:
数据库产品 | CouchDB,MongoDB,RavenDB |
---|---|
典型应用 | Web应用 |
数据模型 | 数据结构要求不严格 |
劣势 | 查询性能不高,而且缺乏统一的查询语法 |
适用场景 | 日志:企业环境下,每个应用程序都有不同的日志信息 |
不适用场景 | 事务 |
企业应用案例 | SAP(mongoDB),Codecademy(MongoDB),Foursquare(MongoDB),NBC News(RavenDB) |
2.4 图形(Graph)数据库
- 图形数据库允许我们将数据以图的方式存储。实体会被作为顶点,而实体之间的关系则会被作为边。比如我们有三个实体,Steve jobs,Apple和Next,则会有两个“Founded by”的边将Apple和Next连接到Steve jobs。
- 图形结构的数据库同其他行列以及刚性结构的SQL数据库不同,它是使用灵活的图形模型,并且能够扩展到多个服务器上。NoSQL数据库没有标准的查询语句(SQL),因此进行数据库查询需要制定数据模型。许多NoSQL数据库都有REST式的数据接口或者查询API。
相关产品及其场景如下:
数据库产品 | Neo4J,InfoGrid,Infinite,Graph,OrientDB |
---|---|
典型应用 | 社交网络,推荐系统等。专注于构建关系图谱 |
数据模型 | 图结构 |
强项 | 利用图结构相关算法 |
弱项 | 需要对整个图做计算才能得出结果,不容易做分布式的集群方案 |
适用的场景 | 在一些关系性强的数据中,推荐引擎。如果我们将数据以图的形式表现,那么将会非常有益于推荐的制定 |
不适用场景 | 不适合的数据模型。图数据库的适用范围很小,因为很少有操作涉及到整个图 |
企业应用 | Adobe(Neo4J),Cisco(Neo4J),T-Mobile(Neo4J) |
第3章 常用NoSQL数据库详细介绍
3.1 Memcached(key-value)
- Memcached是一个开源的,高性能的,具有分布式内存对象的缓存系统。通过它可以减轻数据库负载加速动态Web应用,最初版本由LiveJournal的Brad Fitzpatrick在2003年开发完成。目前全世界很多用户都在使用它来构建自己的大负载网站或提高自己的高访问网站的响应速度。Memcache是这个项目的名称,而Memcached是服务器端的主程序文件名。
- 缓存一般用来保存一些经常被存取的对象或数据(例如,浏览器会把经常访问的网页缓存起来),通过缓存来存取对象或数据要比磁盘存取快很多。Memcache是一种内存缓存,把经常存取的对象或数据缓存在内存中,内存中缓存的这些数据通过API的方式被存取,数据就像一张大的HASH表,以key-value对的方式存在。Memcache通过缓存经常被存取的对象或数据,减轻数据库的压力,提高网站的响应速度,构建出速度更快的可扩展的Web应用。
Memcached的特点:
- 部署极其简单。
- 支持高并发,高性能(比redis快)
- 通过程序或者负载均衡可以实现分布式。
- 仅为内存缓存,重启服务数据丢失(缺点)
3.2 MemcacheDB(key-value)
- Memcached是新浪网基于Memcached开发的一个开源项目。通过为Memcached增加BerkeleyDB的持久化存储机制和异步主辅复制机制,使Memcached具备了事务恢复能力,持久化能力和分布式复制能力,非常适合需要超高性能读写速度,持久化保存的应用场景。例如:memcachedb被应用在新浪博客上。如果对Memcached有持久化需求,可以考虑使用memcachedb。
- memcached用于数据库内存缓存,问题:进程退出,数据全丢,这样就算缓存启动了,内存里没有数据,因此用户会瞬时访问数据库,造成数据库撑不住。
- 通过脚本或者程序,从数据库里把数据读出来存到memcached缓存里,然后前端才能开启对外访问。
- Memcacheddb持久化的缓存系统,不但可以像memcached一样提供内存缓存,还可以把内存的数据存放到磁盘。数据量的多少和NOSQL软件的机制决定了,重新把数据加载到内存需要多久。
Memcachedb的特点:
- 高性能读写基于key-value的对象
- 基于事务的高效存储
- 基于同步的高可用存储
- Memcache兼容协议(兼容memcache代码)
参数:http://memcachedb.org/benchmark.html
3.3 Redis(key-value)
- redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型想对更多,包括string(字符串),list(链表),set(集合)和zset(有序集合)。这些数据类型都支持push/pop,add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率。数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
- Redis是一个高性能的key-value数据库。redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用。它提供了Python,Ruby,Erlang,PHP客户端,使用很方便。
官方:http://www.redis.io/documentation
redis特点:
- 支持内存缓存,相当于memcached;
- 持久化,相当于memcachedb,ttserver;
- 数据类型更丰富;
- 支持集群,分布式。
代码从读取memcached更改读取redis。
3.4 Tokyo Tyrant 介绍(key-value)ttserver
Tokyo Cabinet介绍
- Tokyo Cabinet是日本人Mikio Hirabayashi(平林干雄)开发的一款DBM数据库(注:大名鼎鼎的DBM数据库qdbm就是他开发的),该数据库读写非常快。写入100万数据只需要0.4秒。读取100万数据只需要0.33秒。是BerkeleyDB等DBM的很多倍。
- Tokyo Tyrant是提供dbm数据库Tokyo Cabinet的网络接口。它使用简单的基于TCP/IP的简单二进制协议进行通信。同时它拥有Memcached兼容协议并且可以用HTTP/1.1协议进行数据交换。所以实现了跨平台,跨语言使用Tokyo Tyrant。同时Tokyo Tyrant采用热备份,更新日志记录,复制(replication)来实现高可用性和高可靠性。到目前为止,Tokyo Tyrant可以运行在Linux,FreeBSD,Mac OS X,Solaris。
- Tokyo Tyrant加上Tokyo Cabinet,构成了一款支持高并发的分布式持久化存储系统,对任何原有Memcached客户端来讲,可以将Tokyo Tyrant Server看成是一个Memcached,但是,它的数据是可以持久存储的。这一点和Memcachedb性质一样。
- Tokyo Tyrant兼容Memcached协议,支持主从同步,故障转移,高并发的分布式key-value持久化存储系统。
Tokyo Tyrant优势
相比Memcached及Memcachedb而言,Tokyo Tyrant具有以下优势:
- Tokyo Tyrant 不但支持内存缓存,而且还可以持久化存储。
- 故障转移:Tokyo Tyrant 支持主从模式,也支持双机互为主辅模式,主辅库均可读写,而Memcachedb目前支持类似MySQL主辅库同步的方式实现读写分离,支持“主服务器可读写,辅助服务器只读”模式。
- 5千万条数据级别内的访问相当快。
- 兼容Memcached协议,客户端不需要更改任何代码。
官方:http://fallabs.com/tokyotyrant/
3.5 MongoDB(Document-oriented)
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型。Mongodb最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。它的特点是高性能,易部署,易使用,存储数据非常方便。
主要功能特性:
-
[x] 面向集合存储,易存储对象类型的数据
- “面向集合”(Collenction-Orented),意思是数据被分组存储在数据集中,被称为一个集合(Collenction)。每个集合在数据库中都有一个唯一的标识名,并且可以包含无限数目的文档。集合的概念类似关系型数据库(RDBMS)里的表(table),不同的是它不需要定义任何模式(schema)
-
[x] 模式自由
- 模式自由(schema-free),意味着对于存储在mongodb数据库中的文件,我们不需要知道它的任何结构定义。如果需要,你完全可以把不同结构的文件存储在同一个数据库里。
-
[x] 支持动态查询
-
[x] 支持完全索引,包含内部对象
-
[x] 支持查询
-
[x] 支持复制和故障恢复
-
[x] 使用高效的二进制数据存储,包括大型对象(如视频等)
-
[x] 自动处理碎片,以支持云计算层次的扩展性
-
[x] 支持RUBY,PYTHON,JAVA,C++,PHP等多种语言
-
[x] 文件存储格式为BSON(一种JSON的扩展)
- BSON(Binary Serialized document Format)存储形式是指:存储在集合中的文档,被存储为键-值对的形式。键用于唯一标识一个文档,为字符串类型,而值则可以是各种复杂的文件类型。
-
[x] 可通过网络访问
- MongoDB服务器可运行在Linux,Windows或OS X平台,支持32位和64位应用,默认端口为27017.推荐运行在64位平台。
- MongoDB把数据存储在文件中(默认路径:/data/db),为提高效率使用内存映射文件进行管理。
MongoDB更详细的文档:http://www.mongodb.org/display/DOCS/Manual
3.6 Cassandra(Column-oriented)
Apache Cassandra是一套开源分布式Key-Value存储系统。它最初由Facebook开发,用于储存特别大的数据。Facebook目前在使用此系统。
主要特性:
- 分布式
- 基于column的结构化
- 高伸展性
- Cassandra的主要特点就是它不是一个数据库,而是由一堆数据库节点共同构成的一个分布式网络服务,对Cassandra的一个写操作,会被复制到其他节点上去,对Cassandra的读操作,也会被路由到某个节点上面去读取。对于一个Cassandra群集来说,扩展性能是比较简单的事情,只管在群集里添加节点就可以了。
- Cassandra是一个混合型的非关系的数据库,类似于Google的BigTable。其主要功能比Dynomite(分布式的Key-Value存储系统)更丰富,Cassandra最初由Facebook开发,后转变成了开源项目。它是一个网络社交云计算方面理想的数据库。以Amazon专有的完全分布式的Dynamo为基础,结合了Google GigTable基于列族(Column Family)的数据模型。P2P去中心化的存储。很多方面都可以称之为Dynamo2.0
第4章 生产场景如何选择NoSQL数据库?
- 最常规cache应用:memcached最合适。优点:简单,易用,高效,特别是开发都会用。缺点是只存在内存中,大数据量需要预先预热再提供服务,无法直接实现主从同步。
- memcached的持久化存储替代最佳方案是memcachedb和Tokyo Tyrant,兼容memcached协议,可以完全和memcached兼容使用,且可以实现主从主主同步。
- 2000万以内数量级别的小数据用于替代memcached,Tokyo Tyrant最合适,海量数据效率不高,参考值是2000万条数据下效率最高。(大于10G,性能下降)
- 希望找一个可以大数据量替代memcached的产品,可以用redis持久化存储。缺点:客户端代码需要大量改写,开发人员对redis不熟悉。
- 海量数据(PB千兆兆)并拥有很多机器,而且延时不是个问题,你也不强求极好的响应时间,那么Cassandra和HBase都可以胜任,Mongodb也可以。