`
forever1121
  • 浏览: 16546 次
  • 性别: Icon_minigender_2
  • 来自: 齐齐哈尔
社区版块
存档分类
最新评论

MongoDB权威指南_学习笔记3

阅读更多
GirdFS是一种在MongoDB中存储大二进制文件的机制。

mongofiles内置在MongoDB发布版中,可以用来在GridFS中上传、下载、列示、查找或删除文件。
$ echo "Hello World" > foo.txt
$ ./mongofiles put foo.txt
connected to : 127.0.0.1
added file : { _id : ObjecteId('    '),
               filename : "foo.txt",
               length : 13,
               chunkSize : 262144,
               uploadDate : new Date(   ),
               md5 : "        "
             }
done!
$ ./mongofiles list
connected to : 127.0.0.1
foo.txt 13
$ rm foo.txt
$ ./mongofiles get foo.txt
connected to : 127.0.0.1
done write to : foo.txt
$ cat foo.txt
Hello World

上面的例子中,使用了mongofiles的3个基本操作:put、list和get。put将文件系统中的一个文件添加到GridFS中,list会把所有添加到GridFS中的文件列出来,get是put的逆操作,它将GridFS中的文件写入到文件系统中。mongofiles还支持另外两个操作:search用来按文件名查找GridFS中的文件。delete则从GridFS中删除一个文件。

GridFS是建立在普通MongoDB文档基础上的轻量级文件存储规范。所有相关工作都有客户端驱动或工具完成。GridFS的一个基本思想就是可以将大文件分成很多块,每块作为一个单独的文档存储。因为MongoDB支持在文档中存储二进制数据,可以最大限度的减小块的存储开销。除了存储文件本身的块,还有一个单独的文档用来存储分块的信息和文件的元数据。GridFS的块有个单独的集合。默认情况下,块将使用fs.chunks集合。这个块集合里面文档的结构是非常简单的:
{
    "_id" : ObjectId("..."),
    "n" : 0,             //这个块在原文件中的顺序编号
    "data" : BinData("..."),   //包含组成文件块的二进制数据
    "files_id" : ObjectId("...")  //包含这个块元素的文件文档的_id
}
文件的元数据放在另一个集合中,默认是fs.files。这里面每个文档代表了GridFS中的一个文件,与文件相关的自定义元数据也可以存在其中。除用户自定义的键,GridFS规范还定义了一些键:
_id :        文件的唯一id。在块中作为files_id键的值存储
length :     文件内容总的字节数
chunkSize :  每块的大小,以字节为单位。默认是256K
uploadDate : 文件存入GridFS的时间戳
md5 :         文件内容的md5校验和,有服务器端生成(用户可以校验md5键的值确保文件正确上传)

在服务器端可以通过db.eval函数执行js脚本,也可把js脚本保存在数据库中,然后在别的数据库命令中调用。
db.eval可以在MongoDB的服务器端执行任意的js脚本。这个函数先将给定的js字符串传送给MongoDB,然后返回结果。db.eval可以用来模拟多文档事务:db.eval锁住数据库,然后在执行js,再解锁。虽没有内置的回滚机制,但这的确能保证一系列操作按照指定顺序发生。发送代码有两种选择,或封装进一个函数,或不封装。
db.eval("return 1;")
等价于:db.eval("function(){ return 1 ;}")
只有传递参数的时候。才必须要封装成一个函数。参数通过db.eval的第二个参数传递,要写成一个数组的形式。
db.eval("function(u) { print ('Hello, ' +u+ '!');}",[username])

每个MongoDB的数据库库都有个特殊的集合,叫做system.js,用来存放js变量。这些变量可以在任何MongoDB的js上下文中调用,包括"$where"子句,db.eval调用和MapReduce作业。
db.system.js.insert({"_id" : "x", "value" : 1})
db.system.js.insert({"_id" : "y", "value" : 2})
db.system.js.insert({"_id" : "z", "value" : 3})

db.eval("return x+y+z ;")

安全性:
func = "function() { print('Hello,"+username+" ! ');}"
恶意注入式攻击
username = "'); db.dropDataBase();print ('"
//output
func = "function() {print('Hello,'); db.dropDatabase(); print('!');}"
因此为了避免这种情况,要限定作用域
$func = new MongoCode("function() { print('Hello,'"+username+"!');}",...array("username" => $username));

数据库引用(DBRef)像一个URL,唯一确定一个到文档的引用。它自动加载文档的方式正如网站中URL通过链接自动加载Web页面一样。
DBRef是个内嵌文档,但有些必须键。
{"$ref" : collection, "$id" : id_value}
DBRef指向一个集合。还有一个id_value用来在集合里面根据_id确定唯一的文档。这两条信息使得DBRef能唯一标识MongoDB数据库内的任何一个文档。若要引用另一个数据库中的文档,DBRef中有个可选键"$db"
{"ref" : collection, "$id" : id_value, "$db" : database}  //顺序不能改变

users文档
{"_id" : "mike" "display_name" : "Mike D"}
{"_id" : "Kristina" "display_name" : "Cristina C"}
notes文档
{"_id" : 5, "author" : "mike", "text" : "MongoDB is fun!"}
{"_id" : 25, "author" : "kristina", "text" : " and DBRef are easy, too ", "references" : [{"$ref" : "users", "$id" : "mike" },{"$ref" : "notes", "$id" : 5}]}

var note = db.notes.findOne({"_id" : 20});
note,references.forEach(function(ref){
     printjson(db[ref.$ref].findOne({"_id" : ref.$id}));})
//output
{"_id" : "mike" "display_name" : "Mike D"}
{"_id" : 5, "author" : "mike", "text" : "MongoDB is fun!"}

MongoDB支持从文件获取配置信息。当需要的配置非常多或要自动化MongoDB的启动时就会用到这个。指定配置文件可以用-f或--config选项。
mogod --config ~/.mongodb.conf

让MongoDB停下来的最基本方法是向MongoDB服务器发送一个SIGNT或SIGTERM信号。若服务器是作为前台进程运行在终端,就直接Ctrl C,否则就用kill这种命令发出信号。若mongod的PID是10014,则kill -2 10014  或  kill 10014。另一种稳妥的方式就是使用shutdown命令,这是管理员命令,再要admin数据库下使用。
use admin
//itched to db admin
db.shutdownServer
//server should be down
切记 不要向运行中的MongoDB发送SIGKILL,这会导致数据库直接关闭,不会等当前运行的操作或文件与分配完成,会是数据库文件损坏。要是真的发生不幸,一定要在启动备份前修复数据库。

默认情况下,启动mongod时还会启动一个基本的HTTP服务器,该服务器监听的窗口号比主服务的端口号大1000.这个服务提供了Http接口,可以查看MongoDB的一些基本信息。

要获取运行中的MongoDB服务器统计信息,最基本的工具就是serverStatus命令。

mongostat输出一些serverStatus提供的重要信息。它会每秒钟输出新的一行。

向MongoDB添加管理员
db.addUser("root", "abc", "true" );   //将第三个参数设为true后即可,该数据库变为只读。

--auth 开启安全检查

数据库的用户帐号以文档的形式存储在syste.users集合里面。文档的结构是{"user" : username, "readOnly" : true, "pwd" : password hash}  // password hash是根据用户名和密码生成的散列。

MongoDB将所有数据都存放在数据目录下。默认目录是/data/db。若想要备份MongoDB,只要简单创建数据库目录中所有文件的副本就可以了。在运行MongoDB时复制数据目录不太安全,所以要把服务器关了在再复制数据库。

mongodump是一种能在运行时备份的方法。mongodump对运行的MongoDB做查询,然后将所有查到的文档写入到磁盘。

mongorestore获取mongodump的输出结果,并将备份的数据插入到运行的MongoDB实例中。
$ ./mongodump -d test -o backup
connected to :127.0.0.1
DATABASE : test to  backuo/test
   test.x to backup/text/x.bson
        1 objects
$ ./mongorestore -d foo --drop backuo.test/
connected to : 127.0.0.1 
backuo/test/x.bson
      going into namespace [foo.x]
      1 objects

MongoDB的fsync命令能在MongoDB运行时复制数据目录还不会损坏数据。fsync命令会强制服务器将所有缓存区写入磁盘。还可以选择上锁阻止对数据库的进一步写入,直到释放锁为止。
use admin
db.runCommad({"fsync" : 1, "lock" : 1});   //上锁
db.$cmd.sys.unlock.findOne();   //解锁
db.currentOp();   //确保已经解锁

在从服务器上备份是MongoDB推荐的备份方式。

修复所有数据库的方式是  --repair : mongod --repair来启动服务器。修复数据库的实际过程实际上非常简单:将所有的文档导出然后马上导入、忽略那些无效的文档。完成以后,会重新建立索引。
修复运行中的服务器上的数据库,要在shell中用repairDatabase。
use test
db.repairDatebase

主从复制是MongoDB最常用的复制方式。最基本的设置方式是建立一个主节点和一个或多个从节点,每个从节点要知道主节点的地址。运行mongod --master就启动了主服务器。运行mongod --slave  --source master_address(主节点地址)则启动了从服务器。
主从复制的一些有用的选项:
--only           在从节点上指定只复制特定某个数据库
--slavedelay     在从节点上,当应用主节点的操作时增加延时  
--fastsync       以主节点的数据快照为基础启动从节点。
--autoresync     若从节点与主节点不同步了,则自动更新同步
--oplogSize      主节点iplog的大小

启动从节点时可以用--source指定主节点。若主节点绑定了localhost:27017,启动从节点时可以不添加源,而是随后向source集合添加主节点信息。
$ ./mongod --slave --dbpaht ~/dbs/slave --port 27018
也可以在shell中运行命令
use local
db.sources.insert({"host" : "localhost : 27017"})
db.sources.remove({"host" : "localhost : 27017"})

副本集(Replica Set)有自动故障恢复功能的主从集群。主从集群和副本集最为明显的区别是副本集没有固定的"主节点":整个集群会选举出一个“主节点”,当其不能工作时则变更到其他节点。副本集总会有一个活跃节点(primary)和一个或多个备份节点(secondary)。

设置副本集

不能使用localhost地址作为成员,所以得找到机器的主机名。
两个服务器的情况下:
为每个服务器创建数据目录,选择端口
$ mkdir -p ~/dbs/nodel ~/dbs/node2  //之后要启服
$ ./mongod --dbpath !/db/node1 --port 10001 --replSet blort/morton:10002     //replSet的作用是让服务器知晓在这个blort副本集中还有别的同伴  位置在morton:10002    之后要启服
$ ./mongod --dbpath ~/dbs/node2 --port 10002 --replSet blort/morton:10001
若想添加第三台服务器,则
$ ./mongod --dbpath ~/dbs/node3 --port 10003 --replSet blort/morton:10001
等价于: $ ./mongod --dbpath ~/dbs/node3 --port 10003 --replSet blort/morton:10001,morton : 10002
在shell中初始化副本集
$ ./mongo morton : 10001/admin
db.runCommand({"relSetInitiate" : {
    "_id" : "blort",
    "members" :[
        { 
           "_id" : 1,
           "host" : "morton : 10001"
         },{ 
           "_id" : 2,
           "host" : "morton : 10002"
         },{ 
           "_id" : 3,
           "host" : "morton : 10003"
         }
    ]
  }
})
//output
{
   "info" : "Config now saved locally. Shoule come online in about a minute."
    "ok" :true
}

副本集中的节点:任何时间里,集群只有一个活跃节点,其他的都为备份节点。有几种不同类型的节点可以存在于副本集中:
standard:常规节点。它存储一份完整的数据副本,参与选举投票,有可能成为活跃节点
passive:存储了完整的数据副本,参与投票,不能成为活跃节点
arbiter:仲裁者只参与投票,不接收复制的数据,也不能成为活跃节点
标准节点和被动节点之间的区别仅仅是数量的差别:每个参与节点有个优先权。优先权为0则是被动的,不能成为活跃节点。优先值部位0,则按照由大到小选出活跃节点,优先值一样的化则看谁的数据比较新。默认优先级为1,可以是0~1000。
members.push({
   "_id" : 4,
   "host" : "morton : 10004",
   "priority" : 40 ,     //设置优先级
   "arbiterOnly" : true  //是否为仲裁节点
})

备份节点会从活跃节点抽取oplog,并执行操作。活跃节点也会写操作到自己的本地oplog,这样就成活跃节点了。

活跃节点使用心跳来跟踪集群中有多少节点对其可见。若不够半数,活跃节点会自动降为备份节点。不论活跃节点何时变化,新活跃节点的数据都被假定为系统的最新数据。对其他节点的操作都会回滚,即便是之前的活跃节点已恢复工作。为了完成回滚,所有节点链接新的活跃节点后要更新同步。这些节点会查看自己的oplog,找出其中活跃节点没有执行过的操作,然后向活跃节点请求这些操作影响文档的最新副本。正在执行重新同步的节点被视为恢复中,在完成这个过程之前不能成为活跃节点候选者。

用MongoDB扩展读取的一种方式就是将查询放在从节点上。扩展读取本身很简单:像以往一样设置主从复制,连接从服务器处理请求。唯一的技巧就是 有个特殊的查询选项,告诉从服务器是够可以处理请求。这个选项叫做slaveOkay。
从节点的另外一个用途就是作为一种机制来减轻密集型处理的负载,或作为聚合,避免影响主节点的性能。用--master参数启动一个普通的从节点。同时使用--slave和--master有点矛盾。

MongoDB的复制至少需要两个服务器或者节点。其中一个是主节点,负责处理客户端请求,其他的都是从节点,负责映射主节点的数据。主节点记录在骑上执行的所有操作。从节点定期轮询主节点获得这些操作,然后对自己的数据副本执行这些操作。由于和主节点执行了相同的操作,主从节点就能保持与主节点的数据同步。

主节点的操作记录成为oplog(operation log的简写)。oplog存储在一个特殊的数据库中,叫做local。oplog就在其中的oplog.$main集合里面。oplog中的每个文档都代表主节点上执行一个操作。文档包含的键如下:
ts : 操作的时间戳。时间戳是一种内部类型,用于跟踪操作执行的事件。由4字节的时间戳和4字节的递增计数器构成。
op : 操作类型,只有1字节代码
ns : 执行操作的命名空间
o :  进一步制定要执行的操作文档。对插入来说,就是要插入的文档。
oplog只记录改变数据库状态的操作。

同步:从节点第一次启动时,会对主节点数据进行完整的同步。从节点复制主节点上的每个文档,耗费的资源可想而知。同步完成后,从节点开始查询主节点的oplog并执行这些操作,以保证数据是最新的。若从节点的操作已经被主节点落下很远了,从节点就跟不上同步了。跟不上同步的从节点无法一直不断的追赶主节点,因为主节点oplog的所有操作都太“新”了。从节点发生了宕机或疲于应付读取时就会出现这种情况。也会在执行完完整同步以后发生类似的事,因为只要同步时间太长,同步完成时,oplog就可能已经滚一圈了。
从节点跟不上同步时,复制就会停下来,从节点需要重新做完整的同步。可以用{"resync" : 1 }命令手动执行重新同步,也可以在启动从节点时使用--autoresync选项让其自动重新同步。为了避免从节点跟不上,一定要确保主节点的oplog足够大,能存放相当长时间的操作记录。

本地数据库用来存放所有内部复制状态,主节点和从节点都有。本地数据库的名字就是local,其内容不会被复制。

主节点和从节点都跟踪从节点的更新状况,这是通过存放在"syncedTo"中的时间戳来完成的。每次从节点查询主节点的oplog时,都会用"syncedTo"来确定那些操作需要执行,或者查看是否已经跟不上同步了。


开发者可以用getLastError的'w'参数来确保数据的同步性。这里运行getLastError会进入阻塞状态,知道N个服务器复制了最新的写入操作为止。
db.runCommand({getLastError : 1, w : N });

db.printReplicationInfo()可以看到oplog的大小和oplog中操作的时间范围。
db.printReplicationInfo();
//output
configured oplog size : 10.45MB
log length start to end : 34secs
oplog first event time :               
oplog laser evebt time :
now :
oplog的长度至少要能满足一次完成的重新同步。
日志的长度是通过oplog中最早的操作事件和最后的操作事件的差值得到的。

db.printSlaveReplicationInfo()可以显示从节点的数据源列表,其中有数据滞后时间。
db.printSlaveReplicationInfo();
//output
source : localhost : 27017
syncedTo :                    = 12 secs ago  //数据滞后时间

若发现oplog大小不合适,最简单的做法就是停掉主节点,删除local数据库的文件,用新的设置重新启动。
$ rm/data/db/local.*
$ ./mongod --master --oplogSize size
size is specified in megabytes

重启主节点之后,所有从节点得用--autoresync重启,否则需要手动重新同步。

若在复制的过程中使用了认证,还需要做些配置,是的主从节点能够访问主节点的数据。在主节点和从节点上都需要在本地数据库添加用户,每个节点的用户名和口令都是相同的。

分片是MongoDB的扩展方式,通过分片能够增加更多的机器来应对不断增加的负载和数据。分片(sharding)是指将数据拆分,将其分散存在不同的机器上的过程。有时也用分区(partitioning)来表示这个概念。

MongoDB分片的基本思想就是将集合切分成小块。这些块分散到若干片里面,每个片只负责总数居的一部分。在分片之前要运行一个路由进程,该进程名为mongos。这个路由器知道所有数据的存放位置,所以应用可以连接他来正常发送请求。

在以下几种情形下开始使用分片:
机器的磁盘不够用了
单个mongod已经不能满足写数据的性能需要了
想将大量数据放在内存中提高性能

设置分片时,需要从结合里面选一个键,用该键的值作为数据拆分的依据。这个键称为片键(shard key)。当片键建好并运行后,MongoDB就会把集合拆分成两半,成为块。每个块中包括片键值在一定范围内的所有文档。片键的选择决定了插入操作在片之间的分布。

分片一般会有3个组成部分:
片  就是保存子集合数据的容器。片可是单个mongod服务器,也可以是副本集。
mongos  就是MongoDB各版本中都匹配的路由器进程。它路由所有请求,然后将结果聚合。
配置服务器  存储了集群的配置信息:数据和片的对应关系。mongos不永久存放数据。

启动mongos
$ mkdir -p ~/dbs/config
$ ./mongod --dbpath ~/dbs/config --port 20000
建立mongos进程,以供应应用程序连接。
$ ./mongos --port 30000 --configdb localhost:20000
添加片
$ mkdir -p ~/dbs/shard1
$ ./mongod --dbpath ~/dbs/shard1 --port 10000
启动mongos,为集群添加一个片
$ ./mongo localhost:30000/admin
//output
MongoDB shell version : 1.6.0
url : localhost:30000/admin
connecting to localhost:30000/admin
type "help" for help

db.runCommand({addshard  : "localhost:10000",allowLocal : true})
//output
{
    "added" : "localhost:10000",
    "ok" : true
}

开启foo的分片功能:
db.runCommand({"enablesharding" : "foo"})
对集合进行分片
db.runCommand({"shardcollection" : "foo.bar", "key" : {"_id" : 1}})

配置多个服务器
$ mkdir -p ~/dbs/config1 ~/dbs/config2 ~/dbs/config3
$ ./mongod --dbpath ~/dbs/config1 --port 20001
$ ./mongod --dbpath ~/dbs/config2 --port 20002
$ ./mongod --dbpath ~/dbs/config3 --port 20003
$ ./mongos --confidb localhost : 20001, localhost : 20002, localhost : 20003

在生产环境中,每个片都应是副本集。
db.runCommand({"addshard" : "foo/prod.example/com:27017"})

查找所有的片
db.shared.find();

db.printShardingStatus()

db.runCommand({"removedshard" : "localhost : 10000" })

MongoDB权威指南看完了,感觉看的快,忘得也快。看的都是理论上的东西,感觉懵懵懂懂的,还没有实践。回去要做几个例子才行。不过Maven还没有看,think in java也没有看,Hibernate还没有看完,还有Spring想要深入了解一下...我的任务有点多啊..唯一不忙的就是工作..倒是很希望工作可以忙起来,这样学的会更快、更多。继续加油吧!
分享到:
评论

相关推荐

    mongodb_java_2.6_API

    MongoDB是一款分布式文档数据库系统,以其灵活性、高性能和易扩展性而受到开发者的广泛欢迎。在Java编程环境中,与MongoDB交互主要通过其提供的Java驱动程序。本篇将深入探讨"mongodb_java_2.6_API",即MongoDB 2.6...

    MongoDB权威指南中文版.pdf

    由于提供的文件内容中存在大量重复内容,并且没有具体的章节段落,因此无法直接生成详细知识点。...如果需要对MongoDB有更全面的了解,推荐查找该权威指南的完整版电子书籍或其他专业资源进行学习。

    navicat121_mongodb_cs_x64+navicat121_mongodb_cs_x86.rar

    标题中的"navicat121_mongodb_cs_x64+navicat121_mongodb_cs_x86.rar"指示了这是一个包含两个版本的Navicat for MongoDB安装程序的压缩包,一个是针对64位操作系统(x64),另一个是针对32位操作系统(x86)。...

    navicat121_mongodb_en_x64.exe

    可视化工具mongodb操作简单,可视化强 欢迎大家下载

    navicat150_mongodb_cs_x64.exe

    navicat可以连接MongoDB数据库,也可以连接oracle和mysql等其他的数据库,挺好用的

    MongoDB权威指南 中文版高清PDF

    《MongoDB权威指南》是一本深入解析该技术的专业书籍,旨在帮助读者全面理解和掌握MongoDB的使用。 本书首先从数据库的基础概念入手,介绍了NoSQL数据库与传统关系型数据库的区别,阐述了MongoDB作为文档数据库的...

    MongoDB权威指南.pdf

    英文版:MongoDB: The Definitive Guide内容简介《MongoDB权威指南》是一本广受好评的MongoDB方面的图书。与传统的关系型数据库不同,MongoDB是一种面向文档的数据库。书中介绍了面向文档的存储方式及利用MongoDB的...

    MongoDB权威指南(中英文两版)

    "MongoDB权威指南"是学习和深入理解这一技术的重要参考资料,提供了全面的理论知识和实践经验。本书分为中文版和英文版,适合不同语言背景的读者,帮助他们掌握MongoDB的核心概念和操作技巧。 在中文版的《MongoDB...

    mongodb学习笔记和mongodb权威指南

    这份压缩包文件包含了关于MongoDB的全面学习资源,包括与Python集成的实践、权威指南、学习手册以及综合总结,旨在帮助用户深入理解和掌握这个数据库系统。 首先,`mongodb_and_python`学习笔记可能涵盖了如何使用...

    MongoDB 权威指南.pdf

    ### MongoDB权威指南知识点详解 #### 一、MongoDB概述 MongoDB是一款开源的NoSQL数据库系统,采用BSON(Binary JSON)格式存储文档数据。它支持动态查询、高可用性及横向扩展等特性,适用于大数据量的应用场景。...

    MongoDB权威指南中文版高清版带书签PDF

    在《MongoDB权威指南》这本书中,作者详细地介绍了MongoDB的基础知识、安装配置、数据模型、查询语言、操作管理以及高级特性。以下是对这本书中核心知识点的概述: 1. **MongoDB基础知识**:MongoDB是NoSQL数据库的...

    MongoDB_Architecture_Guide

    MongoDB架构指南包含了关于MongoDB数据库系统的内部架构设计、运作原理和管理实践的深入介绍。本文档的结构主要分为以下几个部分: 1. 引言(Introduction) 文档的引言部分概述了MongoDB的开发背景,强调了它不是...

    MongoDB权威指南 第二版中文 mobi

    MongoDB权威指南 第二版中文 mobi

    MongoDB权威指南中文版

    《MongoDB权威指南中文版》第1章 简介 第2章 入门 第3章 创建、更新及删除文档 第4章 查询 第5章 索引 第6章 聚合 第7章 进阶指南 第8章 管理 第9章 复制 第10章 分片 第11章 应用举例 附录A 安装MongoDB 附录B ...

    MongoDB权威指南(中文版)

    《MongoDB权威指南》是一本全面深入探讨MongoDB数据库系统的专著,中文版的发布使得国内用户能够更方便地学习和理解这一强大的NoSQL数据库。MongoDB作为一种分布式文档型数据库,近年来在处理大规模数据存储和高并发...

Global site tag (gtag.js) - Google Analytics