400 likes | 793 Views
NoSQL 技术交流. ICT- 存储部 - 马健. 目录. 什么是 NoSQL CAP 理论 NoSQL 解决的问题 NoSQL 的不足 较成熟的 NoSQL 数据库对比 TC/TT MongoDB. 什么是 NoSQL. NoSQL 是一种与关系型数据库管理系统截然不同的数据库管理系统,它的数据存储格式可以是松散的、通常不支持 Join 操作并且易于横向扩展。也可以称之为非关系型数据库。. 关系型数据库. nosql. CAP 理论. Availability 可用性. 某个节点的宕机不会影 响其他节点继续完成操 作. Consistency
E N D
NoSQL技术交流 ICT-存储部-马健
目录 • 什么是NoSQL • CAP理论 • NoSQL解决的问题 • NoSQL的不足 • 较成熟的NoSQL数据库对比 • TC/TT • MongoDB
什么是NoSQL • NoSQL是一种与关系型数据库管理系统截然不同的数据库管理系统,它的数据存储格式可以是松散的、通常不支持Join操作并且易于横向扩展。也可以称之为非关系型数据库。 关系型数据库 nosql
CAP理论 • Availability • 可用性 某个节点的宕机不会影 响其他节点继续完成操 作 • Consistency • 一致性 • Partition Tolerance • 分区容错性 RDBMS NoSQL 数据一致更新,所有 数据变动都是同步的 尽管有一些信息丢失 ,系统依旧继续运转
NoSQL解决的问题 • 对数据库的高并发读写 • Key-Value型数据库:TC/TT、Redis等 • 对海量数据的高效率存储和访问 • 文档型数据库:MongoDB、CouchDB • 数据库的可扩展性 • 分布式数据库:Cassandra、MongoDB
NoSQL的不足 没有完美的技术,NoSQL也存在着它的不足: • NoSQL的技术架构通常只提供较弱的一致性保障,如最终一致性或者单一数据对象的事务约束。 • 绝大多数NoSQL只能提供简单的查询,无法进行多表联合查询等复杂的查询操作。 • 大部分NoSQL的替代品都还处于前-生产环境阶段,还有大量的关键特性有待实现. • 功能相对贫乏,NoSQL数据库大部分功能集仅仅旨在满足现代的Web 2.0应用的需求。在一些要求事务一致性较高、业务逻辑比较复杂或者一些需要复杂分析查询的环境中,NoSQL难以担当重任。
TC/TT • TC:Tokyo Cabinet。它其实是一套数据库管理的功能类库。它只将字符串和二进制数据以Key-value的形式存储。既没有表的概念,也没有数据类型的概念,数据库的记录都被组织在哈希表、B+Tree或者定长数组中。TC为不同的应用场景设计了不同的数据库类型。虽然具有很高的性能,但TC本身并不支持远程访问。 • TT:Tokyo Tyrant。TC的网络接口,为其提供了高并发读写、远程访问以及复制等更丰富的管理功能。支持Memcached兼容协议,也可以通过HTTP协议进行数据交换。 • TC/TT由C语言编写,为C、Perl、Ruby、Java均提供了程序接口。
TC的一些概念 • 物理层面上,TC的数据库其实就是包含了以简单的key-value对为记录的数据文件。 • 逻辑层面上,TC的数据库相当于RDBMS中的表。 • 每个数据库都拥有它自己的缓存 • TC提供了一系列的shell工具来对每个数据库(数据文件)进行创建、读、写、优化等操作。当然你也可以通过程序API调用相应的方法来实现。
TC的几种数据引擎 根据不同的使用场景,TC提供了几种不同的数据存储方式: • TCHDB 哈希数据库 • tchmgr:http://www.nixway.net/index.php?manitem&mid=2444 • TCBDB B+Tree数据库 • tcbmgr:http://www.nixway.net/index.php?manitem&mid=2438 • TCFDB 定长数据库 • tcfmgr:http://www.nixway.net/index.php?manitem&mid=2441 • TCTDB 表格数据库 • tctmgr:http://www.nixway.net/index.php?manitem&mid=2449 • TCMDB 内存哈希数据库 • TCNDB 内存B+Tree数据库
TC的几种数据引擎 - TCHDB • 在哈希表数据库中,每个key必须是唯一的。它提供了遍历访问的功能,但其中的数据是无序的。性能仅次于FDB。 • TC通过读取内存中的bucket array来提升访问速度,这里的bucket array实际上就是TC为某个数据库设置的缓存,它存放了映射到内存中的全部/部分数据文件的数据。 • 哈希值冲突由separate chaining策略来管理。 • TC在存入数据时,除了传统的insert和replace,还提供了concatenate模式。
TC的几种数据引擎 - TCBDB • 与TCHDB不同,B+ Tree数据库的key可以是重复的。它的数据是排序并排列在逻辑页中的,所以除了拥有TCHDB的基本功能以外,它还可以根据用户的需求对数据进行排序。 • 由于每个逻辑页都被安排成双向链表,所以可以通过游标按某种顺序访问每一条记录,也可以跳到某一个指定的key的位置。基于这个特性,实现了字符串的正向匹配和数字的范围查询。 • BDB中的数据页是可以被压缩的,支持ZLIB和BZIP2两种方法。
TC的几种数据引擎 - TCFDB • 在定长数组数据库中,每条记录都被给予唯一的自然数作为它的key,而这些记录(Value)的长度是被限制死的。整个数据库可被看做是一个数组。FDB提供了和HDB同样的功能。 • 因为FDB所有的数据都会作为一个多维数组通过mmap映射到内存中,最小化文件I/O,所以只要在满足限制的情况下,FDB的性能在这几种数据库中是最好的。 • 数据库的大小和所定义的key范围和value大小成正比。Key范围越小、value size越小,空间效能就越高。
TC的几种数据引擎 - TCTDB • TCTDB是TCHDB的一个变种,每条记录都由主键来识别,并且拥有一组被命名的字段。虽然数据结构可以是松散的,但是依然可以通过索引来加速一些相对复杂的查询。它既具备了Key-Value数据库的高效读写性能,又具备了MySQL单表能实现的一些功能,即:SELECT …. FROM table WHERE …. ORDER BY …. LIMIT xxx,xxx • 支持字符串的完全匹配、正向匹配、正则表达式匹配等。支持数值型的完全匹配和范围匹配。 • 支持标签搜索和全文搜索 • 支持多条件查询、UNION、正反向排序。
TC的使用示例 http://fallabs.com/tokyocabinet/
MongoDB • MongoDB官方给自己的定义是Key-value存储(高性能和高扩展)和传统RDBMS(丰富的查询和功能)之间的一座桥梁。 • 功能:MongoDB所提供的查询和各种功能在NoSQL产品中的确是佼佼者,如GridFS提供了文件存储功能、Map/Reduce的数据聚合操作为分布式系统的高性能读写提供了技术基础、分布式的动态sharding集群提供了高可扩展性、Replica-set的投票和复制机制又提供了高可用性…… • 性能:丰富的功能无疑带来的就是性能的下降,它无法像TC/TT一样达到如此高的性能指标,但它的性能依然可以达到MySQL的17倍。
MongoDB - document • MongoDB的最小存储单位就是文档对象,数据在Mongo中以BSON(Binary-JSON)文档的格式存储在磁盘上。每一个文档对象,MongoDB都会为它分配一个唯一的id号,名为“_id”。如果硬要和关系型数据库扯上关系,你可以把文档视作关系型数据库中的行。 • 下图描述了一个最简单的Mongo document: { _id : ObjectId( “xxxxxxxx" ) , name : "majian", gender : "M", address : "Beijing" } 如果不显式创建_id,mongo会自动创建并为它分配一个唯一的值,作为该文档对象的唯一标识。
MongoDB - document • 跟一般的key-value数据库不一样的是,它的value中存储了结构信息,所以它提供了嵌入式的文档结构。 { _id : ObjectId( “xxxxxxx" ) , name : "majian", gender : "M", address : "Beijing", score : } [ Chinese : "60", English : "50" ]
MongoDB - collection • Collection就是documents的集合,可以理解为关系型数据库中的表,也可以看成一个文件夹,用来专门储存同一类文档。 COLLECTION ____________ _document_ _document_ _document_ _document_
MongoDB - Database • Document • Collection • Database • MongoDB的最外层结构,和关系型数据库一样,是存放多个Collections的容器。 • 可以把MongoDB看成一个文件仓库,每个document就如同一页纸;成千上万张纸被存放在文件夹里,这些文件夹就可以看做是Collection;多个文件夹存放在一个储藏柜里,也就是Database。
MongoDB – GridFS • 物理文件 • 文件切分 • 元数据 • 二进制数据 id : ObjectId("xxxxx"), filename : "file", chunkSize : 262144, uploadDate : "xxx", md5 : "xxx", length : 668734007 _id : ObjectId("yyyyy"), files_id : ObjectId("xxxxx"), n : chunk_number, data : data_binary,
MongoDB – GridFS性能 针对物理文件的存储,我们对MySQL和MongoDB做了一次性能对比,下面的图标反映了二者对于存储3MB物理文件的性能差异。
MongoDB –数据查询 http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7Bcount%28%29%7D%7D • db.users.find({'last_name': 'Smith'}) • Select * from users where last_name=‘Smith’; • db.users.find({last_name: 'Smith'}, {'ssn': 1}); • Select ssn from users where last_name=‘Smith’; • db.users.find().skip(20).limit(10); • Select * from users limit 20,10; • db.things.find({j:{$nin: [2,4,6]}}); • Select * from things where j is not in (2,4,6); • db.address.distinct( "zip-code" , { age : 30 } ) • Select distinct zip-code from address where age=30; • <, <=, >, >=, $all, $exists, $mod, $ne, $in, $nin, $nor, $or, $size, $type等操作符。 • 游标方法:count(), limit(), skip(), snapshot(), sort()
MongoDB –References • MongoDB是非关系型数据库,不支持join操作(无法select a.*,b.* from a,b where a.id=b.id;也无法select cols from a, b where a.id=b.id;)。但是可以通过References的方式去实现两个document之间的关联查询。 > p = db.postings.findOne({title:'Brewing Methods'}); { "_id" : ObjectId("4b866f08234ae01d21d89604"), "author" : "jim", "title" : "Brewing Methods" } > db.users.find( { _id : p.author } ) { "_id" : "jim", "email" : "jim@gmail.com" }
MongoDB –跨库跨实例查询 • 利用MongoDB提供的函数connect()可以为我们的查询提供更丰富的功能:通过它,你可以进行跨实例的查询: • 假设我们在两个服务器sv1和sv2上各跑一个mongod,sv1上建db1数据库,sv2上建db2数据库,分别创建数据如下: • 现在要知道pencil这个物品的拥有者的详细信息,假设我们正在连接sv1,具体实现方法如下: > conn = connect("sv2:27017/db2") connecting to: sv2:27017/db2 db2 > res = conn.stuff.findOne({item:'pencil'}) { "_id" : ObjectId("4c93720a859fbb4e384da194"), "item" : "pencil", "owner" : "xiaoming" } > db.person.findOne({name:res.owner}) { "_id" : ObjectId("4c93775d1d031ab611413187"), "name" : "xiaoming", "job" : "student", "age" : "18", "address" : "Beijing" }
MongoDB –Map/Reduce http://www.mongodb.org/display/DOCS/MapReduce • MapReduce是一种编程模式,也是一种处理和生成大型数据集的联合运算方式。MongoDB使用这个技术去实现对单个实例和sharding集群中的数据聚合操作,数据库会自动生成临时的collection来保存这些结果集, 当关闭连接时,这些临时的collection会自动被删除。在sharding集群中,map/reduce方法会让查询平行地在每个shard上面执行,最终返回混合后的结果。
MongoDB – 缓存 MongoDB采用的是内存映像存储引擎,它通过内存映像文件进行全部的磁盘I/O操作。这样使MongoDB具有如下特性: • 不存在操作系统缓存和数据库缓存之间的冗余,它们是一样的。 • 不需要人为修改设置,MongoDB会自动使用系统剩余的所有内存作为cache。 • 缓存动作,如LRU等页操作等,都由操作系统来控制。
MongoDB – shard集群 • MongoDB的shard集群支持数据的自动切分和平衡分布。 • 数据的分布会根据节点的数据变动而自动迁移,这让数据库的扩展变得很容易;而且,数据分布在多个shard节点也打散了读写压力,提供了高并发高负载的解决方案。 • 每个shard节点都可以由一个replica-set高可用架构组成,也就是说实现了自动的故障恢复功能,避免了单点故障。 • Shard集群由以下几个关键点组成:Shard keys、Chunks、Shard nodes、Congfigure servers、Routine servers
MongoDB集群 – 架构图 Shard 1 Shard 2 Shard 3 mongod mongod mongod mongod mongod Replica-set Configure servers c1 mongod c2 mongod c3 mongod mongos mongos … client …
MongoDB集群 – shard keys • 当要将一个Collection进行分割的时候,需要指定一个shard key。shard key和索引key有些相像,它定义了在分布存储数据时,这一个或几个字段值的上限。这样,相邻的数据都会存储在满足key值范围的节点上。mongodb的shard key是需要你提前预设的,在congfig数据库中,你可以找到所有shard key的元数据。
MongoDB集群 – chunks • chunks指的是在某一个collection中的一系列相邻的数据。可以从三方面去描述它:collection、minkey、maxkey。假设一个document的shard key是K,那么只有当minkey <= K < maxkey的时候,这个document才会被分配到这个chunk中来。 • 假如,一个chunk的最大size是200M,当超过这个值时,它会分裂出两个100M的chunk来,当一个shard节点存储了过多的数据时,那么一些chunks将被迁移到其他的shard节点上。(新加入节点也会引起chunk的迁移)
MongoDB集群 – shard nodes • 每一个shard 都是由一个或者多个存储着数据的mongod server组成的。对于生产环境而言,它可以由replica-set来组成,以提供高可用性,保证无单点故障。mongodb shard集群需要至少两个的shard节点。 • replica-set基于异步的replication技术,由几台(2-7)replication的节点组成。在集群初始化时,集群的几个节点会进行投票,决定谁做master,其余的作为slave去复制写入master的数据。一个replica-set中只有master是可写的,保证了数据的一致性。当一个master宕掉的时候,内部的投票机制会重新选举出一个新的master出来提供服务。当原来宕掉的节点恢复的时候,只要启动mongd进程(带有replica-set相应参数)就可以自动地加入集群,并且作为一个slave去提供备障和分摊读压力(可选项)。 vote vote vote
MongoDB集群 – config server • Config server的config库中存储了集群的元数据,包括每个shard server和 chunks的基本信息。当然,主要的还是chunks的信息。每个config server完全地拷贝了所有chunks的信息。 • 当任何一个Config server宕掉的时候,那么这些元数据都将变为只读,但是这并不影响数据节点的读写操作。mongodb shard集群需要至少一个config server。
MongoDB集群 – routine server • 你可以把mongos程序看做是一个路由,它可以使各种不同的组件一起协同工作,看起来就像是一个单独的系统,这有点像mysql的proxy。当客户端发送一条查询,mongos会依据config server的信息,把这条查询分配到相应的shard节点上,再将查询结果整合起来,一起返回客户端。你可以开启任意数量的mongos对外提供服务。
Hash table Hash Function http://en.wikipedia.org/wiki/Hash_table
Separate chaining • 在separate chaining策略中,每一个bucket array的插槽都是一个指向链表的指针。每个链表包含了所有hash到同一个值的key的key-value对。 • 查找操作需要去扫描这个列表中和给出的key相对应的条目。 • 插入操作需要在这个列表的结尾处增加新的条目。 • 删除则需要找到并且从列表中移除这个条目。
B+Tree 主干 分枝 叶节点 存储数据 内部节点 存储key
Doubly-linked list 双向链表是一种数据记录集被连接起来的数据结构。每条记录都包含了两个连接字段,里面包含了对序列中前一条和后面一条的记录的引用。它可以被视为同一数据对象的两个方向相反的单向链表。 双向链表 单向链表 连接字段中存储的引用通常是指针;但也可能是目标所在地址的偏移值或数组中的索引。