码迷,mamicode.com
首页 > 数据库 > 详细

MongoDB介绍

时间:2015-10-20 10:27:36      阅读:349      评论:0      收藏:0      [点我收藏+]

标签:

1 关系数据库的传统优势

1.1 基于二维结构数据

1.1.1 schema based、表、关系模式

1.1.2 拥有成熟严谨的关系代数理论基础

  • 查询表达能力强
  • 查询优化有理论基础(cost-based rule-based)
  • 读写性能稳定

1.1.3 实体约束、外键约束

关系范式理论:降低冗余、避免插入删除异常

保证数据一致性的关键之一

1.2 对事务的支持

1.2.1 多种事务隔离级别

  • read uncommitted:不可同时写,但写的时候其他事务可读脏,排他写锁
  • read committed:不允许读脏,但允许不可重复读,读时候允许写,只是不读脏、写的时候不需要读
  • repeatable read:读时候不让写,写的时候不让读,不排除幻影读(读不到新纪录)
  • serializable:序列化执行,不允许并发执行事务

表锁 行级锁 读锁 写锁 共享锁 排他锁 各种封锁封锁协议等

锁机制是实现事务隔离的关键

同时不可否认的是 锁通常也是访问性能瓶颈的主要原因,特别是应对并发读写的情况

1.2.2 需要事务的原因:

  • 数据资源是共享的,一致性需求,而访问(读写)可能是并发的,这是一对矛盾,不同级别的事务隔离在不同程度上妥协之
  • 四个级别解决三个问题:读脏 不可重复读  幻影读
  • 事务隔离级别越高,一致性越强,并发能力越差,甚至直接变成队列顺序处理

1.3 BI:数据仓库、知识发现

  • 面向企业应用的决策支持,发展成熟

1.4 数据高可靠性

  • 安全:权限控制成熟,RBAC
  • 容灾:故障恢复,完善的日志和备份机制,能将数据库恢复到任何时间点的状态

1.5 地位

  • 重视数据的高可靠性、访问的稳定性、强一致性, 在金融、电信、电子政务、电子商务、企业信息化等领域目前不可替代

2 关系数据库面临的挑战

2.1 web2.0带来的变化:以用户为中心

= 访问的规模大、并发高、“读多写少”甚至“读多写也多”(SNS,微博)

= 数据海量

= 传统的优势不再那么重要: 数据的读写一致性 读写实时性 复杂的关联查询

2.1.1 数据库的并发读写

= 锁机制和事务控制是限制关系数据库并发读写能力的主要原因

2.1.2 海量数据的高效存储

= 固定模式的存储方式灵活性较差

2.1.3 海量数据访问

= 为了保证数据强一致性的锁机制往往是大数据量下访问不稳定的原因

2.1.4 关键:数据库的扩展性

= 关系数据库本身的复杂性决定(限制)其横向扩展能力,oracle RAC、mysql复制、sharding

3 问题焦点

3.1 CAP理论

3.1.1 consistency一致性

3.1.2 availability可用性,快速稳定地读写数据

3.1.3 tolerance to network partitions分区容忍性,分布的程度(规模)

= 一个分布式系统三个方面是相互制约的,适当的取舍以定制最高性价比的方案,传统的关系数据库注重C&A web2.0新的需求更加需要A&P

=

3.2 到底需要什么样的一致性

  • 强一致性:数据的读写在任何情况下都是一致的
  • 弱一致性:允许一定时间的不一致性状态的存在
  • 最终一致性:弱一致性的特例

3.3 取舍:BASE  OR  ACID

  • Atomicity、Consistency、Isolation、Durability
  • Basically available基本可用、Soft state软状态(允许不一致的状态存在)、Eventual consistency最终一致性

4 NoSQL数据库

4.1 no rational OR not only SQL

4.2 并发读写性能:Redis,Tokyo Cabinet/Tyrant , Flare

4.2.1 key-value数据库

4.2.2 Redis:

  • 内存数据库,支持链表、集合操作,key-value操作类似memcached 受内存限制大数据处理能力不足,不具有scale能力 适合的场景主要局限在较小数据量的高性能操作和运算上

4.2.3 Tokyo Cabinet/Tyrant

  • 日本sns网站开发,支持key-value、Hashtable等数据组织方式,
  • 支持memcached协议

4.2.4 Flare

  • 日本sns网站开发,给Tokyo Cabinet扩展了scale能力

4.3 海量存储和访问:Mongodb,CouchDB

4.3.1 面向文档

  • json格式组织数据

4.3.2 MongoDB

  • 扩展性好、查询功能丰富、内存映射文件、Gridfs、BSON

4.3.3 CouchDB:

  • Apace开源项目,用erlang语言开发,先天的并发特性,支持REST API

4.4 高可扩展性和可用性:Cassandra,Voldemort

4.4.1 面向分布式计算

4.4.2 cassandra:

  • facebook开发,分布式网络服务(集群),扩展非常容易

4.4.3 Voldemort:

  • Linkedin(美国sns网站)开发

5 Mongodb的主要特性

= agile and scalable 敏捷&可扩展

5.1 docment-oriented

5.1.1 document

  • 定义: a single entity which contains zero or more key-value pairs 包含若干键值对的单个实体 an ordered set of keys with associated values  键值对应的有序集合  强调有序
  • 和XML类似,是一种数据展现(representation)和交换的方式
  • json(javascrip object notation):一种轻量级的、独立于语言的、文本格式的document
  • eg:{"greeting" : "Hello, world!"}

5.2 BSON-based

5.2.1 BSON ( Binary  JSON ):

  • 一种存储规范; 几乎继承了json的所有特性; 并扩展了数据类型(如 byte array); 最后解决了json数据的二进制存储
  • 文法

 

eg

 

5.2.2 BSON characteristics 特性

= Compared to JSON, BSON is designed to be efficient both in storage space and scan-speed.

 

  • lightweight轻量级:

Keeping spatial over­head to a min­im­um is im­port­ant for any data rep­res­ent­a­tion format, es­pe­cially when used over the net­work

如同json,平台无关

  • traversable可遍历:BSON的设计主要设计目标之一,以C的方式描述了文档、数据项类型、长度等,MongoDB比较依赖的特性
  • efficient有效:由于使用了C数据类型,在所有语言里都能快速的编解码

5.2.3 关于BSON存储空间有效性的一点说明

BSON注重于空间的有效性,但是在很多情况下并没有比JSON有效多少。甚至在一些情况下比JSON使用更多的空间。 导致这个的原因是BSON的另一个设计目标:可遍历性。BSON增加了一些额外的信息,比如长度前缀,这使得它更容易并快速的遍历,BSON的设计同时也注重编码和解码,例如整数被存储为32或者64位整数,所以不必从文本去解析再转换。 显然这些相对与JSON会花费更多的空间,换来的好处是解析快很多。

5.2.4 mongodb项目是BSON规范的主要应用之一

发起者和探索者

5.3 mongodb basic

5.3.1 安装

  • 解压执行文件或编译源码即可,相当的轻量级
  • 包括服务器守护程序(mongod、mongos等)、客户端(mongo)
  • 恢复mongorestore,备份mongodump(数据文件bson)
  • 导出mongoexport、导入mongoimport等(文档document/ json)
  • 客户端以命令行的方式与服务器交互,类似mysql
  • 支持javascript脚本
  • 各种操作可用以函数、命令实现交互,实际上函数就是内置的js函数

5.3.2 数据的逻辑组织结构:类似关系数据

  • 数据库

n  有系统库admin,存放系统用户名

n  简单的权限访问控制,system user表

n  每个库有默认的表 system.indexes ,记录该库中所有的索引信息

n  show dbs

n  一个collection,文档的集合,一条记录以文档(BSON)的形式组织

n  表名采用命名空间(namespace)的方式组织,原因?层次关系明了,如netease.finance.forex ;

 

n  show tables / show  collections

  • 索引:见full index

5.3.3 Memory Mapped Storage Engine

  • 默认的存储引擎
  • 服务启动时将map all datafiles to memory,操作系统负责flush data并维护内存页面在内存和虚拟内存之间的调度

n  MongoDB’s code for managing memory is small and clean

n  服务进程吃内存,内存的调度交给os

n  不能控制写磁盘的顺序,it impossible to use a writeahead log to provide single-server durability.

n  32-bit mongodb受内存寻址局限只能管理2gb的数据,64-bit无限制

5.3.4 数据的物理组织结构:

以名为foo的库为例

  • 文件种类

n  foo.ns:类似系统文件

n  foo.0,foo.1,foo.2,......:数据文件

n  double  increase,up to 2GB

n  如果设置了预分配,则肯定有一个待用的空文件,以避免写数据时在分配文件上被阻塞

  • 物理结构

n  数据文件被分成多个盘区(extent)系统维护了一个空间盘区列表foo.$freelist

n  一个逻辑的namespace(collection)占用一个或多个盘区,而且很可能是物理不连续的

n  图示

 

5.4 CURD

5.4.1 create:

  • 同时支持显示和隐式创建,包括库和表(若没有指定的库或表,则自动创建)
  • 由于shema-free,所以创建时只需要指定名字即可,类似于指定一个分级别的容器
  • db.createCollection(name, { size : ..., capped : ..., max : ... } )

5.4.2 update:

  • db.test.update(query, object[, upsert_bool, multi_bool])

n  query指定更新的记录

n  objec指定更新之后的内容,可以是表达式

n  常用的$modifies包括:$set, $inc, $push, $addToSet, $pop, $pull, $等

n  eg:db.users.update({name:"user1"}, {$inc:{age:10}, $set:{sex:1}})

n  eg:db.test.update({name:"user1"},{name: "user2"},false,false)

n  upsert_bool:当记录不存在时,是否insert,true or false

n  muti_bool:是否更新多行(多个文档)当设定为true时,更新内容表达式必须使用$操作符;设定为false时,只会更新满足条件的第一个文档

5.4.3 read;见doc based query

5.4.4 delete

  • db.collection.remove(query);删除collection中符合条件的记录,不可恢复
  • db.dropDatabase():删除数据库,不可恢复

5.5 doc-based query

5.5.1 能实现sql的大部分查询功能,翻译简单

  • db.users.find({name:"user1"})
  • db.users.find({sex:1, age:{$gt:23, $lt:28}}) 多字段 AND组合

n  常用比较操作符包括:$gt (>)、$lt (<)、$gte (>=)、$lte(<=)、$ne (!=)

 

n  $exists :判断字段是否存在,eg:db.users.find({sex:{$exists:true}})

  • db.users.find({$or:[{age:25}, {age:28}]})  OR组合
  • db.users.find().sort({age:1})  按age升序
  • db.users.find().sort({sex:1, age:-1}) 多字段排序
  • db.users.find().skip(2).limit(3)  切片操作slice
  • db.users.find({age:{$in:[23,26,32]}})  in操作符

n  $nin  equal to ‘not in’

  • db.users.find({age:{$gt:30}}).count()  count统计

5.5.2 find() return a cursor

5.5.3 findOne() return a document or null

5.5.4 Aggregation支持

  • count
  • distinct
  • group

n  包含group操作的SQL:只有参与的group字段和聚合函数才能作为select 中的列,mongodb的group也是类似的

n  group的实现用到了MapReduce机制

n  示例

 

5.5.5 Query Optimizer

  • not cost based
  • when testing new plans, MongoDB executes multiple query plans in parallel.  As soon as one finishes, it terminates the other executions, and the system has learned which plan is good 有新的查询时,并行执行多种查询计划,一旦有完成的立即结束其他的执行,并记住这个相对good的查询计划
  • if the query seems to be taking longer than usual, the database will once again run the query in parallel to try different plans.

5.6 Full Index

  • Index on any attribute, just like you‘re used to
  • BTree结构
  • Default key:_id,不可删除,强制唯一,类似rowid
  • 可以在嵌套document的key上建立索引
  • 索引字段可以是任意类型,包括document

5.6.1 支持组合索引

  • db.factories.ensureIndex( { "metro.city" : 1, "metro.state" : 1 } );
  • 索引的升降序对单个索引和随机检索不产生影响,但对复合索引上的范围查询和排序操作至关重要?
  • 只有在查询包含第一列时才使用索引,其他的情况下不使用除非强制使用

n  If the first key of the index is present in the query, that index may be selected by the query optimizer. If the first key is not present in the query, the index will only be used if hinted explicitly

5.6.2 unique index

  • 唯一键索引:保证不会在索引key/keys下插入相同的value/values
  • any missing indexed keys will be inserted with null values

n  所以不包含index-key的记录最多只可能出现一条

  • db.things.ensureIndex({firstname : 1}, {unique : true, dropDups : true})

n  创建唯一索引时删掉重复记录

5.6.3 Sparse Indexes

  • 图示

 

  • 非完全索引:any document that is missing the sparsely indexed field will not be stored in the index 所有不包含索引key的记录不会被存储在索引中
  • 非block-level索引:可以认为是 dense indexes(稠密索引) with a specific filter
  • You can combine sparse with unique to produce a unique constraint that ignores documents with missing fields:允许多个不包含index-key的document,同时对包含index-key的document实施唯一约束

5.6.4 use explain() and hint

  • db.c.find({"age" : 14, "username" : /.*/}).explain()
  • db.c.find({"age" : 14, "username" : /.*/}).hint({"username" : 1, "age" : 1})

5.6.5 Geospatial index

  • 应用: finding the nearest N things to a  location
  • 方案:index for coordinate plane queries,二维坐标上的索引
  • value:包含两个键值对,默认的值域范围-180到180,可设置

n  db.star.trek.ensureIndex({"light-years" : "2d"}, {"min" : -1000, "max" : 1000})

n  db.places.ensureIndex( { loc : "2d" } , { bits : 26 } )

  • 使用

n  db.map.find({"gps" : {"$near" : [40, -73]}}).limit(10)

n  db.runCommand({geoNear : "map", near : [40, -73], num : 10})

n  db.map.find({"gps" : {"$within" : {"$box" : [[10, 20], [15, 30]]}}})

n  db.map.find({"gps" : {"$within" : {"$center" : [[12, 25], 5]}}})

 

  • the earth is not a 2d plane

根据精度需求使用近似算法转换

5.6.6 索引的删除

  • db.collection.dropIndexes()
  • db.collection.dropIndex({x: 1, y: -1})

5.7 Replication

由于存储引擎不能提供single-server durability,生产环境下复制是必要的,一共有两种方式。

 

5.7.1 Master-Slave Replication

Master/slave: 一对一、一对多、多对多

  • 如果一个slave复制多个master,相同的表会被合并,不推荐这么做
  • transaction log:master.local.oplog.$main:记录主库上的operations,时间点间隔默认是10秒

 

  • slave.local.sources:从库的master列表

 

  • 同步的工作方式

n  主库oplog记录主库上所有的operations,覆盖写,大小很重要,--oplogsize参数指定

n  pull:从库向主库apply并perform oplog 里的operations

n  从库启动时,会首先做一个full sync,可以指定参数--fastsync 表示实例从复制源的一个快照开始

n  out of sync:极端情况,复制将会停止,需要fully resync,可以手动执行命令,也可以在启动时指定--autoresync选项

  • 启动选项

 

  • 不爽:不支持slave-slave复制,不能级联,单master

5.7.2 Replica Sets

  • basically asynchronous master/slave replication
  • 自动故障转移和恢复

 

  • --repSet参数指定
  • vote

n  primary-secondaries,primary投票产生

n  节点种类

标准节点:full copy,participate in vote、can be elected primary,1>优先级>0,

被动节点:full copy,participate in vote、nerver be elected primary,优先级为0,无被选举权,也不参与读写

 

仲裁节点:only in vote,只有选举权,解决多个partition僵持的情况(break tie)

n  优先级使用场合

当产生了新的primary时,需要resync,如何选择master,不一定是primary

 

n  server状态:primary、secondary、recovering

n  标准节点发现primary unreachable(heartbeat网络错误or连接超时10s)时,发起选举

n  primary节点使用heartbeat跟踪所有可用节点,数目少于临界值时,自动放弃primary身份

n  选举:投票过程?可用,能获取大多数投票,数据最新maxLocalOpOrdinal

 

 

n  选举出新的primary时,所有secondaries全部resync

n  可能会丢失最新数据,丢失的数据将会写入特定的文件以备手动恢复

n  取决于新老primary之前的同步情况

n  会有永久丢失的吗

= ?

n  新版本1.9支持手动申请roll back数据

n  如果选举不能达成一致,replica set 不可写,同样在新primary产生之前

n  所以快速选出primary很重要,注意arbiter,有助于打破平衡

  • 对外访问接口 foo/anode:port

5.7.3 适用场合

如果不是版本(<1.6)和机器限制,推荐使用replia sets

5.8 GridFS

  • MongoDB为存储大文件而制定的一种规范
  • 提供一种透明的机制将大文件分割成多个文档,可以存储大的对象,比如视频
  • 各种驱动里均有实现,使用方便,只需要关心API即可
  • put get等,内部依据file_id来操作文件

5.8.1 规范

  • use two mongodb‘s  collections to store data

n  files:contains the object metadata

 

n  chunks:contains the binary chunks with some addtional accounting info

 

  • index:自动在chunks的files_id和n上建立唯一索引

 

5.9 sharding

5.9.1 保证可扩展性的关键特性之一,水平扩展

 

5.9.2 自动分割数据并将不同分区存储在不同的机器上

5.9.3 适用场景

 

5.9.4 shard key,类似于关系数据库里制定分区用的字段,依据value的值域来划分分区?

  • 决定insert的分布
  • 字典顺序A~Z,timestamp时间区间

5.9.5 构成

图示

 

  • shard:一个或一组(replicat set)管理data的mongod,独立运行,自己并不知道参与了sharding
  • mongos:路由,负责转发请求、处理并相应结果

$ ./mongos --port 30000 --configdb localhost:20000

  • config server:which data is on which shard,也是有mongod进程承担

$ ./mongod --dbpath ~/dbs/config --port 20000

  • mongo连接mongos,添加shard节点

 

  • shard data设定切片

 

 

5.9.6 通常和replica功能配合,同时保证可用性和可扩展性

 

需要说明:不是一个节点一台物理机器,但是避免在同一台机器上部署所有同类型的节点

5.10 map/reudce

5.10.1 map-reduce工作流程

  • 可行性

n  子计算各自独立

n  子计算无顺序要求

  • 示例图

 

5.10.2 MongoDB内置mapreduce支持,用于批量(海量)数据处理和聚集操作(如group by)

5.10.3 调用方式

 

  • db.collection.mapReduce(m,r[,option])

5.10.4 实例

  • 示例一

 

  • 示例二

 

5.10.5 不爽

  • 由于javascript engins设计的限制,目前单个mongod里的MapReduce是单线程
  • sharding 或者 在客户端代码里实现并行

6 mongoDB的应用情况

6.1 国外

6.2 国内

  • 淘宝网、视觉中国、大众点评等

7 mongoDB社区

7.1 License

 

7.2 10gen的商业支持

 

7.3 支持C++,PHP,java,ruby,python,perl,c#,scala等多种开发语言,driver丰富完善

7.4 社区活跃

8 问题&讨论

 

9 To be continute

性能测试

谢谢!!

 

MongoDB介绍

标签:

原文地址:http://www.cnblogs.com/200911/p/4893912.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!