在工作之余接触到了noSql NoSQL数据库的出现,弥补了关系型数据库在某些方面的不足,但从功能上讲,NoSQL的几乎所有功能,在关系数据库上都能满足,所以,选择NoSQL的原因并不在功能上,而是二者都有各自的特点和应用场景,两者的紧密结合将会给web2.0的数据库发展带来新的思路,让关系型数据库关注在关系上,非关系型数据关注在存储上。
mongoDB是一个开源的,基于分布式的,面向文档存储的非关系型数据库。是非关系型数据库当中功能最丰富、最像关系数据库的。
mongoDB由C++编写,其名字来源于"humongous"这个单词,其宗旨在于处理大量数据。
mongoDB可以运行在Windows、unix、OSX、Solaris系统上,支持32位和64位应用,提供多种编程语言的驱动程序。
mongoDB支持的数据结构非常松散,是类似json的BSON格式,通过键值对的形式存储数据,可以存储复杂的数据类型。
mongoDB支持的数据类型有:null、boolean、String、objectId、32位整数、64位整数、64位浮点数、日期、正则表达式、js代码、二进制数据、数组、内嵌文档、最大值、最小值、未定义类型。
其中,内嵌文档我理解的并不是.doc.txt等文件,这里所指的文档是mongoDB的一个存储单元(相当于关系型数据当中的记录),在mongoDB中的表现形式为{key1:value1,key2:value2},而内嵌文档则是这样的形式{key1:value1,key2:{key2.1:value2.1,key2.2:value2.2}}。
mongoDB最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
一、开发工具
1.安装文件:
http://pan.baidu.com/s/1pKN1Ux9 linux x86版本
http://pan.baidu.com/s/1nuQTKox ; window x86版本
2.开发教程
http://pan.baidu.com/s/1i5x5Whf ; MongoDB权威指南(第2版)
http://pan.baidu.com/s/1qXLxWDY ; 深入云计算MongoDB管理与实践
二、mongoDB的特性:
1. 面向集合存储。数据被分组到若干集合,每个集合可以包含无限个文档,可以将集合想象成RDBMS的表,区别是集合不需要进行模式定义。
2. 模式自由。集合中没有行和列的概念,每个文档可以有不同的key,key的值不要求一致的数据类型。
3. 支持动态查询。mongoDB支持丰富的查询表达式,查询指令使用json形式表达式。
4. 完整的索引支持。mongoDB的查询优化器会分析查询表达式,并生成一个高效的查询计划。
5. 高效的数据存储,支持二进制数据及大型对象(图片、视频等)。
6. 支持复制和故障恢复。
7. 自动分片以支持云级别的伸缩性,支持水平的数据库集群,可动态添加额外的服务器。
三、学习技能笔记(个人笔记、勿喷)
- mongod.exe --dbpath c:\data\db 启动服务器
2.show dbs 查看数据库(空的数据库是不会显示的)
3.mongodb://admin:123456@localhost/test 链接到用户名为 admin 密码为123456 端口默认的 test数据库
4.use test 使用test数据库(test如果不存在则会新建 test 并且应该向里面插入数据 )
- db 查看当前所链接的数据库名称
6.db.test1.insert({“name”:“菜鸟教程”}) //向test数据库里面插入集合 test1
7.db.test1.find() db.test.find().pretty()(结构化查询显示) 查看test1集合(数据)
8.show collections; 显示查看数据库下面的collection的名称
9.db.test1.drop() 删除集合test1
10.use test->db.dropDatabase 删除test数据库
11.db.dropDatabase() 删除集合
12.db.col.insert(document) 插入文档 (document 为对象文档)
13.db.col.update({‘title’:‘MongoDB 教程’},{$set:{‘title’:‘MongoDB’}}) 将col集合的title 改成MongoDB
14.db.col.save({document}) 替换掉col的数据为document
15.db.collection.update( criteria, objNew, upsert, multi )
criteria : update的查询条件,类似sql update查询内where后面的
objNew : update的对象和一些更新的操作符(如 , , ,inc…)等,也可以理解为sql update查询内set后面的
upsert : 这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
multi : mongodb默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
例子:db.test0.update( { “count” : { $gt : 10 } } , { $inc : { “count” : 1} },false,false );只更新了第一条
“ g t " 、 " gt" 、" gt"、"gte”、 “ l t " 、 " lt"、 " lt"、"lte”、"$ne"(分别对应">"、 “>=” 、"<" 、"<="、"!="),
16.db.collection.remove(,,)
query :(可选)删除的文档的条件。
justOne : (可选)如果设为 true 或 1,则只删除一个文档。
writeConcern :(可选)抛出异常的级别。
例子:db.col.remove({'title':'MongoDB 教程'}) 删除title为‘'MongoDB 教程’ 的文档
db.col.remove({}) 删除所以的额文档
-
db.col.find({key1:value1, key2:value2}).pretty()查询
-
条件查询例子
等于 {:} db.col.find({“by”:“菜鸟教程”}).pretty() where by = ‘菜鸟教程’
小于 {:{KaTeX parse error: Expected 'EOF', got '}' at position 11: lt:<value>}̲} db.col.find({…lt:50}}).pretty() where likes < 50
小于或等于 {:{KaTeX parse error: Expected 'EOF', got '}' at position 12: lte:<value>}̲} db.col.find({…lte:50}}).pretty() where likes <= 50
大于 {:{KaTeX parse error: Expected 'EOF', got '}' at position 11: gt:<value>}̲} db.col.find({…gt:50}}).pretty() where likes > 50
大于或等于 {:{KaTeX parse error: Expected 'EOF', got '}' at position 12: gte:<value>}̲} db.col.find({…gte:50}}).pretty() where likes >= 50
不等于 {:{KaTeX parse error: Expected 'EOF', got '}' at position 11: ne:<value>}̲} db.col.find({…ne:50}}).pretty() where likes != 50
19.db.col.find({“by”:“菜鸟教程”, “title”:“MongoDB 教程”}).pretty() 查询 by=“菜鸟教程” and title =“title”:“MongoDB 教程” 的数据
20.db.col.find({$or:[{“by”:“菜鸟教程”},{“title”: “MongoDB 教程”}]}).pretty() 查询键 by 值为 菜鸟教程 或键 title 值为 MongoDB 教程 的文档。
21.db.col.find().limit(2) 查询前两条
22.db.col.find().sort({“age”:-1}) 按照age -1降序排列 1升序
23.db.col.find({},{“name”:1,"_id":0}).sort({“age”:1}) 按照age的升序查询name “name”:1 表示显示 _id:0表示不显示 _id
24.db.mycol.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: …roup : {_id : "by_user", num_tutorial : {$sum : 1}}}]) 按照by_user分组,并计算每组的个数
25.管道操作
$project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
m a t c h : 用 于 过 滤 数 据 , 只 输 出 符 合 条 件 的 文 档 。 match:用于过滤数据,只输出符合条件的文档。 match:用于过滤数据,只输出符合条件的文档。match使用MongoDB的标准查询操作。
$limit:用来限制MongoDB聚合管道返回的文档数。
$skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
$unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
$group:将集合中的文档分组,可用于统计结果。
$sort:将输入文档排序后输出。
$geoNear:输出接近某一地理位置的有序文档。
26.mongodb复制原理:mongodb的复制至少需要两个节点。其中一个是主节点,负责处理客户端请求,其余的都是从节点,负责复制主节点上的数据。
mongodb各个节点常见的搭配方式为:一主一从、一主多从。
主节点记录在其上的所有操作oplog,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致
27.mongodump -h 127.0.0.1:27017 -d col -o e:\cao 将本地27017的的col备份到E:\cao 中
28.mongorestore -h 127.0.0.1:27017 -d col --directoryperdb e:\cao 将e:\cao里面的数据恢复到啊27017里面(先删除本来的数据然后复制)
29.KaTeX parse error: Expected '}', got 'EOF' at end of input: …e":"col"},...{"inc":{“age”:-1}}) age减一 (不能用于非数字的值) 使用修改器的时候_id的值不能变,替换的时候什么都可以变 ,原地修改不会修改文档的大小
30.KaTeX parse error: Expected '}', got 'EOF' at end of input: …title":"hao"},{push:{“commects”:{"$each":{},{}}}}) 向title为hao的文档的commects中添加两个元素 each 指随便插入多少个都可以的 会修改文档的大小
31.将文档插入到MongoDB中时,依次插入的文档在磁盘上的位置是相邻的,因此,如果某个文档变大了,原先的位置就不能放下这个文档,则会被移到其他的位置
32.upsert 一种特殊的更新,如果没有找到符合条件的文档,就以这个条件和更新文档为基础创建一个新的文档,如果匹配到了文档,就正常更新
33.save 如果文档不存在则自动创建文档,如果存在就更细文档 例子:var x=db.coll.findOne();x.num=100;db.coll.save(x) 把num=42 添加到原来的coll中
34.KaTeX parse error: Expected '}', got 'EOF' at end of input: …find({"name":{"in":[“a”,“b”]})查询col集合中 name为 a 或者b的文档 n i n 和 nin和 nin和in相反
35.KaTeX parse error: Expected '}', got 'EOF' at end of input: … db.col.find({"or":[{“name”:“a”},{“age”:10}]) 查询col中name=a或者age=10的文档
36.$not 不满足
37.null 不仅会匹配某个键值为null的文档,还会匹配不包含这个见的文档 解决办法:db.col.find({“z”:{“ i n " : [ n u l l ] , " in":[null]," in":[null],"exists”:true}})
38.KaTeX parse error: Expected '}', got 'EOF' at end of input: …l.find({fruit:{all:[“a”,“b”]}})查询col中的数组fruit中有a和b的文档
db.col.find({"fruit.2":"a"})查询col中数组fruit的第三项为a的文档
39.KaTeX parse error: Expected '}', got 'EOF' at end of input: …ind({"fruit":{"size":3}})查询col集合中数组fruit长度为3的文档
40.KaTeX parse error: Expected '}', got 'EOF' at end of input: …,{"commects":{"clice":[23,10]}})返回col集合中comments数组从23个元素开始的10个元素
41.KaTeX parse error: Expected '}', got 'EOF' at end of input: … db.food.find({where:“this.spinach=this.watermelon”}) 查询food集合中spinach=watermelon的文档
42.db.runCommand({“drop”:“coll”}) 数据库命令 : 删除coll数据库
43.db.col.ensureIndex({“username”:1}) 给username字段上创建一个索引:添加每一个索引,写入的操作时间将加长,因为当数据发生变动的时候,mongodb不仅要更新文档,还要更新集合上的索引。每个集合最多使用64个索引
44.索引使用原则:提取较小的子数据集合时,索引效率高,结果集在原集合中所占的比例越大是,索引的速度越慢,因为使用索引需要进行两次查找:一是查找索引条目,二是根据索引指针去查找相应的文档。而全表扫描只需要进行一次查找;
45.唯一索引:集合的每一个文档的指定键都有唯一值 例如 为username创建唯一索引:db.users.ensureIndex({“username”:1},{“unique”:true}) 注意:唯一索引会把null看作值
- 标识索引:索引名称,用于唯一标识这个索引;
47.修改索引:db.user.dropIndex(“X_1_y_1”)
48.固定集合:有固定的空间大小,不能被分片,当集合空间已满的时候新插入文档是会将最老的文档删除以释放空间
49.db.createCollection(“guding”,{“capped”:true,“size”:10000,“max”:100})创建一个名字为guding的大小10000的文档数量为100的固定文档
db.runCommand({“converToCapped”:“test”,“size”:1000})将test集合转换为一个大小为10000字节的固定集合
50.复制操作要求每个集合上都有”_id“ ,createCollection 创建集合的时候制定autoIndexId为false
51.TTL索引:为每个文档设置一个超时时间,到达时间后,就会被删除。例子:db.foo.ensureIndex({“lasupdate”:1},{“expireAfterSecs”:606024})设置一个lasupdate的TTL索引,时间为24小时,到时间后就会删除文档
52.GridFs文件管理器
mongofiles put foo.txt 上传文件foo.txt到GridFS
mongofiles list 列出GridFS中的文件
mongofiles get foo.txt 下载GridFs中的文件到文件系统
53.GridFs可以将大文件分割为多个比较大的块,将每个块独立的文档进行储存,块会被储存到专用的集合中,块默认的集合石fs.chunks
文档集合实例:
{
“id”:ObjectId("…"),
“n”:0,块在文件中的相对位置
“data”:BinData("…"),块所包含的二进制书记
“files_id”:ObjectId("…")快所属文件元信息
}
54.聚合框架:对集合中的文档进行变换和组合,主要使用地方法为创建一个管道,用于对一连串的文档进行处理。
管道例子:
db.articles.aggregate({"$probject":{“author”:1}}, //将’author’从每个文档中投影出来
{“KaTeX parse error: Expected '}', got 'EOF' at end of input: group":{"_id":"author”,“count”:{"$sum":1}}},//按照’author’排序,某个’author’出现一次,就对这个’author’中的’count’加1
{"$sort":{“count”:-1}}, //按照 'count’降序排序
{"$limit":5})//返回前5个文档
55.$project
a.简单的表达式:最简单的’$project’表达式是包含和排除字段,以及字段名称
b.数学表达式:$add :[expr1,expr2,expr3] 接受一个或者多个表达式参数,将这个表达式相加
$subtract:[expr1,expr2] 接受两个表达式参数,用第一个表达式减去第二个表达式作为结果
$multiply:[expr1,expr2…] 接受多个表达式,将他们呢相乘,
$divide:[expr1,expr2] 接受两个表达式,用第一个表达式除以第二个表达式的商作为结果
$mod:[expr1,expr2]接受两个表达式,将第一个表达式除以第二个表达式得到的余数作为结果
例子 db.col.aggregate({“KaTeX parse error: Expected '}', got 'EOF' at end of input: project":{"totalPay”:{“KaTeX parse error: Expected '}', got 'EOF' at end of input: subtract":[{"add”:[“ s a l a r y " , " salary"," salary","bonus”]},"$401k"]}}})在 totalPay 中减去 salary+bonus
c.日期表达式 y e a r , year, year,month, w e e k , week, week,dayOfMonth, d a y O f W e e k , dayOfWeek, dayOfWeek,dayOfYear, h o u r , hour, hour,minute,$second
例子 db.col.aggregate({“project”:{“hiredIn”:{“ m o n t h " : " month":" month":"hireDate”}}}) 计算col中hireDate的时间
db.col.aggregate({“project”:{“time”:{“KaTeX parse error: Expected '}', got 'EOF' at end of input: subtract":[{"year”:new Date()},{“ y e a r " : " year":" year":"hireDate”}]}}}) 计算时间差 time
b.字符串表达式 $substr:[expr1,startOffset,numToReturn] 截取字符串expr1 从startOffset开始的numToReturn个字节
$contcat:[expr1,expr2,…]将给定的表达式(字符串)链接在一起返回
$toLower:expr1 返回字符串expr1的小写
$toUpper:expir1 返回字符串expr1的大写
例子 db.col.aggregate({“KaTeX parse error: Expected '}', got 'EOF' at end of input: …roject":{"a":{"contcat”:[“ a g e " , " . . . . . " , " age","....."," age",".....","name”]}}}) 将col中的 a g e 和 age 和 age和name链接起来
e.逻辑表达式:$cmp:[expr1,expr2] 比较大小 expr1==expr2 0 expr1<expr2 返回负数 expr1>expr2 返回正数
$strcasecmp:[string1,string2] 比较string1和string2,区分大小写,只对罗马字符组成的字符串有效
e q , eq, eq,ne, g t , gt, gt,gte, l t , lt, lt,lte:[expr1,expr2] 对expr1和expr2执行相应比较的操作 返回true false
$and :[expr1,expr2…] 如果所有的表达式的值都是true 那就返回true 否则返回false
$or:[expr1,expr2] 如果任意一个表达式的值为true,就返回true 否则返回false
$not :expr 取反
$cond:[booleanExpr,trueExpr,falseExpr] 如果booleanExpr值是true 返回trueExpr,否则返回falseExpr
$ifNull:[expr,replacementExpr] 如果expr是null返回replacementExpr 否则返回expr
例子 db.students.aggregate(
{
“$project”:{
“grage”:{//成绩
“$cond”:[
" t e a c h e r s P e t " : 100 , / / 如 果 是 老 师 最 喜 欢 的 老 师 成 绩 为 100 即 teachersPet":100,//如果是老师最喜欢的老师 成绩为100 即 teachersPet":100,//如果是老师最喜欢的老师成绩为100即teachersPet true
{//否则
“$add”:[ //相加
{“ m u l t i p l y " : [ 0.1 , " multiply":[0.1," multiply":[0.1,"attendancAvg”]}, 出勤的 10%
{“ m u l t i p l y " : [ 0.3 , " multiply":[0.3," multiply":[0.3,"quizzAvg”]}, 平时成绩的 30%
{“ m u l t i p l y " : [ 0.6 , " multiply":[0.6," multiply":[0.6,"testAvg”]},期末考试的 60%
]
}
]
}
}
})
56.$group 将文档按照特定字段的不同值进行分组
a.分组操作符:允许对每个分组进行计算,得到相应的结果
b.算数操作符:
KaTeX parse error: Expected '}', got 'EOF' at end of input: …ol.aggregate({"group":{"_id":“KaTeX parse error: Expected '}', got 'EOF' at end of input: …otalRevenue":{"sum”:"$revenue"}}}) 计算每个国家的收入
KaTeX parse error: Expected '}', got 'EOF' at end of input: …ol.aggregate({"group":{"_id":“KaTeX parse error: Expected '}', got 'EOF' at end of input: …otalRevenue":{"avg”:“KaTeX parse error: Expected 'EOF', got '}' at position 9: revenue"}̲,"numSales":{"sum”:1}}}) 计算每个国家的平均收入 以及总销量
c.极值操作符:
$max:expr 计算分组内的最大值
$min:expr 计算分组内的最小值
$first:exp1 返回分组的第一个值,忽略后面所有的值 $last 反之
例子:db.col.aggregate(
{
“$sort”:{“score”:1} 按成绩分数升序排列
},
{
“$group”:{
“_id”:"$grade",根据成绩分组
“lowestScore”:{“ f i r s t " : " first":" first":"score”}, 选出分数最低的一个
“highestScore”:{“ l a s t " : " last":" last":"score”}选出分数最高的一个
}
})
e.数组操作符:
$addToSet:expr 如果当前数组不包含expr 那就将它添加到数组中,在返回结果集中,每个元素最多出现一次
$push:expr 不管expr是什么值,都将它添加到数组中
注意: g r o u p 必 须 等 收 到 的 所 有 文 档 以 后 , 才 能 对 文 档 进 行 分 组 , 然 后 才 能 将 各 个 分 组 发 送 给 管 道 中 的 下 一 个 操 作 符 , 所 以 group 必须等收到的所有文档以后,才能对文档进行分组,然后才能将各个分组发送给管道中的下一个操作符,所以 group必须等收到的所有文档以后,才能对文档进行分组,然后才能将各个分组发送给管道中的下一个操作符,所以gruop会现在每个分片上执行,然后各个分片的分组结果会被发送到mongos再进行最后的同意分组,剩余的管道工作也都是早mongos(而不是分片)上运行
57.$unwind 将数组中的每一个值拆分为单独的文档
例子:db.col.aggregate(
{“KaTeX parse error: Expected '}', got 'EOF' at end of input: …":{"comments":"comments”}},查询$comments
{“ u n w i n d " : " unwind":" unwind":"comments”},将$comments 进行分组获得子文档
{“KaTeX parse error: Expected '}', got 'EOF' at end of input: match":{"comments.author”:“Mark”}} 在子文档中找到author为 Mark 的文档
)
58.$sort 根据任何字段(或者多个字段)进行排序,在普通的查询中的语法相同。如果要对大量的文档进行排序,最好在管道的第一阶段进行排序
例子:db.col.aggregate(
{
“$project”:{
“compensation”:{//员工的报酬 compensation= s a l a r y + salary+ salary+bonus
“ a d d " : [ " add":[" add":["salary”,"$bonus"]
},
“name”:1 //显示姓名
}
},
{
“$sort”:{“compensation”:-1,“name”:1} 报酬降序排列,,姓名升序
})
注意: s o r t 和 sort和 sort和group一样,也是无法使用流式工作方式的操作符,也必须要接受到所有的文档后才能进行排序。在分片的环境下,先在各个分片上拍寻,然后再将各个分片的排序结果发送到mongos进一步处理
59.$limit 接受一个数字n,返回结果集中的前n个文档
60.$skip 接受一个数字n,丢弃结果集中的前n个文档
61.MapReduce 一种强大的聚合工具,可以在多台服务器上并行执行,将一个大的问题拆分为多个小问题,将各个小问题发送到不同的机器上,每台机器之负责完成一部分的工作,所有的机器都完成时,再将这些零碎的解决方案合并为一个完整的方案,
62.count是最简单的聚合工具 适用于返回集合众的文档数量 例子:db.foo.count() db.foo.count({“name”:“PHP”})返回foo集合中name=PHP的文档的数量
63.db.runCommand({“distinct”:“people”,“key”:“name”}) 找出people集合里面所有文档的不同name 去重
64.范式化与反范式化 :
范式化,将数据分散到多个不同的集合,不同的集合之间可以相互引用数据,虽然很多的文档可以引用么哦一块数据,但是这块数据只存储在一个集合中,修改数据的时候就只需修改保存这块的数据的文档就可以了。但是需要多次查询。 适合频繁更新数据的情况(引用数据)
反范式话:与范式话相反,是将每个文档所需的数据都嵌入在文档内部,每个文档都拥有自己的数据副本,而不是以文档共同引用同一个数据副本。所以信息发生变化,则所以的文档都需要进行更新,但是只需要一次查询就可以。 适合频繁读写数据的情况(内嵌数据)
65.内嵌数据和引用数据的比较:
更适合内嵌:子文档较小、数据不会定期改变、最终数据一致即可、文档数据小幅增加、数据通常需要执行二次查询才能获得、快速读取
更适合引用:子文档较大、数据经常改变、中介的数据必须一致、文档数据大幅增加、数据通常不包含在结果中、快速写入
66.基数:一个集合包含的对其他集合的引用数量较基数。
67.副本集:使用复制可以将数据副本保存到多台服务器上,,副本集是一组服务器,其中有一个主服务器,用于处理客户端请求,还有多个备份服务器,用于保存主服务器的数据副本,如果主服务器崩溃了,备份服务器会自动将一个成员升级为新的主服务器。
68.创建副本集:http://www.cnblogs.com/dennisit/archive/2013/01/28/2880166.html 教程
mongo --nodb 只打开mongo 而不链接集合
replicaSet=new ReplSetTest({“nodes”:3}) 创建一个包含三个服务器的副本集,一个主的 两个备份的(可叫节点,也可叫主从库)
replicaSet.startSet() 启动3个mongod进程
replicaSet.initiate() 配置复制功能
在创建完副本集后,登陆到相应的服务器后 ,,,shell 命令符发生变化:testReplSet(副本集标识):PRIMARY(当前状态为主) SECONDARY 为副
rs.isMaster()、re.status() 查看副本集状态 ismaster:true 说明本端口是主节点
rs.slaveOk()从库分担主库压力 给予数据读取的权利
rs.stopSet()关闭副本集
69.注意:a.客户端不能对备份节点(从库)执行写操作,备份节点只能通过复制功能写入数据,不接受客户端的写入请求(如果主节点挂了,其中一个副节点会被自动选为主节点)
b.客户端在单台服务器上可以执行的请求,都可以发送到主节点上执行(读、写、执行命令、创建索引等)
c.默认情况下,客户端不能从备份节点中读取数据。在备份节点上显示执行setSlaveOk之后,客户端就可以从备份节点读取数据
70.创建副本集过程 a. mongod --replSet fuben --dbpath e:\mongo\data1 --port 8888
mongod --replSet fuben --dbpath e:\mongo\data2 --port 8889
在两个服务器位置上创建同名的服务器
b.mongo --port 8888 登陆其中的一台服务器
c.config={
“_id”:“fuben”,//副本集名称 要和 创建的时候一至
“member”:[
{_id:0,“host”:“localhost:8888”,priority:1}, priority :1 设置成主节点
{_id:0,“host”:“localhost:8889”} 副节点(备份节点)
]
}
d.rs.initiate(config)初始化副本集
e.mongo --port 8889 登陆副节点服务器
f.rs.slaveOk() 允许副节点备份主节点的数据
71.网络连接注意事项:副本集内的每个成员都必须能链接到其他所有的成员(包括自身)另外副本级的配置中不应该使用localhost作为主机名,因为如果在多台机器上运行,localhost解析会出现异常,最好使用ip地址设置(尽管Mongodb允许副本集中所有的成员运行在同一台服务器上)
72.rs.add(“localhost:8887”) 给当前的副本集再加一个副的节点 localhost:8887 (mongod --replSet fuben --dbpath e:\mongo\data3 --port 8887)
rs.remove(“localhost:8887”)删除该成员
73.配置修改副本集:
var config=rs.config()
config.member[1].host=“localhost:8886” 修改副本集中的member[1]的节点的端口
rs.reconfig(config) 执行修改配置
注意要求:
a.不能修改成员的"_id“字段
b.不能将接受rs.reconfig命令的成员(通常是主节点)的优先级设为0
c.不能将仲裁者成员变成非仲裁成员,反之亦然
d.
73.rs.config() 用来查看配置是否修改成功 注意:重新配置副本集时,主节点先退化为普通的备份节点,以便接受新的配置,然后恢复,重新配置后,副本集中会暂时没有主节点,之后会恢复
74.选举:原则上MongoDB支持单一主节点(也可以设置多个主节点)当副本集被设置为只读时,将导致程序暂时无法写入数据,当一个备份节点无法与主节点联通时,它会联系并请求其他的副本集成员将自己选举为主节点。其他成员检查后(检测其数据是否为最新,有没有其他优先级更高的成员被选为主节点)即可将其设置为主节点,只要有一个成员否决,此次选举失败。选举过程中主节点额可能会暂时不可用,如果没有可达的成员能够成为主节点,主节点可能长时间不可用,这是驱动程序在这段时间内不会处理任何请求,但可以选择将请求路由到备份节点上
例子:该候选节点最后一个复制操作到123 如果它能联通的成员其中有一个最后复制操作到124 那么就被否决 这个候选节点会继续更新数据,等他复制到124的时候,它会重新发起请求
75.priority 优先级 :表示一个成员渴望成为主节点的成都 0-100 默认为1 0 表示永远不可能成为主节点
例子:rs.add({"_id":4,“host”:“localhost:8885”,“priority”:1.5}) 假设其他成员的优先级都是1,只要_id:4有最新的数据,那么当前的主节点就会自动退位,——id:4会被选为新的主节点(优先级只是相对优先级,无法一次reconfig操作中将当前主节点的优先级设为0 也不能对所有优先级为0的副本集执行reconfig)
76.隐藏成员:客户端不会想隐藏成员发送请求,隐藏成员也不会作为复制源,
例子:var config=rs.config() 获取副本集的配置信息
config.member[1].hidden=0 将第二个从节点设置为隐藏成员
rs.reconfig(config) 执行配置
77.db.serverCmdLineOpts()查看服务器命令行参数 在维护这台服务器的时候需要阻止其他的副本集链接到这台服务器,可以保持dbpath不变,然后直接重启 指向另一个端口 例如:本来该端口为8888 则在维护的时候 mongodb --port 30000 --dbpath(原来的路径)且不要replSet重启 保持单机模式运行,其他的成员会依然链接他原来的端口,所以会失败,会以为这台服务器挂掉了
78.rs.stepDown(60)将主节点降级为备份节点 并持续60秒,这段时间没有新的主节点被选出来,这个节点会被要求重新选举。
79.rs.freeze(10000)阻止选举,对主节点维护的时候 如果不希望这个时将其他成员选举为主节点,可以给每个备份节点执行这个命令1 秒 维护完成后再执行 rs.freeze(0)释放掉其他成员就可以了
也可以在主节点上执行rs.freeze(0),这样可以将推诿的主节点重新变为主节点
81.MongoDB维护这不同成员间请求的平均花费时间,选择同步源时,会选择一个离自己比较近而且数据比自己新的成员(或者主节点复制),复制链越长,将写操作复制到所以服务器所花费的时间就越长,复制链中每个备份节点都回比他前面的备份节点稍微落后一点 。
82.禁止出现复制链:强制要求每个备份节点都从主节点复制,即将rs.config()中的 allowChaining设置成false即可
83.db.printReplicationInfo 输出包括主节点的oplog信息,db.printSlaveReplicationInfo 获取当前成员的复制源,以及当前成员相对复制源的落后成都信息(只是相对时间而已)
84.分片:将数据拆分,将其分散存放在不同的机器上的过程,有时候也用分区来表示,应用管理需要维护与若干不同的数据库服务连接,连接是独立的,可以很好第工作,不需要强大的大型计算机也可以存储更多的数据,处理更大的负载,但是不方便维护,应用程序发过来的请求发到路由服务器mongos上,有路由服务器转发到不同的分片上,每个分片的响应都发到路由上,然后路由服务器将所有的响应合并在一起,在发送给应用程序
85.分片与复制:复制是让多台服务器都拥有同样的数据副本,每台服务器都是其他服务器的镜像,而每一个分片都有其他分片拥有不同的数据子集。主分片指的是组成分片的整个副本集,而副本集的主节点指的是副本集中能处理写请求的单台服务器。
86.片键:是集合的一个键,Mongodb根据这个键拆分数据,类似于索引的概念,随着集合的不断增长,片键会成为集合上最重要的索引,在查询中如果没有使用片键,mongos会将查询发送到每个分片
87.定向查询:包含片键的查询能直接被发送到目标分片或者是集群 分片的一个子集
聚集查询:有些查询必须被发送到所有的分片。
mongos将查询分散到所以的分片上,然后将各个分片的查询结果聚集起来
88.分片注意:不必分片太早,因为分片会增加部署的操作复杂度,而该决策以后很难再改。也不要运行太久后再分片,因为在一个过载的系统上不停机进行分片是很困难的。
作用: a.增加可用RAM
b.增加可用磁盘空间
c.减轻单台服务器的负载
d.处理单个mongod无法承受的吞吐量
89.配置分片
a.mongod -configsvr --dbpath e:\mongod\data\jq1 --port 8887 配置三个服务器 8887 8888 8889 分别在jq1 jq2 jq3里面
b.mongos --configdb -f e:\mongod\data\db\config.fig
90.sh.addShard(“spock/server-1:8888,server-2:8889”)将spock副本集上的server-1,和server-2添加到分片上,此时必须将客户端的设置为将所有的请求发送到mongos而不是副本集,mongos会将副本集内的所有数据库注册为分片的数据库,因此所以的查询会被发送到新的分片商,
91.db.enableSharding(“music”)对数据库music分片
sh.shardCollection(“music.artists”,{“name”:1}) 将music数据库里的artists集合按照name建分片
92.片键分类:
升序片键:类似于“data”字段的ObjectId,是一种会随着时间稳定增长的字段。
随机分发的片键:类似,用户名,邮件地址,UDID(Uinique Device IDentifier,唯一设备标识)、MD5散列值,或者是数据集其他一些没有规律的键,
位置片键:用户的ID,经纬度、或者是地址
散列片键:加载速度是极致的,使其他任何键随机分发,因此如果打算在大量查询中使用升序键,但又同时希望写入数据随机分发的话,弊端是无法使用散列片键做指定目标的范围查询。
93.片键规则和指导方针:
a.片键不可以是数组,在拥有数组值得键上执行sh.shardCollection(),命令不会呢生效,向片键插入数组值也是不被允许的
b.片键的势:不管片键是跳跃增长还是稳定增长,选择一个值会发生变化的键是非常重要的。与索引一样,分片在势比较高的字段上性能更佳。
94.sh.status()查看摘要信息,sh.status(true)打印出尽可能多的集群信息
db.shards.findOne()记录集群内所有分片的信息,,如果修改了每个数据库的数据应该重启mongos服务器
db.databases.find() 记录集群中所有数据库的信息,不管数据库有没有被分片
db.collections.findOne()跟踪记录所有分片集合的信息
db.chunks记录有集合中所有快的信息
db.changelog() 集合跟踪记录集群的操作,该集合会记录所有的拆分和迁移的操作
db.tags.find() 该集合的创建实在在为系统配置分片标签时发生的,
db.settings() 该集合包含有当前的均衡器设置和块大小的文档信息,可开启或关闭均衡器,也可以修改块的大小
db.adminCommand({“connPoolStats”}) 查看mongos和mongod之间的连接信息
db.adminCommand({“removeShard”:“test-rs3”}) 删除分片
sh.setBalanceState(fales) 关闭均衡器 在数据库管理操作之前,都应该先关闭均衡器
db.locks.find({"_id":“balancer”})[“state”] 返回 0 表示均衡器已经关闭
db.settings.save({"_id":“chunksize”,“value”:32}) 在迁移块的时候通过减小块的大小为32M,会提高迁移速度
sh.moveChunk(“test.users”,{“user_id”:numberlong(“1844674407370955160”)},“spock”) 将包含文档user_id为1844674407370955160的块移至名为spock的分片上
db.adminCommand({“flushRouterConfig”:1}) 当mongos无法从配置服务器正确更新配置是,如果发现配置有误,则用该命令手动刷新
db.currentOp()查看当前正在进行的操作 返回的active 表示该操作是否正在云行,opid为操作的唯一标识
db.killOp(opid) 终止 操作标识 为opid的操作
db.setProfilingLevel(1,500)记录所有耗时超过500ms的操作
db.stats() 查看集合信息
db.addUser(“read_user”,“ijkl”,true)在数据库中添加了一个read_user用户 权限是只读
db.user.remove({“user”:“test_user”})在删除这个用户的文档
db.runCommand({“touch”:“logs”,“data”:true,“index”:true}) 将touch集合里的数据加载到内存中
95.限制连接数量:maxConns=20000-(mongos进程的数量3)-(每个副本集成员数量3)-(其他/mongos进程的数量) 一个mongos最多允许20000个连接
(mongos进程的数量*3) :每个mongos会为每个mongod创建3个连接,一个用于转发客户端请求,一个用于追踪错误信息,即写回监听器,一个用于控制副本集
(每个副本集成员数量*3):主节点会与每个备份节点创建一个连接吧,而每个备份节点会与住节点创建两个连接
96.将单机服务器分片修改为副本集分片过程:a.停止向系统发送请求->b.关闭单机服务器(server-1)和所有的mongos进程->c.以副本集模式重启server-1 (使用–replSet选项)->d.连接到server-1,将其作为一个单成员副本集进行初始化 ->e.连接到配置服务器,替换该分片的入口,在config.shards中将分片名称替换为setName/server-1:27017 db.runCommand({“dbhash”:1}) ->f.重启所有mongos进程,他们会在启动时从配置服务器读取分片数据将副本集当做分片对待 ->g.重启所有的分片的主服务器,刷新工配置数据,然后再次向系统发出请求,再向server-1副本集中添加新成员
98.mongod --dbpath xxx --repair mongod内置的修复工具,用来修复数据文件
99.db.shutdownServer()停止Mongodb 在主节点上运行shutdown命令是,服务器在关闭前,会先等待备份节点追赶上主节点保持同步。如果几秒内备份节点没有成功同步,则shutdown操作失败,主节点不会停止运行
db.adminCommand({“shutdown”:1,“force”:true}) 强制关闭主节点