数码资讯
【MongoDB】02、MongoDB索引及复制
一、索引
索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。
索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构
1、索引的类型
B+ Tree、hash、空间索引、全文索引
MongoDB支持的索引:
单字索引、组合索引(多字段索引)、
多键索引:索引创建在值为键值对上的索引
空间索引:基于位置查找
文本索引:相当于全文索引
hash索引:精确查找,不适用于范围查找
2、索引的管理
创建:
db.mycoll.ensureIndex(keypattern[,options])
查看帮助信息:
db.mycoll.ensureIndex(keypattern[,options]) - options is an object with these possible fields: name, unique, dropDups
db.COLLECTION_NAME.ensureIndex({KEY:1})
语法中 Key 值为你要创建的索引字段,1为指定按升序创建索引,如果你想按降序来创建索引指定为-1即可。ensureIndex() 方法中你也可以设置使用多个字段创建索引(关系型数据库中称作复合索引)。db.col.ensureIndex({"title":1,"description":-1})
ensureIndex() 接收可选参数,可选参数列表如下:
查询:
db.mycoll.getIndex()
删除:
db.mycoll.dropIndexes() 删除当前集合的所有索引
db.mycoll.dropIndexes("index") 删除指定索引
db.mycoll.reIndex() 重新构建索引,
> db.students.find()
> for (i=1;i<=100;i++) db.students.insert({name:"student"+i, age:(i%100)})
# 使用for循环
> db.students.find().count()
100
> db.students.find()
{ "_id" : ObjectId("58d613021e8383d30814f846"), "name" : "student1", "age" : 1 }
{ "_id" : ObjectId("58d613021e8383d30814f847"), "name" : "student2", "age" : 2 }
{ "_id" : ObjectId("58d613021e8383d30814f848"), "name" : "student3", "age" : 3 }
{ "_id" : ObjectId("58d613021e8383d30814f849"), "name" : "student4", "age" : 4 }
{ "_id" : ObjectId("58d613021e8383d30814f84a"), "name" : "student5", "age" : 5 }
{ "_id" : ObjectId("58d613021e8383d30814f84b"), "name" : "student6", "age" : 6 }
{ "_id" : ObjectId("58d613021e8383d30814f84c"), "name" : "student7", "age" : 7 }
{ "_id" : ObjectId("58d613021e8383d30814f84d"), "name" : "student8", "age" : 8 }
{ "_id" : ObjectId("58d613021e8383d30814f84e"), "name" : "student9", "age" : 9 }
{ "_id" : ObjectId("58d613021e8383d30814f84f"), "name" : "student10", "age" : 10 }
{ "_id" : ObjectId("58d613021e8383d30814f850"), "name" : "student11", "age" : 11 }
{ "_id" : ObjectId("58d613021e8383d30814f851"), "name" : "student12", "age" : 12 }
{ "_id" : ObjectId("58d613021e8383d30814f852"), "name" : "student13", "age" : 13 }
{ "_id" : ObjectId("58d613021e8383d30814f853"), "name" : "student14", "age" : 14 }
{ "_id" : ObjectId("58d613021e8383d30814f854"), "name" : "student15", "age" : 15 }
{ "_id" : ObjectId("58d613021e8383d30814f855"), "name" : "student16", "age" : 16 }
{ "_id" : ObjectId("58d613021e8383d30814f856"), "name" : "student17", "age" : 17 }
{ "_id" : ObjectId("58d613021e8383d30814f857"), "name" : "student18", "age" : 18 }
{ "_id" : ObjectId("58d613021e8383d30814f858"), "name" : "student19", "age" : 19 }
{ "_id" : ObjectId("58d613021e8383d30814f859"), "name" : "student20", "age" : 20 }
Type "it" for more # 只显示前20个,it显示更多
> db.students.ensureIndex({name:1}) # 在name键上构建索引,1表示升序,-1表示降序
> show collections
students
system.indexes
t1
> db.students.getIndexes()
[
{ # 默认的索引
"v" : 1,
"name" : "_id_",
"key" : {
"_id" : 1
},
"ns" : "students.students" # 数据库.集合
},
{
"v" : 1,
"name" : "name_1", # 自动生成的索引名
"key" : {
"name" : 1 # 在name键上创建的索引
},
"ns" : "students.students"
}
]
> db.students.dropIndexes("name_1") # 删除指定索引
{
"nIndexesWas" : 2,
"msg" : "non-_id indexes dropped for collection",
"ok" : 1
}
> db.students.getIndexes()
[
{
"v" : 1,
"name" : "_id_",
"key" : {
"_id" : 1
},
"ns" : "students.students"
}
]
> db.students.dropIndexes() # 默认的索引无法删除,
{
"nIndexesWas" : 1,
"msg" : "non-_id indexes dropped for collection",
"ok" : 1
}
> db.students.getIndexes()
[
{
"v" : 1,
"name" : "_id_",
"key" : {
"_id" : 1
},
"ns" : "students.students"
}
> db.students.find({age:"90"}).explain() # 显示查询过程
{
"cursor" : "BtreeCursor t1",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 0,
"nscannedObjectsAllPlans" : 0,
"nscannedAllPlans" : 0,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 17,
"indexBounds" : { # 使用的索引
"age" : [
[
"90",
"90"
]
]
},
"server" : "Node7:27017"
}
二、MongoDB配置
mongodb配置文件/etc/mongodb.conf中的配置项,其实都是mongod启动选项(和memcached一样)
[root@Node7 ~]# mongod --help
Allowed options:
General options:
-h [ --help ] show this usage information
--version show version information
-f [ --config ] arg configuration file specifying additional options
-v [ --verbose ] be more verbose (include multiple times for more
verbosity e.g. -vvvvv)
--quiet quieter output
--port arg specify port number - 27017 by default
--bind_ip arg comma separated list of ip addresses to listen on
- all local ips by default
--maxConns arg max number of simultaneous connections - 20000 by
default
--logpath arg log file to send write to instead of stdout - has
to be a file, not directory
--logappend append to logpath instead of over-writing
--pidfilepath arg full path to pidfile (if not set, no pidfile is
created)
--keyFile arg private key for cluster authentication
--setParameter arg Set a configurable parameter
--nounixsocket disable listening on unix sockets
--unixSocketPrefix arg alternative directory for UNIX domain sockets
(defaults to /tmp)
--fork fork server process
--syslog log to system's syslog facility instead of file
or stdout
--auth run with security
--cpu periodically show cpu and iowait utilization #
--dbpath arg directory for datafiles - defaults to /data/db/
--diaglog arg 0=off 1=W 2=R 3=both 7=W+some reads
--directoryperdb each database will be stored in a separate
directory
--ipv6 enable IPv6 support (disabled by default)
--journal enable journaling # 是否启用事务日志,默认已启动
--journalCommitInterval arg how often to group/batch commit (ms)
--journalOptions arg journal diagnostic options
--jsonp allow JSONP access via http (has security
implications)
--noauth run without security
--nohttpinterface disable http interface
--nojournal disable journaling (journaling is on by default
for 64 bit)
--noprealloc disable data file preallocation - will often hurt
performance
--noscripting disable scripting engine
--notablescan do not allow table scans
--nssize arg (=16) .ns file size (in MB) for new databases
--profile arg 0=off 1=slow, 2=all # 性能剖析
--quota limits each database to a certain number of files
(8 default)
--quotaFiles arg number of files allowed per db, requires --quota
--repair run repair on all dbs
# 意外关闭时,应该启用这样来修复数据
--repairpath arg root directory for repair files - defaults to
dbpath
--rest turn on simple rest api
--shutdown kill a running server (for init scripts)
--slowms arg (=100) value of slow for profile and console log
# 设定慢查询,单位为ms,超过设定的时间就为慢查询
--smallfiles use a smaller default file size
--syncdelay arg (=60) seconds between disk syncs (0=never, but not
recommended)
--sysinfo print some diagnostic system information
--upgrade upgrade db if needed
Replication options:
--oplogSize arg size to use (in MB) for replication op log. default is
5% of disk space (i.e. large is good)
Master/slave options (old; use replica sets instead):
--master master mode
--slave slave mode
--source arg when slave: specify master as <server:port>
--only arg when slave: specify a single database to replicate
--slavedelay arg specify delay (in seconds) to be used when applying
master ops to slave
--autoresync automatically resync if slave data is stale
Replica set options:
--replSet arg arg is <setname>[/<optionalseedhostlist>]
--replIndexPrefetch arg specify index prefetching behavior (if secondary)
[none|_id_only|all]
Sharding options:
--configsvr declare this is a config db of a cluster; default port
27019; default dir /data/configdb
--shardsvr declare this is a shard db of a cluster; default port
27018
SSL options:
--sslOnNormalPorts use ssl on configured ports
--sslPEMKeyFile arg PEM file for ssl
--sslPEMKeyPassword arg PEM file password
--sslCAFile arg Certificate Authority file for SSL
--sslCRLFile arg Certificate Revocation List file for SSL
--sslWeakCertificateValidation allow client to connect without presenting a
certificate
--sslFIPSMode activate FIPS 140-2 mode at startup
常用配置参数:
fork={true|false} mongod是否运行于后台
bind_ip=IP 指定监听地址
port=PORT 指定监听的端口,默认为27017
maxConns=N 指定最大并发连接数
syslog=/PATH/TO/SAME_FILE 指定日志文件
httpinterface=true 是否启动web监控功能,端口为mongod端口 + 1000
三、MongoDB的复制
1、mongodb复制简介
mongodb复制的实现有两种类型:
master/slave:和mysql主从复制非常近似,已经很少用了,
replica set:复制集或副本集,能自动实现故障转移
复制集
服务于同一数据集的一组mongodb实例
一个复制集只能有一个主节点,能读写,其它从节点只能读
主节点将数据修改操作保存至oplog(操作日志)中,各从节点通过oplog来复制数据并应用在本地
mongodb的复制至少需要两个节点,一般为3个节点或更多节点,即使只需要2个节点就够用时也应该使用令一个节点当做仲裁设备,可以不保存数据(如果只有一主一从的话,故障时不知道到底是主故障了还是从故障了)
副本集中各节点之间不断通过心跳信息传递来判断健康状态,默认心跳信息每隔2S传递一次,一旦和主节点与其它节点中断通信超过10S,副本集就会触发重新选举,选举一个从节点成为新的主节点
副本集特征:
奇数个节点的集群,应至少为3个节点,
任何节点可作为主节点,且只能有一个主节点
所有写入操作都在主节点上
自动故障转移,自动恢复
副本集中节点分类:
0优先级的节点:
冷备节点,不会被选举为主节点,但能参与选举过程,并持有数据集,能被客户端访问;常用于异地容灾
被隐藏的从节点:
首先得是0优先级的节点,且对客户端不可见
延迟复制的节点:
首先得是0优先级的节点,且复制时间落后于主节点一个固定时长
arbiter:
仲裁节点,不持有数据集
2、mongodb复制集架构
hearbeat:
实现心跳信息传递,并触发选举
oplog:
保存数据修改操作,是实现复制的基础工具
大小固定的文件,存储在local数据库中,复制集中各节点都有oplog,但只有主节点才会写oplog,并同步给从节点,
oplog具有幂等性,多次运行,结果不变
因为oplog的大小是固定的,不可能保持主节点的所有操作,所以从节点添加进复制集会先初始化:从节点先从主节点的数据集复制数据,并跟上主节点,然后才从oplog复制数据
> show dbs local 0.078125GB sb (empty) studnets (empty) test (empty) > use local switched to db local > show collections # 需要启用了复制集才会生成相关的集合 startup_log >
1个新从节点加入复制集合后的操作过程:
初始同步(initial sync)
回滚后追赶(post-rollback catch-up)
切分块迁移(sharding chunk migrations)
local数据库:
local数据库本身不参与复制(不会复制到别的节点去)
存放了副本集的所有元数据和oplog;用于存储oplog的是一个名为oplog.rs的collection(该节点加入了副本集后第一次启动时自动创建);
oplog.rs的大小依赖于OS及文件系统,默认为磁盘空间的5%(此值少于1G时为1G);但可以自定义其大小:使用oplogSize=N单位为M
3、Mongo的数据同步类型
1)初始同步
从节点没有任何数据时,但主节点已有数据
从节点丢失副本复制历史时
初始同步的步骤:
a、克隆所有数据库
b、应用数据集的所有改变:复制oplog并应用于本地
c、为所有collection构建索引
2)复制
4、选举
副本集的重新选举的影响条件:
心跳信息
优先级
optime
网络连接
网络分区
选举机制:
触发选举的事件:
新副本集初始化时
从节点联系不到主节点时
主节点“下台”时
主节点收到stepDown()命令时
某从节点有更高的优先级且已经满足成主节点其它所有条件
主节点无法联系到副本集的“多数方”