mongo db技术分享
TRANSCRIPT
MongoDB技术分享
主讲:胡创健
分享目录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 技巧汇总
MongoDB 简介
memcached sqlserver siis
iis
Mongo 是一个高性能,开源,无模式的文档型数据库 ( 采用文件内存映射机制 ),它在许多场景下可用于替代传统的关系型数据库或键 /值存储方式。Mongo使用 C++开发。
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% 的性能提高
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 等系统消耗是相当的低
MongoDB特点高性能、易部署、易使用,存储数据非常方便。主要功能特性有:* 面向集合存储,易存储对象类型的数据。 * 模式自由 ( 没有行,列,关系等概念 ) 。* 支持动态查询 , 拥有与 sqlserver 相似的查询功能 。 * 支持完全索引,包含内部对象。 * 支持查询。 * 支持复制和故障恢复。 * 使用高效的二进制数据存储,包括大型对象(如视频等)。* 自动处理碎片,以支持云计算层次的扩展性* 支持 C#, Python, PHP, Ruby, Java, C, Javascript, Perl及 C++ 语言的驱动程序,社区中也提供了对 Erlang 及 .NET 等平台的驱动程序。* 文件存储格式为 BSON (一种 JSON 的扩展)* 可通过网络访问
模式自由 MongoDB 是面向文档的数据库,而不是关系型数据库。1 、面向文档的方式可以将文档对象或者数组内嵌进来,用
一条记录就可以表示非常复杂的层次关系——适合面向对象语言的开发。
2 、文档 与 关系型数据库对比:从关系数据库的范式的概念来说,嵌套是明显的反范式设计。范式设计的好处是消除了依赖,但是增加了关联,查询需要通过关联两张或者多张表来获得所需要的全 部数据,但是更改操作是原子的,只需要修改一个地方即可。反范式则是增加了数据冗余来提升查询性能,但更新操作可能需要更新冗余的多处数据,需要注意一致 性的问题。
内存映射存储引擎
MongoDB 目前支持的存储引擎为内存映射引擎。当MongoDB启动的时候,会将所有的数据文件映射到内存中,然后操作系统会托管所有的磁盘操作。这种存储引擎有以下几种特点:
* MongoDB 中关于内存管理的代码非常精简,毕竟相关的工作已经有操作系统进行托管。
* MongoDB服务器使用的虚拟内存将非常巨大,并将超过整个数据文件的大小 ( 数据文件如果超过内存大小,搜索性能将会大大降低 ) 。不用担心,操作系统会去处理这一切。
* MongoDB无法控制数据写入磁盘的顺序,这样将导致MongoDB无法实现 writeahead日志的特性。所以,如果MongoDB希望提供一种durability 的特性(这一特性可以参考关于 Cassandra 文章: http://www.cnblogs.com/gpcuster/tag/Cassandra/),需要实现另外一种存储引擎。
* 32位系统的 MongoDB服务器每一个 Mongod实例只能使用 2G 的数据文件。这是由于地址指针只能支持 32位。
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
安装文件 )
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
C# 驱动操作 ( 对照命令行 )
1 、支持单条数据插入tables.Insert(info);tables.Save(info); (区别:先根据 BsonId判断集合
中是否存在记录,存在就更新,否则就插入)BsonId= 时间戳 (4b)+ 机器 (3b)+PID(2b)+ 计数器
(3b)(BsonId为 12 字节字符串,是文档的唯一标识,可
以自定义 )2 、支持批量数据插入tables2.InsertBatch(infos);
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);
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];
C# 驱动操作 ( 对照命令行 )
FindAll 用法 :
MongoDB.Driver.MongoCursor<HeadLineInfo>
mongoHeadLineInfos = new MongoHelper().GetCollection<HeadLineInfo>();
var mongoHeadLineInfoList = mongoHeadLineInfos.FindAll();
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
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" } }
企业管理器 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: 操作耗时 (毫秒 ) 。
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")));
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);
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);
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 。
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);
MongoDB的架构
1.Master-Slave Replication
MongoDB的架构
2.Replica Sets 集群方案
Replica Set 模式 含一个 primary ,一个 secondary ,和一个 arbiter( arbiter 的唯一作用是在primary 宕机后选举新的 primary 时拥有投票权,用以使存活节点数大于 50% ,不包括 50% ,否则系统将整个 down掉,以及在票数相同的情况下用以打破选举 的平衡,并不存储和读取数据)。
Master-Slave Replication与 Replica Sets 集群方案比较
优点:主数据服务器或从数据服务器挂掉后,会自动切换主数据库,不用人工干预,稳定性比 Master-Slave Replication 高。
缺点 :需要客户端的驱动支持,因为客户端在与主服务器连接失败后,会向集群的其他服务器发一条特殊的指令询问,谁是新的主数据服务器。
集群的服务器在不做分区的前提下,分成三种,主数据服务器,从数据服务器,选举服务器(只做投票不存储数据),若做数据分
区还有配置服务器。
部署方法步骤一:在三台服务器启动 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" />
设置集群查看状态命令可以通过命令行查看集群状态,也可以通过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
}
MongoDB功能1. 面向集合的存储:适合存储对象及 JSON形式的数据。2. 动态查询: Mongo 支持丰富的查询表达式。查询指令使用 JSON形式的标
记,可轻易查询文档中内嵌的对象及数组。3. 完整的索引支持:包括文档内嵌对象及数组。 Mongo 的查询优化器会分析
查询表达式,并生成一个高效的查询计划。4. 查询监视: Mongo 包含一个监视工具用于分析数据库操作的性能。5. 复制及自动故障转移: Mongo 数据库支持服务器之间的数据复制,支持主 -
从模式及服务器之间的相互复制。复制的主要目标是提供冗余及自动故障转移。
6. 高效的传统存储方式:支持二进制数据及大型对象(如照片或视频)7. 自动分片以支持云级别的伸缩性:自动分片功能支持水平的数据库集群,可
动态添加额外的机器。
MongoDB适用场合1. 网站数据: Mongo 非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
2. 缓存:由于性能很高, Mongo 也适合作为信息基础设施的缓存层。在系统重启之后,由 Mongo搭建的持久化缓存层可以避免下层的数据源 过载。
3. 大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵,在此之前,很多时候程序员往往会选择传统的文件进行存储。
4. 高伸缩性的场景: Mongo 非常适合由数十或数百台服务器组成的数据库。某公司经典案例: MongoDB 存储的数据量已超过 50亿, >1.5TB
5. 用于对象及 JSON 数据的存储: Mongo的 BSON 数据格式非常适合文档化格式的存储及查询。
MongoDB不适用场合1. 高度事务性的系统:例如银行或会计系统。传统的关系型数据库目
前还是更适用于需要大量原子性复杂事务的应用程序。
1. 传统的商业智能应用:针对特定问题的 BI 数据库会对产生高度优化的查询方式。对于此类应用,数据仓库可能是更合适的选择。
1. 需要复杂 SQL 的问题
MongoDB谁在用 ?谁在使用 ?
Mongo与Mysql语法对应关系图
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 &
MongoDB分布式 -Sharding(碎片 )
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();
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
小结
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 系统安装
谢谢大家!