MySQL DBA
分类: NOSQL
2013-03-07 13:06:02
Mongodb 特性
来由:humongous c++/java
特性:
MongoDB是一个可扩展、高性能的下一代数据库,由C++语言编写,旨在为web应用提供可扩展的高性能数据存储解决方案。它的特点是高性能、易部署、易使用,存储数据非常方便,主要特性有:
? 1.模式自由,支持动态查询、完全索引,可轻易查询文档中内嵌的对象及数组
? 2.面向文档存储,易存储对象类型的数据, 包括文档内嵌对象及数组
? 3.高效的数据存储,支持二进制数据及大型对象(如照片和视频)
? 4.支持复制和故障恢复;提供了主-从、主-主模式的数据复制及服务器之间的数据复制
? 5.自动分片以支持云级别的伸缩性,支持水平的数据库集群,可动态添加额外的服务器
适用场景:
? 适合作为信息基础设施的持久化缓存层
? 适合实时的插入,更新与查询,并具备应用程序实时数据存储所需的复制及高度伸缩性
? Mongo的BSON数据格式非常适合文档化格式的存储及查询
? 适合由数十或数百台服务器组成的数据库。因为Mongo已经包含了对MapReduce引擎的内置支持
不适用场景:
? 要求高度事务性的系统
? 传统的商业智能应用
? 复杂的跨文档(表)级联查询
特性:
1. 自由模式。逻辑结构类似关系数据库,但集合中无固定格式,可存储不同格式的文档。
2. 数据格式为key-value集合。BSON
3. 易部署。windows/linux下安装方式简单,以及主从配置,集群配置
4. 内存使用。不能指定内存大小,将所有空闲内存视为缓存
5. 磁盘使用。文件大小递增方式自动增长。
6. 唯一性标示自动生成或手动生成唯一性标识,但无自增长特性
7. 单个插入对象大小不超过4M,超过使用GirdFS方式(?)
8. 标记已删除记录,不释放空间,可重复利用
9. 主从同步更加local.oplog来实现
10. 分区及集群技术(?)
11. 安全机制
详细测试:
1. 安装配置。无其他依赖项,下载安装包后只需配置相关参数便可以启动mongodb(不包括源码安装)。
2. 运行机制。
> use test
switched to db test
> db.test.insert({name:'test',sex:'male',phone:123})
> db.test.insert({name:'test',sex:'male',phone:123,add:'china'})
> db.test.find()
{ "_id" : ObjectId("4ee462f217fc66f3e161c89b"), "name" : "test", "sex" : "male", "phone" : 123 }
{ "_id" : ObjectId("4ee4630717fc66f3e161c89c"), "name" : "test", "sex" : "male", "phone" : 123, "add" : "china" }
数据库在数据插入时创建(use db时不创建),创建后在数据目录产生2个文件,大小为16M:test.0为数据文件存放文档数据;test.ns,存放索引。存储格式为key-value,_id字段没有指定的情况由系统自动产生,生成格式:BSON ObjectId长12个字节,包含4字节的时间戳、3字节的机器id、2字节的进程id以及3字节长的计数器。也可以自定义_id自增长唯一字段:
> db.test.insert({_id:001,name:'test',sex:'male',phone:123,add:'china'})
> db.test.find()
{ "_id" : ObjectId("4ee462f217fc66f3e161c89b"), "name" : "test", "sex" : "male", "phone" : 123 }
{ "_id" : ObjectId("4ee4630717fc66f3e161c89c"), "name" : "test", "sex" : "male", "phone" : 123, "add" : "china" }
{ "_id" : 1, "name" : "test", "sex" : "male", "phone" : 123, "add" : "china" }
在同一库中,可存放不同格式的文档数据,体现其模式的自由。
3.内存使用(?)。
MongoDB使用的是内存映射存储引擎,它会把磁盘IO操作转换成内存操作,如果是读操作,内存中的数据起到缓存的作用,如果是写操作,内存还可以把随机的写操作转换成顺序的写操作,可以大幅度提升性能。MongoDB并不干涉内存管理工作,而是把这些工作留给操作系统的虚拟缓存管理器去处理,这样的好处是简化了MongoDB的工作,但坏处是控制MongoDB占多大内存,事实上MongoDB会占用所有能用的内存,所以最好不要把别的服务和MongoDB放一起。
测试中发现,在插入大数据量(百万,千万)时,mongodb会不断占用系统空闲内存,直到物理内存使用90%以上。获取内存使用的情况可通过mongostats或者以下命令:
> db.serverStatus().mem
{
"bits" : 32,
"resident" : 33, //实际内存
"virtual" : 152, //虚拟内存
"supported" : true,
"mapped" : 96 //映射数据量大小
}
4.磁盘使用。
采用预分配方式,数据文件为一倍递增,命名为dbname.0,dbname.1….文件大小增长方式为64M,128M..,每次增长为上一个文件的2倍。32位服务器上单文件上限2G。win7上测试,初始文档大小为16M,增加到512M后,后一个文件任然是512M。
插入248万数据后文件为:
16,777,216 test.0
33,554,432 test.1
67,108,864 test.2
134,217,728 test.3
268,435,456 test.4
16,777,216 test.ns
当数据删除后,不释放原空间,而是继续占用,并添加delete标志,后续插入数据将使用:
> db.test.storageSize()
20480
> db.test.remove({date:123})
> db.test.storageSize()
20480
在数据删除后,实际数据量减少,当存储空间不释放,用于存储后期插入数据。此时插入新数据:
> db.test.storageSize()
20480
> db.test.insert({name:'testthestorage'})
> db.test.storageSize()
20480
插入新数据后,存储空间未增加,占用已删除的数据空间。
5.主从同步。
同步介质:local.oplog 主机为读写模式,从库只读。
配置:(单机开启2个mongodb,端口10111,10112)
主库启动:D:\mongodb-win32-i386-2.0.1\bin>mongod -master -port=10111 -dbpath=e:\mongodb1
参数:
-master 主机模式 -oplogSize n 单位MB,oplog文件的大小
从库启动:D:\mongodb-win32-i386-2.0.1\bin>mongod -slave -source=127.0.0.1:10111 -port=10112 -dbpath=e:\mongodb2 -slavedelay 5
参数:
-slave 从机模式
-source 主机ip
-only dbname 指定同步的库
-slavedelay n 单位S,同步延迟时间
-autoresync slave自动重连
同步测试:
主机:
> use repdb
switched to db repdb
> db.repdb.insert({name:'this string can be find on the slave'})
从机:
> use repdb
switched to db repdb
> db.repdb.find()
{ "_id" : ObjectId("4ee5837f115a917e15fcc156"), "name" : "this string can be find on the slave" }
同步成功。
从库写入数据,将得到非主库报错信息:
> db.repdb.insert({name:'insert on slave'})
not master
主从切换:主库A,从库B
A停止写入
关闭B服务
清空B目录local.*文件
使用-master启动B
在B上执行一次写操作,初始化oplog,获取同步起始点
关闭B服务
关闭A服务,拷贝B中local.*文件覆盖A中的文件
使用-master 启动B
使用-slave –fastersync启动A
修改主机信息:
> use local
switched to db local
> db.sources.update({host:"127.0.0.1:10111"}),{$set:{host:"127.0.0.1:10111"}}
重新-slave启动。
6.分片集群(?)
将原先数据库中集合依据一定的规则切分成若干小块,这些分片小块统一由mongos路由管理,当有请求查询或写入时,路由会依据分片shard key规则找到对应的分片操作。分片解决了写密集操作,用于分散单一写服务器负载。亦或者原先的存储空间不够了,这个时候可能通过分片操作将之后的数据写入其它存储空间上。
7.安全机制
目前,只对用户名和密码进行认证,可控制用户读写权限,分片环境安全机制无效。
开启安全认证 启动增加-auth
用户添加/密码修改:use admin db.addUser("name","password")
认证:db.auth("name","password")
查看用户:db.system.users.find()
删除用户:db.removeUser(username)