189 8069 5689

【MongoDB】03、MongoDB索引及分片基础

一、MongoDB配置

创新互联自2013年起,先为蓬莱等服务建站,蓬莱等地企业,进行企业商务咨询服务。为蓬莱企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。

     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
  --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 
  --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 [/]
  --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

   journal          是否启动事务日志,默认已启动

   slowms arg (=100)   设定慢查询,单位为ms,超过设定的时间就为慢查询,默认100ms

   repair           意外关闭时,应该启用这样来修复数据

 

二、索引

      索引通常能够极大的提高查询的效率,如果没有索引,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() 接收可选参数,可选参数列表如下:

ParameterTypeDescription
backgroundBoolean建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 "background" 可选参数。 "background" 默认值为false
uniqueBoolean建立的索引是否唯一。指定为true创建唯一索引。默认值为false.
namestring索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。
dropDupsBoolean在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为false.
sparseBoolean对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为false.
expireAfterSecondsinteger指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。
vindex version索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。
weightsdocument索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。
default_languagestring对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语
language_overridestring对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language.

查询:

  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的分片

1、分片简介

   随着业务发展,当数据集越来越大,CPU、Memory、IO出现瓶颈,就需要对mongodb进行扩展。

增加mongodb只能均衡读压力,不能均衡写压力,就需要对数据集分片。

mongodb原生支持分片

MySQL的分片解决方案(框架),需要资深DBA(5年以上经验)

   Gizzard, HiveDB, MySQL Proxy + HSACLE, Hibernate Shard, Pyshards

2、分片架构中的角色

【MongoDB】03、MongoDB索引及分片基础

mongos:Router  

     相当于代理,将用户请求路由到合适的分片上执行,本身不存储数据也不查询数据,

config server:元数据服务器,也需要多个,但不是副本集,需要借助其它工具实现如zookeeper

      存放的是shard服务器上存储的数据集的索引

shard:数据节点,也称mongod实例

zookeeper:

   常用于实现分布式系统中心节点协调,能够提供选举并选举出主节点机制;zookeeper本身也可以自行做分布式。

3、分片的方式

    分片是基于collection

     为保证每个shard节点上数据集均衡,将每个collectin切割成大小固定的chunk(块),然后逐个分配给shard节点。

基于范围切片:

       range,所用到的索引一定是顺序索引,支持排序如:B tree 索引

       根据索引平均分配chunk

基于列表切片:

       list,离散的方式,将值放在列表中

基于hash切片:

       hash,按键对shard服务器的个数取模,分散存放,实现热点数据发散

  具体使用哪种切片方式需要根据自己的业务模型来定

切片的原则:

   写离散,读集中

  db.enableSharding("testdb")

四、实战案例

1、架构

  【MongoDB】03、MongoDB索引及分片基础

2、配置过程

 1)应先配置config server节点 

      使用configsvr=true配置,无需加入副本集,监听在tcp:27019端口上

 2)mongos

      只需启动mongos时,使用--configdb=172.16.100.16:27019 指定config server即可,监听在tcp 27017作为代理

mongos启动时的选项:

mongos --configdb=172.168.100.16 --fork --logpath=/var/log/mongodb/mongos.log   

 3)在mongos节点上添加shard节点

和shard相关命令的帮助: 

testSet:PRIMARY> sh.help()
	sh.addShard( host )                       server:port OR setname/server:port
	                      # 添加shard节点,可以是副本集名称
	sh.enableSharding(dbname)                 enables sharding on the database dbname                    
	                      # 指定在哪个数据库上启用切片功能
	sh.shardCollection(fullName,key,unique)   shards the collection
	                       # 对哪个collection作切片
	sh.splitFind(fullName,find)               splits the chunk that find is in at the median
	sh.splitAt(fullName,middle)               splits the chunk that middle is in at middle
	sh.moveChunk(fullName,find,to)            move the chunk where 'find' is to 'to' (name of shard)
	sh.setBalancerState(  )   turns the balancer on or off true=on, false=off
	sh.getBalancerState()                     return true if enabled
	sh.isBalancerRunning()                    return true if the balancer has work in progress on any mongos
	sh.addShardTag(shard,tag)                 adds the tag to the shard
	sh.removeShardTag(shard,tag)              removes the tag from the shard
	sh.addTagRange(fullName,min,max,tag)      tags the specified range of the given collection
	sh.status()                               prints a general overview of the clustest                # 查看shard的状态;“primary” 表示如果一些collection很小,没必要做shard,没有做shard的collection存放的数据节点

创建一个collection时,明确指定基于哪个键作shard

sh.shardCollection(fullName,key,unique)

    fullName:为完整的名字,包括数据库和集合:数据库名称.集合名称

例子:sh.shardCollection("testdb.students",{"age":1})

     表示对testdb库中students集合做切片,基于“age”字段创建升序索引;然后在testdb库students集合下的数据就会自动分发到各个shard节点上     

       

use admin  

db.runCommand("listShards")   # 列出shard节点

db.printShardingStatus()和sh.status()一样

sh.isBanlancerRunning()      # 查看均衡器是否在运行,需要均衡时才会自动运行,

sh.getBalancerState()       # 均衡功能是否开启

sh.moveChunk(fullName,find,to)  # 手动移动chunk,不建议使用    


网站栏目:【MongoDB】03、MongoDB索引及分片基础
当前路径:http://cdxtjz.cn/article/pegeeh.html

其他资讯