mongo db技术分享

39
MongoDB 技技技技 主主 主主主

Upload: -

Post on 30-Jun-2015

1.100 views

Category:

Technology


8 download

TRANSCRIPT

Page 1: Mongo db技术分享

MongoDB技术分享

主讲:胡创健

Page 2: Mongo db技术分享

分享目录1.MongoDB 简介 2.MongoDB 版本对比3.MongoDB 性能测试 4.MongoDB 特点5.MongoDB 命令行与 C# 驱动操作对照6.MongoDB 的架构--1.Master-Slave Replication

--2.Replica Sets 集群方案7. 部署方法8. 设置集群查看状态命令9.MongoDB 适用场合10.MongoDB 不适用场合11. linux下mongodb 的安装12.MongoDB 技巧汇总

Page 3: Mongo db技术分享

MongoDB 简介

memcached sqlserver siis

iis

Mongo 是一个高性能,开源,无模式的文档型数据库 ( 采用文件内存映射机制 ),它在许多场景下可用于替代传统的关系型数据库或键 /值存储方式。Mongo使用 C++开发。

Page 4: Mongo db技术分享

MongoDB 版本对比Mongo 当前稳定版是 1.8.2( 见附件mongodb.rar) 比前一版本 1.4 做了很多改进 ( 使用C# 驱动 MongoDB.Driver.dll和MongoDB.Bson.dll( 见附件 C# 驱动类库 .rar)):# 改进和提高了并发性能。# Mongodb 存储文件申请磁盘空间的方式做了改进。# 增加了 $or 等查询操作符。# Replication 的同步方面做了改进。

select 方面 , 性能提升显著,合计有 83% 性能提高update 方面有 75% 的性能提高

Page 5: Mongo db技术分享

MongoDB 性能测试

Mongo 测试数据( suse11-64bit、 xeon3.6*2、 4G DDR333、 scsi73G*2无 raid 的机器)

1 、 insert 九百万条简单数据( 3 个字段):平均值大约在24000/s (最高 2.8W ,最低 2.1W );同时,插入第一个一百万和第九个一百万效率没有明显差异,数据文件体积大概在 3.8G ,比较大;

2 、 select 一万条数据(有索引): 57~61ms ,一千条大概在6ms 左右,非常稳定;

数据量约 2 千万,数据库 300G 的情况下,读写 2000rps, CPU 等系统消耗是相当的低

Page 6: Mongo db技术分享

MongoDB特点高性能、易部署、易使用,存储数据非常方便。主要功能特性有:* 面向集合存储,易存储对象类型的数据。 * 模式自由 ( 没有行,列,关系等概念 ) 。* 支持动态查询 , 拥有与 sqlserver 相似的查询功能 。 * 支持完全索引,包含内部对象。 * 支持查询。 * 支持复制和故障恢复。 * 使用高效的二进制数据存储,包括大型对象(如视频等)。* 自动处理碎片,以支持云计算层次的扩展性* 支持 C#, Python, PHP, Ruby, Java, C, Javascript, Perl及 C++ 语言的驱动程序,社区中也提供了对 Erlang 及 .NET 等平台的驱动程序。* 文件存储格式为 BSON (一种 JSON 的扩展)* 可通过网络访问

Page 7: Mongo db技术分享

模式自由 MongoDB 是面向文档的数据库,而不是关系型数据库。1 、面向文档的方式可以将文档对象或者数组内嵌进来,用

一条记录就可以表示非常复杂的层次关系——适合面向对象语言的开发。

2 、文档 与 关系型数据库对比:从关系数据库的范式的概念来说,嵌套是明显的反范式设计。范式设计的好处是消除了依赖,但是增加了关联,查询需要通过关联两张或者多张表来获得所需要的全 部数据,但是更改操作是原子的,只需要修改一个地方即可。反范式则是增加了数据冗余来提升查询性能,但更新操作可能需要更新冗余的多处数据,需要注意一致 性的问题。

Page 8: Mongo db技术分享

内存映射存储引擎

MongoDB 目前支持的存储引擎为内存映射引擎。当MongoDB启动的时候,会将所有的数据文件映射到内存中,然后操作系统会托管所有的磁盘操作。这种存储引擎有以下几种特点:

* MongoDB 中关于内存管理的代码非常精简,毕竟相关的工作已经有操作系统进行托管。

* MongoDB服务器使用的虚拟内存将非常巨大,并将超过整个数据文件的大小 ( 数据文件如果超过内存大小,搜索性能将会大大降低 ) 。不用担心,操作系统会去处理这一切。

* MongoDB无法控制数据写入磁盘的顺序,这样将导致MongoDB无法实现 writeahead日志的特性。所以,如果MongoDB希望提供一种durability 的特性(这一特性可以参考关于 Cassandra 文章: http://www.cnblogs.com/gpcuster/tag/Cassandra/),需要实现另外一种存储引擎。

* 32位系统的 MongoDB服务器每一个 Mongod实例只能使用 2G 的数据文件。这是由于地址指针只能支持 32位。

Page 9: Mongo db技术分享

MongoDB安装mongod --logpath D:\webroot\mongodb\log\MongoDB.log --logappend --dbpath D:\webroot\mongodb\data --directoryperdb --serviceName MongoDB1 --port 25436 --install

注:此处是将 mongod.exe注册为 windows服务 ,必须先在相应目录下建立 data与 log 目录,否则安装时提示错误 ( 附件 mongodb.rar为mongodb

安装文件 )

Page 10: Mongo db技术分享

MongoDB 命令行操作 普通操作1 、新建集合集:> db.createCollection("user");2 、插入数据:> db.user.insert({uid:1,username:"Falcon.C",age:25});> j = { name: "mongo"};> db.things.save(j);> for( var i = 1; i < 10; i++ ) db.tables.save( { x:4, j:i } );3 、更新数据:> db.user.update({uid:1},{$set:{age:26}}) #age=26> db.user.update({uid:1},{$inc:{age:-1}}) #age=age-1

Page 11: Mongo db技术分享

C# 驱动操作 ( 对照命令行 )

1 、支持单条数据插入tables.Insert(info);tables.Save(info); (区别:先根据 BsonId判断集合

中是否存在记录,存在就更新,否则就插入)BsonId= 时间戳 (4b)+ 机器 (3b)+PID(2b)+ 计数器

(3b)(BsonId为 12 字节字符串,是文档的唯一标识,可

以自定义 )2 、支持批量数据插入tables2.InsertBatch(infos);

Page 12: Mongo db技术分享

C# 驱动操作 ( 对照命令行 )

3 、支持更新数据 var query = Query.And(Query.EQ("Number", gcommentInfo.Number),

Query.EQ("IsHotting", 1));

var update = Update.Set("Id", gcommentInfo.Id) .Set("NewsId", gcommentInfo.NewsId) .Set("ChnId", gcommentInfo.ChnId); var info = mongoGCommentInfos.FindOne(query); if (info != null) mongoGCommentInfos.Update(query, update);

Page 13: Mongo db技术分享

MongoDB 命令行操作普通操作4 、查询: 4.1遍历集 > var cursor = db.things.find(); > while (cursor.hasNext()) { print(tojson(cursor.next())); } 4.2 方法 2 > db.things.find().forEach( function(x){print(tojson(x));}); 4.3 、获取结果集 > var cursor = db.things.find(); > print (tojson(cursor[4])); > var arr = db.things.find().toArray(); > arr[5];

Page 14: Mongo db技术分享

C# 驱动操作 ( 对照命令行 )

FindAll 用法 :

MongoDB.Driver.MongoCursor<HeadLineInfo>

mongoHeadLineInfos = new MongoHelper().GetCollection<HeadLineInfo>();

var mongoHeadLineInfoList = mongoHeadLineInfos.FindAll();

Page 15: Mongo db技术分享

MongoDB 命令行操作普通操作5 、条件查询:> db.things.find({name:"mongo"}).forEach(function(x) { print(tojson(x));});等价于: SQL: SELECT * FROM things WHERE name="mongo"

>db.things.find({x:4}, {j:true}).forEach(function(x) { print(tojson(x));});等价于:SQL: SELECT j FROM things WHERE x=4

Page 16: Mongo db技术分享

C# 驱动操作 ( 对照命令行 )

4 、支持条件查询( 查询操作可以用文档与企业管理器 MongodbVUE配套使用 )

a.日期查询:Query.GT("SubmitTime",MongoDB.Bson.BsonDateTime.Create(DateTime.Now.AddDays(-25)));

对应文档查询 大于某日期: { SubmitTime : { $gt : new Date(2011,5,28) } }

Query.GT() :大于某日期; Query.LT() :小于某日期; Query.ET() :等某日期;

b. 支持模糊搜索:Query.Matches("Title", "/" + key + "/i");

对应文档: {"Title" : { "$regex" : "基尼系数 ", "$options" : "i" }}c. 支持 and 条件

Query.And(Query.EQ("Channel._id", BsonInt32.Create((int)type)), Query.Matches("Title", "/" + key + "/i"));

对应文档 : { "Channel._id" : 18,"Title" : { "$regex" : "抵制 ", "$options" : "i" } }

Page 17: Mongo db技术分享

企业管理器 MongodbVUE监控(安装附件 MongoDB企业管理器 Installer-0.9.7.2.zip )system.profile 中记录下一条耗时过长的操作。模糊查询性能测试: query news2.Jiubang.NewsClient2.Models.Entities.NewsInfo ntoreturn:50 reslen:313

nscanned:42841  query: { $query: { Title: { $regex: "基尼系数 ", $options: "i" } }, $explain: true }  nreturned:1 215ms

Or 条件与模糊查询性能测试: query news2.Jiubang.NewsClient2.Models.Entities.NewsInfo scanAndOrder reslen:192393 nscanned:42810 query: { $query: { $or: [ { Title: / 百度 /i }, { Keywords: / 百度 /i } ] }, $orderby: { UpdateTime: -1 } } nreturned:27 255ms 

 In 条件性能测试: query news2.$cmd ntoreturn:1 command: { count: "Jiubang.NewsClient2.Models.Entities.HeadLineInfo", query: { ChannelType: { $in: [ 10, 74, 21 ] }, SType: 0 } } reslen:64 139ms

ts: 操作执行时间。    info: 操作详细信息。    info.query: 查询目标 ( 数据库 . 集合 ) 。    info.ntoreturn: 客户端期望返回的文档数量。    info.nscanned: 服务器实际扫描的文档数量。    info.reslen: 查询结果字节长度。    info.nreturnned: 查询返回文档数。    millis: 操作耗时 (毫秒 ) 。

Page 18: Mongo db技术分享

C# 驱动操作 ( 对照命令行 )

d. 支持对象或数组字段搜索Query.EQ("Channel._id", MongoDB.Bson.BsonInt32.Create((int)type));

e. 支持 or 条件: Query.Or(Query.Matches("Title", "/" + key + "/i"), Query.Matches("KeyWords", "/" + key + "/i"));

对应文档: { "$or" : [{ "Title" : { "$regex" : "杀 ", "$options" : "i" } }, { "Keywords" : { "$regex" : " 杀 ", "$options" : "i" } }] }

f. 支持 In 用法Query.In("ChannelType", MongoDB.Bson.BsonArray.Create(new[] { 10, 74, 21 }));

f. 支持模糊搜索区分大小写 和 以某个字符开头匹配 ^ 符号表示以 lvl开头, I表示区分大小写, i表示不区分大小写

Query.And(Query.EQ("ChnId", MongoDB.Bson.BsonInt32.Create(ChnId)), Query.Matches("Lvl", new MongoDB.Bson.BsonRegularExpression("^" + lvl, "I")));

Page 19: Mongo db技术分享

MongoDB 操作 普通操作6 、 sort 用法>db.things.find({tags :'economy'}).sort({ts:-1}).limit(10);等价于:SQL: select * from things where 'economy' in tags order by ts DESC limit 10

7 、 findOne 用法> var mongo = db.things.findOne({name:"mongo"});> print(tojson(mongo));

8 、 limit 用法db.things.find().limit(3);

Page 20: Mongo db技术分享

C# 驱动操作 ( 对照命令行 )

g. sort 用法query = Query.In("ChannelType", MongoDB.Bson.BsonArray.Create(new[]

{ 10, 74, 21 }));

var sort = SortBy.Descending(new string[] { "Number", "SubmitTime" });

HeadLineTable = HeadLineTb.Find(query).SetSortOrder(sort);

h. findOne 用法var query = Query.EQ("_id", MongoDB.Bson.BsonString.Create(KeyId));

var info = newsinfos.FindOne(query);

Page 21: Mongo db技术分享

MongoDB 操作 索引>db.u_info.insert({uid:1,name:"Falcon.C",address:"Beijing"});

>db.u_info.insert({uid:2,name:"sexMan",address:"Wuhan"});

添加:>db.u_info.ensureIndex({uid:1});

>db.u_info.ensureIndex({name:1});

删除:>db.u_info.dropIndex("name_1")

查询索引>db.u_info.find({name:"Falcon.C"}).explain();查询的条件中有索引时,查询走 BtreeCursor 的索引,而没有索引时走 BasicCursor 。

Page 22: Mongo db技术分享

C# 驱动操作 ( 对照命令行 )

g.索引添加索引:

var headLineInfos = new MongoHelper().GetCollection<HeadLineInfo>();

headLineInfos.EnsureIndex(IndexKeys.Descending("NewsId"));

headLineInfos.EnsureIndex(IndexKeys.Descending(“ChannelType”, “SubmitTime”));( 支持复合索引 )

移除索引:headLineInfos.DropIndex(IndexKeys.Descending("IsVertical"));

h. findOne 用法var query = Query.EQ("_id", MongoDB.Bson.BsonString.Create(KeyId));

var info = newsinfos.FindOne(query);

Page 23: Mongo db技术分享

MongoDB的架构

1.Master-Slave Replication

Page 24: Mongo db技术分享

MongoDB的架构

2.Replica Sets 集群方案

Page 25: Mongo db技术分享

Replica Set 模式 含一个 primary ,一个 secondary ,和一个 arbiter( arbiter 的唯一作用是在primary 宕机后选举新的 primary 时拥有投票权,用以使存活节点数大于 50% ,不包括 50% ,否则系统将整个 down掉,以及在票数相同的情况下用以打破选举 的平衡,并不存储和读取数据)。

Page 26: Mongo db技术分享

Master-Slave Replication与 Replica Sets 集群方案比较

优点:主数据服务器或从数据服务器挂掉后,会自动切换主数据库,不用人工干预,稳定性比 Master-Slave Replication 高。

缺点 :需要客户端的驱动支持,因为客户端在与主服务器连接失败后,会向集群的其他服务器发一条特殊的指令询问,谁是新的主数据服务器。

集群的服务器在不做分区的前提下,分成三种,主数据服务器,从数据服务器,选举服务器(只做投票不存储数据),若做数据分

区还有配置服务器。

Page 27: Mongo db技术分享

部署方法步骤一:在三台服务器启动 mongodb服务,Windows和 Linux都类似,只是文件路径有部分差别。指令如下: mongod --replSet car( 集群名称 ) --port 25017(端口 ) --dbpath

E:\mongodb-test\data1( 数据文件路径 )

步骤二:用mongo 命令行工具连接mongo服务器,并配置集群服务,指令如下:

config = {_id: 'car',

members: [

{_id: 0, host: '192.168.56.71:25017'},

{_id: 1, host: 192.168.56.72:25017', initialSync : {state : 1}},

{_id: 2, host: '192.168.56.73:25017', arbiterOnly : true}

]}

rs.initiate(config)

步骤三:修改客户端的连接字符串:<add key="constr"

value="mongodb://192.168.56.71:25017,

192.168.56.72:25017/?connect=replicaSet;replicaSet=car" />

Page 28: Mongo db技术分享

设置集群查看状态命令可以通过命令行查看集群状态,也可以通过C#驱动检查集群状态(见附件:检查单台服务器或主服务器 .rar)d:\webroot>e:

E:\>cd\Tools\mongodb\bin

E:\Tools\mongodb\bin>mongo 192.168.56.71:25017

MongoDB shell version: 1.8.2

connecting to: 192.168.56.71:25017/test

car:PRIMARY> rs.status()

{

"set" : "car",

"date" : ISODate("2011-07-11T03:48:37Z"),

"myState" : 1,

"members" : [

{

"_id" : 0,

"name" : "192.168.56.71:25017",

"health" : 1,

"state" : 1,

"stateStr" : "PRIMARY",

"optime" : {

"t" : 1310355731000,

"i" : 1

},

"optimeDate" : ISODate("2011-07-11T03:42:11Z"),

"self" : true

},

{

"_id" : 1,

"name" : "192.168.56.73:25017",

"health" : 1,

"state" : 7,

"stateStr" : "ARBITER",

"uptime" : 382,

"optime" : {

"t" : 0,

"i" : 0

},

"optimeDate" : ISODate("1970-01-01T00:00:00Z"),

"lastHeartbeat" : ISODate("2011-07-11T03:48:37Z")

}

],

"ok" : 1

}

Page 29: Mongo db技术分享

MongoDB功能1. 面向集合的存储:适合存储对象及 JSON形式的数据。2. 动态查询: Mongo 支持丰富的查询表达式。查询指令使用 JSON形式的标

记,可轻易查询文档中内嵌的对象及数组。3. 完整的索引支持:包括文档内嵌对象及数组。 Mongo 的查询优化器会分析

查询表达式,并生成一个高效的查询计划。4. 查询监视: Mongo 包含一个监视工具用于分析数据库操作的性能。5. 复制及自动故障转移: Mongo 数据库支持服务器之间的数据复制,支持主 -

从模式及服务器之间的相互复制。复制的主要目标是提供冗余及自动故障转移。

6. 高效的传统存储方式:支持二进制数据及大型对象(如照片或视频)7. 自动分片以支持云级别的伸缩性:自动分片功能支持水平的数据库集群,可

动态添加额外的机器。

Page 30: Mongo db技术分享

MongoDB适用场合1. 网站数据: Mongo 非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。

2. 缓存:由于性能很高, Mongo 也适合作为信息基础设施的缓存层。在系统重启之后,由 Mongo搭建的持久化缓存层可以避免下层的数据源 过载。

3. 大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵,在此之前,很多时候程序员往往会选择传统的文件进行存储。

4. 高伸缩性的场景: Mongo 非常适合由数十或数百台服务器组成的数据库。某公司经典案例: MongoDB 存储的数据量已超过 50亿, >1.5TB

5. 用于对象及 JSON 数据的存储: Mongo的 BSON 数据格式非常适合文档化格式的存储及查询。

Page 31: Mongo db技术分享

MongoDB不适用场合1. 高度事务性的系统:例如银行或会计系统。传统的关系型数据库目

前还是更适用于需要大量原子性复杂事务的应用程序。

1. 传统的商业智能应用:针对特定问题的 BI 数据库会对产生高度优化的查询方式。对于此类应用,数据仓库可能是更合适的选择。

1. 需要复杂 SQL 的问题

Page 32: Mongo db技术分享

MongoDB谁在用 ?谁在使用 ?

Page 33: Mongo db技术分享

Mongo与Mysql语法对应关系图

Page 34: Mongo db技术分享

MongoDB 操作 同步复制1 、Master对 Slave

[Master]bin/mongod --dbpath=/data/db/m_data --logpath=/data/db/m_log --logappend --port=27017 --master --auth &

[Slave]bin/mongod --dbpath=/data/db/m_data --logpath=/data/db/m_log --logappend --port=27017 --slave --source=192.168.100.202:27017 --auth &

Page 35: Mongo db技术分享

MongoDB分布式 -Sharding(碎片 )

Page 36: Mongo db技术分享

MongoDB 技巧汇总 备份./mongodump -u admin -p 123456 -d user -o user -d db -o path

还原./mongorestore -u admin -p 123456 -d user -c user user/user/user.bson

帮助信息db.help();db.user.help();

Page 37: Mongo db技术分享

linux下mongodb 的安装mkdir -p /data/mongodb/data

mkdir -p /data/mongodb/logs

cd /usr/local

wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.0.0.tgz

tar zxvf mongodb-linux-x86_64-2.0.0.tgz

rm mongodb-linux-x86_64-2.0.0.tgz

mv mongodb-linux-x86_64-2.0.0/ mongodb

# 创建启动脚本vi /usr/local/mongodb/startmongodb.sh

#把以下内容复制#! /bin/bash

if [ -f /data/db/mongod.lock ];then

/bin/rm -rf /data/db/mongod.lock

fi

/usr/local/mongodb/bin/mongod -dbpath=/data/mongodb/data -logpath=/data/mongodb/logs/mongod.log --port 27017 --logappend&

# 主从设置#/usr/local/mongodb/bin/mongod --master --fork --dbpath=/data/mongodb/data

--logpath=/data/mongodb/logs/mongod.log --logappend --port=27017 > /dev/null 2>&1 &

#保存后启动 mongodb

sh /usr/local/mongodb/startmongodb.sh

Page 38: Mongo db技术分享

小结

1、Mongo 是一个高性能,开源,无模式的文档型数据库 ( 采用文件内存映射机制 ) ;

2 、当前使用的是 1.8.2 版本(安装程序见附件 mongodb.rar) ,既可以通过命令行操作,

也可以通过 C# 驱动操作 ( 见附件 C# 驱动类库 .rar) ;3 、可以搭建mongodb 集群4、 C# 驱动操作可以与企业管理器 MongodbVUE配套使用,通过

MongodbVUE的 system.Pofile 功能来监控查询效率5、 C# 驱动支持增删改查, or\In\And\ 模糊搜索等搜索条件,但不支持

join 关联搜索6 、支持排序 \findOne\limit 用法7 、支持 C# 驱动建立查询索引8 、支持 Window和 linux 系统安装

Page 39: Mongo db技术分享

谢谢大家!