IT虾米网

MongoDB学习--安装与管理详解

admin 2018年05月27日 大数据 192 0

一、简介

        MongoDB是一种强大、灵活,且易于扩展的通用型数据库。他能扩展出非常多的功能。如二级索引(secondary index)、范围查询(range query)、排序、聚合(aggregation),以及地理空间索引(geospatial index)。

        1、易于使用

        MongoDB是一个面向文档(document-oriented)的数据库,而不是关系型数据库。面向文档的数据库不在有“行(row)”的概念,取而代之的是更为灵活的“文档(document)”模型。通过在文档中嵌入文档和数组,面向文档的方法能够仅适用一条记录来表现复杂的层次关系。

        不在有预定义模式(predefined schema),文档的键(key)和值(value)不在是固定的类型和大小。由于没有固定的模式,根据需要添加或删除字段变得更容易了。

        2、易于扩展

        MongoDB的设计采用横向扩展。面向文档的数据模型使它很容易地在多台服务器之间进行数据切割。MongoDB能自动处理跨集群的数据和负载,自动重新分配文档,以及将用户的路由到正确机器上。

        3、丰富的功能

        MongoDB作为一款通用型数据库,除了能够创建、读取、更新和删除数据之外,还提供一系列不断扩展的独特功能。

        索引(indexing):

        MongoDB支持通用二级索引,允许多种快速查找,且提供唯一索引、符合索引、地理空间索引,以及全文索引。

        聚合(aggregation):

        MongoDB支持“聚合管道(aggregation pipeline)”。用户能够通过简单的片段创建复杂的聚合,并通过数据库自动优化。

        特殊的集合类型:

        MongoDB支持存在时间有限的集合,适用于那些将在某个时刻过期的数据,如会话(session)。类似的,MongoDB也支持固定大小的集合,用于保存近期数据,如日志。

        文件存储(file storage):

        MongoDB支持一种非常易用的协议,用于存储大文件和文件元数据。

        MongoDB并不具备一些在关系型数据库中很普遍的功能,如连接(join)和复杂的多事务(multirow transcation)。省略这些功能是出于架构上的考虑(为了得到更好的扩展性),因为在分布式系统中这两个功能难以高效地实现。

        4、卓越的性能

        MongoDB能对文档尽心动态填充(dynamic padding),也能预分配数据文件以利用额外的空间来换取稳定的新能。MongoDB把尽可能多的内存用作缓存(cache),一般会用尽服务器的可用内存,试图为每次查询自动选择正确的索引。  所以MongoDB会非常占用服务器内存,目前并没有什么办法可以限制MongoDB占用内存的方法,所以一般不建议在MongoDB服务器上启用其他进程。

二、下载安装包

下载地址为:https://www.mongodb.com/download-center?jmp=nav#community

Windows: mongodb-win32-x86_64-2008plus-ssl-3.6.4.zip

Linux(CentOS 7): mongodb-linux-x86_64-rhel70-3.6.4.tgz

注意:这里下载的都是压缩包,本文不提供rpm和msi等可执行程序的安装方式

三、Windows下的MongoDB单节点安装

我们将下载完的包解压:C:/context/mongodb

在工作目录下创建MongoDB数据存放目录:D:/workspaces/mongodbspaces/data

在工作目录下创建MongoDB日志文件:D:/workspaces/mongodbspaces/logs/mongodb.log

在安装目录下创建config目录:C:/context/mongodb/config

在配置目录下创建配置文件:C:/context/mongodb/config/config.conf

修改配置文件:

systemLog: 
    # 日志级别,0:包含“info”信息,1~5,即大于0的值均会包含debug信息。类型: integer,默认: 0 
    verbosity: 0 
    # 发送所有的诊断信息日志文件的路径。systemLog.destination为file时有效。类型: string。 
    path: D:/workspaces/mongodbspaces/logs/mongodb.log 
    # 如果是true,则mongod服务重启时会将日志追加到日志末尾,否则每次重启会备份已有的日志并创建新日志。 
    # 类型: boolean。默认: false。 
    logAppend: true 
    # 日志输出目的地,可以指定为“file”或者“syslog”,如果指定“file”则必须要设置systemLog.path。 
    # 如果不指定,则会输出到标准输出中(standard output)。 
    destination: file processManagement: 
    # Windows特有配置选项 
    windowsService: 
        # mongos/mongod作为Windows服务时的服务名称,在net start <name>和net stop <name>时使用。 
        # 类型: string。默认: MongoDB 
        # 必须与--install 安装服务或者--remove删除服务结合使用。 
        serviceName: MongoDB 
        # 在服务管理应用程序中MongoDB服务应用程序的名称。默认: MongoDB 
        displayName: MongoDB 
        # 设置MongoDB服务的描述,默认为MongoDB Server,在--install安装服务时使用。 
        description: MongoDB Server 
net: 
    # mongod/mongos服务侦听客户端连接的端口。类型: int。默认: 27017。 
    port: 27017 
    # mongod/monogs应用侦听客户端的IP地址或者完整UNIX域套接字路径,如果想要绑定多个地址使用逗号分隔。 
    # 若要绑定到所有IPv4地址,请输入0.0.0.0。与net.bindIpAll配置互斥,不能同时配置两个。 
    # 类型: string。默认: localhost 
    bindIp: 0.0.0.0 security: 
    # 打开访问数据库和进行操作的用户角色认证,仅mongod有效。disabled: 关闭; enabled: 开启(默认开启) 
    authorization: enabled 
    # 启用或禁用服务器端JavaScript执行,仅mongod有效。 
    # 如果为false,那么任何与javascript相关的功能都不能使用。类型: boolean。默认: true 
    javascriptEnabled: true setParameter: 
    # 如果开启,则允许本机(localhost/127.0.0.1)第一次访问时不需要密码认证,以便于创建第一个admin数据库的用户 
    # true/1或者false/0,默认为true。mongods和mongod有效,建议mongod关闭该功能。 
    enableLocalhostAuthBypass: true 
    # 认证机制,可选值为“SCRAM-SHA-1”、“MONGODB-CR”、“PLAN”等,建议为“SCRAM-SHA-1” 
    authenticationMechanisms: SCRAM-SHA-1 storage: 
    # mongod实例存储数据库文件路径,仅mongod有效。类型: string 
    dbPath: D:/workspaces/mongodbspaces/data 
    journal: 
        # 是否开启journal日志持久存储,journal日志用来数据恢复, 
        # 是mongod最基础的特性,通常用于故障恢复,仅mongod有效。 
        # 类型: boolean。64bit默认为true,32bit默认为false 
        enabled: true 
    # 是否将不同DB的数据存储在不同的目录中,dbPath的子目录,目录名为db的名称,仅mongod有效。 
    # 类型: boolean。默认: false 
    directoryPerDB: true 
    # mongod存储引擎类型,仅mongod有效,可选mmapv1、wiredTiger、inMemory(企业版专用)。3.2之后默认: wiredTiger 
    engine: wiredTiger
    wiredTiger: 
        engineConfig: 
            # wiredTiger缓存工作集(working set)数据的内存的最大大小。mmapv1引擎没有改配置,会占用系统所有内存。 
            # 这个值需要合理的规划,如果过小会影响MongoDB读写性能,如果过大则会大量使用swap甚至进程会被Linux内存管理进程kill。 
            # 单位:GB,默认值最小256M,如果内存大于512M则默认50%。官方推荐不要将值设置为大于默认值。仅mongod有效 
            cacheSizeGB: 1 
            # 是否将集合数据和索引数据分两个目录存储,默认: false。仅mongod有效 
            directoryForIndexes: true 
配置mongodb环境变量这里就不赘述了。我们执行命令将MongoDB安装成服务:
mongod.exe --config C:/context/mongodb/config/config.conf --install
 
如果需要删除MongoDB服务,则需要执行命令:
mongod.exe --config C:/context/mongodb/config/config.conf --remove
 
如果需要重新安装MongoDB(先卸载再安装),则需要执行:
mongod.exe --config C:/context/mongodb/config/config.conf --reinstall
 
需要注意的是,这里的--config选项的值必须是绝对路径,也可以使用-f参数后面跟配置文件路径,这些操作都必须是在管理员CMD命令窗口里面完成。至此MongoDB的安装已经完成,我们需要先启动MongoDB服务,然后创建admin数据库下的管理员账号和密码:
C:\Users\Administrator> mongo 
... 
> use admin 
... 
> db.createUser({user: "root", pwd: "root", roles: [{role: "root", db: "admin"}]}) 
...

需要注意的是,由于我们第一次启动之前就已经打开了角色认证功能: security.authorization: enabled,但是初始是没有用户和密码的。MongoDB中 setParameter.enableLocalhostAuthBypass: true 这个配置是默认开启的,使用localhost/127.0.0.1第一次登录的时候可以免去角色认证,但是也仅有一次机会。

四、Linux下的MongoDB单节点安装

我们将下载完的包解压:

[root@abc] tar -zxvf mongodb-linux-x86_64-rhel70-3.6.4.tgz -C /usr/local/ 
[root@abc] mv /usr/local/mongodb-linux-x86_64-rhel70-3.6.4 /usr/local/mongodb

在工作目录下创建MongoDB数据存放目录:

[root@abc] mkdir /data/mongodb/data -p

在工作目录下创建MongoDB日志文件:

[root@abc] mkdir /data/mongodb/logs/ -p 
[root@abc] touch /data/mongodb/logs/mongodb.log

在安装目录下创建config配置文件,并编辑配置文件:

[root@abc] mkdir /usr/local/mongodb/config -p 
[root@abc] vim /usr/local/mongodb/config/config.conf
systemLog: 
    # 日志级别,0:包含“info”信息,1~5,即大于0的值均会包含debug信息。类型: integer,默认: 0 
    verbosity: 0 
    # 发送所有的诊断信息日志文件的路径。systemLog.destination为file时有效。类型: string。 
    path: /data/mongodb/logs/mongodb.log 
    # 如果是true,则mongod服务重启时会将日志追加到日志末尾,否则每次重启会备份已有的日志并创建新日志。 
    # 类型: boolean。默认: false。 
    logAppend: true 
    # 日志输出目的地,可以指定为“file”或者“syslog”,如果指定“file”则必须要设置systemLog.path。 
    # 如果不指定,则会输出到标准输出中(standard output)。 
    destination: file processManagement: 
    # 是否以守护进程(后台进程)的方式运行mongod/mongos进程。类型: boolean。默认: false。 
    fork: true 
    # 配合"fork:true"参数,将mongod/mongos进程ID写入指定的文件,如果不指定,将不会创建PID文件。类型: string 
    pidFilePath: /data/mongodb/logs/mongodb.pid 
net: 
    # mongod/mongos服务侦听客户端连接的端口。类型: int。默认: 27017。 
    port: 27017 
    # mongod/monogs应用侦听客户端的IP地址或者完整UNIX域套接字路径,如果想要绑定多个地址使用逗号分隔。 
    # 若要绑定到所有IPv4地址,请输入0.0.0.0。与net.bindIpAll配置互斥,不能同时配置两个。 
    # 类型: string。默认: localhost 
    bindIp: 0.0.0.0 security: 
    # 打开访问数据库和进行操作的用户角色认证,仅mongod有效。disabled: 关闭; enabled: 开启(默认开启) 
    authorization: enabled 
setParameter: 
    # 如果开启,则允许本机(localhost/127.0.0.1)第一次访问时不需要密码认证,以便于创建第一个admin数据库的用户 
    # true/1或者false/0,默认为true。mongods和mongod有效,建议mongod关闭该功能。 
    enableLocalhostAuthBypass: true 
    # 认证机制,可选值为“SCRAM-SHA-1”、“MONGODB-CR”、“PLAN”等,建议为“SCRAM-SHA-1” 
    authenticationMechanisms: SCRAM-SHA-1 storage: 
    # mongod实例存储数据库文件路径,仅mongod有效。类型: string 
    dbPath: /data/mongodb/data 
    journal: 
        # 是否开启journal日志持久存储,journal日志用来数据恢复, 
        # 是mongod最基础的特性,通常用于故障恢复,仅mongod有效。 
        # 类型: boolean。64bit默认为true,32bit默认为false 
        enabled: true 
    # 是否将不同DB的数据存储在不同的目录中,dbPath的子目录,目录名为db的名称,仅mongod有效。 
    # 类型: boolean。默认: false 
    directoryPerDB: true 
    # mongod存储引擎类型,仅mongod有效,可选mmapv1、wiredTiger、inMemory(企业版专用)。3.2之后默认: wiredTiger 
    engine: wiredTiger
    wiredTiger: 
        engineConfig: 
            # wiredTiger缓存工作集(working set)数据的内存的最大大小。mmapv1引擎没有改配置,会占用系统所有内存。 
            # 这个值需要合理的规划,如果过小会影响MongoDB读写性能,如果过大则会大量使用swap甚至进程会被内存管理器kill。 
            # 单位:GB,默认值最小256M,如果内存大于512M则默认50%。官方推荐不要将值设置为大于默认值。仅mongod有效 
            cacheSizeGB: 1 
            # 是否将集合数据和索引数据分两个目录存储,默认: false。仅mongod有效 
            directoryForIndexes: true

创建mongodb.service文件,将mongodb配置成Linux服务:

[root@abc] vim /lib/systemd/system/mongodb.service
[Unit] 
 
Description=mongodb  
After=network.target remote-fs.target nss-lookup.target 
 
[Service] 
Type=forking 
ExecStart=numactl --interleave=all /usr/local/mongodb/bin/mongod --config /usr/local/mongodb/config/config.conf 
ExecReload=/bin/kill -s HUP $MAINPID 
ExecStop=/usr/local/mongodb/bin/mongod --shutdown --config /usr/local/mongodb/config/config.conf 
PrivateTmp=true 
 [Install] 
WantedBy=multi-user.target

设置MongoDB服务开机启动:

[root@abc] systemctl enable mongodb.service

如果需要取消开机启动则执行:  systemctl disable mongodb.service

第一次启动MongoDB服务:

[root@abc] systemctl start mongodb.service

如果需要停止服务则执行: systemctl stop mongodb.service

配置mongodb环境变量:

[root@abc] vim /etc/profile
... 
... 
export PATH=$PATH:/usr/local/mongodb/bin 
 
:wq
[root@abc] source /etc/profile

然后开始创建admin数据库的root角色用户。记住,这里只有一次机会免密码登入创建用户:

[root@abc] mongo 
... 
> use admin 
... 
> db.createUser({user: "root", pwd: "root", roles: [{role: "root", db: "admin"}]}) 
...

五、Linux下的MongoDB集群安装

  在安装之前,我们得先要了解一下MongoDB集群的集群类型,以及集群中的一些角色和它们的作用。mongodb有传统的主从集群(未来可能会被废弃)、副本集集群和分片集群三种模式的集群,传统的主从集群这里不做介绍。副本集和分片两种集群模式并不对立,既可以单独部署也可以组合部署。

1、副本集

   在副本集集群中有两种类型的角色:主节点(primary)和备用节点(secondary)。客户端只会与主节点进行数据交互(只有主节点允许写操作),备用节点通过oplog日志异步复制主节点数据,oplog包含了主节点的每一次写操作,是主节点中local数据库中的一个固定集合,备用节点通过这个集合复制主节点数据,每个备用节点都维护着自己的oplog,记录者每一次从主节点复制数据的操作,备用节点不对外提供服务。

        集群中每个成员会每隔2秒向其他成员发送一条心跳请求,确认集群中成员的状态(那个是主节点,那个可以作为同步源、  那个节点下线了),心跳信息量非常小,用于检查每个成员状态。心跳的功能之一就是让主节点知道自己是否满足集合“大多数”的条件,如果主节点不在得到“大多数”服务器的支持,他就会退位,变成备用节点。

        如果主节点宕机或者由于网络原因,备用节点无法连接到主节点,那么所有得到这个消息的备用节点都会申请被选举成为主节点,希望被选举成为主节点的成员会向它能到达的所有成员发送通知。如果这个申请选举的成员不符合候选主节点要求(这个成员的数据落后于副本集,或者只是由于网络原因备用节点无法到达主节点而申请的选举),其他成员不会进行选举。

        如果没有反对理由,那么其他成员就会对这个成员进行选举投票。如果这个成员得到副本集中“大多数”赞成票,那么它就会被选举成为主节点。如果达不到“大多数”的要求,那么选举失败,它仍然助于备用节点状态,它之后还可以在此申请。主节点会一直处于主节点状态,除非它由于不在满足“大多数”的要求而退位。副本集节点数据必须是奇数个,否则在选举时可能会出现平局的选举结果导致无法出现主节点而集群不能工作。如果一定要使用偶数个节点,那么就必须再加一个仲裁节点,仲裁节点只会在选举平局的时候出来仲裁,并不会提供其他任何服务,所以占用资源非常少,但官方建议使用奇数个节点。

2、分片

  分片是指将数据拆分,将其分散存放到不同的机器上的过程。在分片集群中有配置服务(Config Server)、路由服务(Router Server)、和分片服务(Shard Server)等角色。mongodb本身有两种组件:mongod和mongos,Shard Server和Config Server服务是以mongod类型的进程运行的,Router Server是以mongos类型的进程运行的。

        Config Server:配置服务相当于集群大脑,保存着集群和分片的元数据,即各分片包含着那些数据的信息。MongDB 3.4  之后要求配置服务必须是奇数个节点的副本集,否则集群不能正常启动。鉴于配置服务所包含的数据极端重要,所以必须启用日志功能,并确保其数据保存在非易失性驱动器上。

        Router Server:前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用。mongos能够根据给定的片键找到文档的存放位置,但当集群中存在成千上万个文档时,就会难以操作。因此将文档分组为块(chunk),每个块由给定片键特定范围内的文档组成。一个块只存在一个分片上,所以可以使用一个比较小的空间就能够维护块和分片间的映射。数据块大小是固定的,均衡器(balancer)会周期性地检查快的大小,当块超过这个大小之后,会有均衡器将其拆分为多个块,以保证数据均衡。

        Shard Server:用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个副本集承担,防止主机单点故障。当需要对集合分片时,就必须得指定一个片键,片键必须有索引,如果集合已存储了大量数据,那么基本就不可能再修改片键了,因此选择片键时需要慎重。

3、分片+副本集集群安装

        通过上面的描述,我们大概已经了解了分片+副本集集群的相关概念,可以开始安装了。这里我们提供三台机器供安装,服务规划为:

172.23.102.56172.23.102.57172.23.102.58
mongos port:27017mongos port:27017mongos port:27017
config server port:27018config server port:27018config server port:27018
shard1 server port:27019shard1 server port:27019shard1 server port:27019
shard2 server port:27020shard2 server port:27020shard2 server port:27020
shard3 server port:28021shard3 server port:28021shard3 server port:28021

将安装包解压到/use/local/mongodb目录下(三个机器相同操作):

[root@abc] tar -zxvf mongodb-linux-x86_64-rhel70-3.6.4.tgz -C /usr/local/ 
[root@abc] mv /usr/local/mongodb-linux-x86_64-rhel70-3.6.4 /usr/local/mongodb

在安装目录下创建配置文件存放目录和配置文件(三个机器相同操作):

[root@abc] mkdir /usr/local/mongodb/config 
[root@abc] cd /usr/local/mongodb/config 
[root@abc] touch mongos.conf config.conf shard1.conf shard2.conf shard3.conf

配置文件目录和配置文件都已经创建好了,其中 mongos.conf 为路由服务配置文件, config.conf 为配置服务配置文件, shard1.conf shard2.conf shard3.conf 为三个分片服务配置文件。我们开始创建数据存储目录(三个机器相同操作):

[root@abc] mkdir /data/mongodb/mongos/logs -p ## mongos日志文件存储目录,由于mongos不存储数据,所以不需要数据存储目录 
[root@abc] touch /data/mongodb/mongos/logs/mongos.log ## mongos日志文件 
[root@abc] mkdir /data/mongodb/config/logs -p         ## config日志文件存储目录 
[root@abc] mkdir /data/mongodb/config/logs/config.log ## config日志文件 
[root@abc] mkdir /data/mongodb/config/data -p         ## config数据文件存储目录 
[root@abc] mkdir /data/mongodb/shard1/logs -p         ## 第一个分片日志文件存储目录 
[root@abc] mkdir /data/mongodb/shard1/logs/shard1.log ## 第一个分片日志文件 
[root@abc] mkdir /data/mongodb/shard1/data -p         ## 第一个分片数据文件存储目录 
[root@abc] mkdir /data/mongodb/shard2/logs -p         ## 第二个分片日志文件存储目录 
[root@abc] mkdir /data/mongodb/shard2/logs/shard2.log ## 第二个分片日志文件 
[root@abc] mkdir /data/mongodb/shard2/data -p         ## 第二个分片数据文件存储目录 
[root@abc] mkdir /data/mongodb/shard3/logs -p         ## 第三个分片日志文件存储目录 
[root@abc] mkdir /data/mongodb/shard3/logs/shard3.log ## 第三个分片日志文件 
[root@abc] mkdir /data/mongodb/shard3/data -p         ## 第三个分片数据文件存储目录

在这里我们使用keyFile的方式作为集群成员之间的安全校验,所以需要先生成keyFile文件:

[root@abc] openssl rand -base64 756 > /usr/local/mongodb/keyFile.file [root@abc] chmod 400 /usr/local/mongodb/keyFile.file

编写config server配置文件,在三个机器中除 net.bindIp 配置需要对应到不同的机器之外,其他配置都一样:

:包含“”信息,~,即大于0的值均会包含debug信息。类型: integer,默认: /data/mongodb/config/logs/”或者“syslog”,如果指定“/mongos进程。类型: boolean。默认: 参数,将mongod/mongos进程ID写入指定的文件,如果不指定,将不会创建PID文件。类型: /data/mongodb/config/logs//mongos服务侦听客户端连接的端口。类型: 。默认: /..,. / .,. / .,./usr/local/mongodb/keyFile././1或者false/-SHA-”、“MONGODB-CR”、“PLAN”等,建议为“SCRAM-SHA--SHA-/data/mongodb/config/%%

分别启动三个机器上的config server:

[root@abc] numactl --interleave=all mongod --config /usr/local/mongodb/config/config.conf

当三个机器上的配置服务都启动之后,然后随便选择一个服务登入,将三个配置服务节点添加到一个副本集中:

[root@abc] mongo --port 27018  #连接 
... 
> config = { 
> ...     _id: "config",  # 配置文件中配置服务副本集的名称 
> ...     members: [ 
> ...         { _id: 0, host: "172.23.102.56:27018", priority: 100 }, 
> ...         { _id: 1, host: "172.23.102.57:27018", priority: 99 }, 
> ...         { _id: 2, host: "172.23.102.58:27018", priority: 98 } 
> ...     ] 
> ... }  # 设置变量 
... 
rs.initiate(config)  # 初始化副本集 
... 
rs.status()  # 查看副本集状态 
...

priority 代表优先级,数值越大优先级越高。如果这里使用的是偶数个节点的话,那么就需要多加一个参数 {_id : 2, host : "172.23.102.58:27018", priority: 98,  arbiterOnly: true } ,表示58这个机器为仲裁节点。需要注意的是,配置服务一定要在mongos路由服务之前启动并初始化完成,因为mongos服务需要依赖配置服务中的数据。

编写shard1 server配置文件,在三个机器中除 net.bindIp 配置需要对应到不同的机器之外,其他配置都一样:

systemLog: 
    # 日志级别,0:包含“info”信息,1~5,即大于0的值均会包含debug信息。类型: integer,默认: 0 
    verbosity: 0 
    # 发送所有的诊断信息日志文件的路径。systemLog.destination为file时有效。类型: string。 
    path: /data/mongodb/shard1/logs/shard1.log 
    # 如果是true,则mongod服务重启时会将日志追加到日志末尾,否则每次重启会备份已有的日志并创建新日志。 
    # 类型: boolean。默认: false。 
    logAppend: true 
    # 日志输出目的地,可以指定为“file”或者“syslog”,如果指定“file”则必须要设置systemLog.path。 
    # 如果不指定,则会输出到标准输出中(standard output)。 
    destination: file processManagement: 
    # 是否以守护进程(后台进程)的方式运行mongod/mongos进程。类型: boolean。默认: false。 
    # 在Linux下如果是使用npm包的方式安装,并使用自带的init script脚本,则不推荐修改默认值。 
    # 否则需要禁用默认的init script,而使用自己的init script。 
    fork: true 
    # 配合"fork:true"参数,将mongod/mongos进程ID写入指定的文件,如果不指定,将不会创建PID文件。类型: string 
    pidFilePath: /data/mongodb/shard1/logs/shard1.pid 
net: 
    # mongod/mongos服务侦听客户端连接的端口。类型: int。默认: 27017。 
    port: 27019 
    # mongod/monogs应用侦听客户端的IP地址或者完整UNIX域套接字路径,如果想要绑定多个地址使用逗号分隔。 
    # 若要绑定到所有IPv4地址,请输入0.0.0.0。与net.bindIpAll配置互斥,不能同时配置两个。 
    # 类型: string。默认: localhost 
    bindIp: 127.0.0.1,172.23.102.56 / 127.0.0.1,172.23.102.57 / 127.0.0.1,172.23.102.58 #这里三个设备分别对应 
security: 
    # 密钥文件的路径,它存储MongoDB实例在共享的集群或副本集中相互验证的共享密钥。 
    # 必须设置security.authorization为enable。类型: string 
    keyFile: /usr/local/mongodb/keyFile.file 
    # 集群成员之间的认证模式。类型: string。可选: keyFile、sendKeyFile、sendX509、x509。默认: keyFile。 
    clusterAuthMode: keyFile 
    # 打开访问数据库和进行操作的用户角色认证,仅mongod有效。disabled: 关闭; enabled: 开启(默认开启) 
    authorization: enabled 
    # 启用或禁用服务器端JavaScript执行,仅mongod有效。 
    # 如果为false,那么任何与javascript相关的功能都不能使用。类型: boolean。默认: true 
    javascriptEnabled: true setParameter: 
    # 如果开启,则允许本机(localhost/127.0.0.1)第一次访问时不需要密码认证,以便于创建第一个admin数据库的用户 
    # true/1或者false/0,默认为true。mongods和mongod有效,建议mongod关闭该功能。 
    enableLocalhostAuthBypass: true 
    # 认证机制,可选值为“SCRAM-SHA-1”、“MONGODB-CR”、“PLAN”等,建议为“SCRAM-SHA-1” 
    authenticationMechanisms: SCRAM-SHA-1 storage: 
    # mongod实例存储数据库文件路径,仅mongod有效。类型: string 
    dbPath: /data/mongodb/shard1/data 
    journal: 
        # 记录操作日志,防止数据丢失。64bit默认为true,32bit默认为false 
        enabled: true 
    # 是否将不同DB的数据存储在不同的目录中,dbPath的子目录,目录名为db的名称,仅mongod有效。类型: boolean。默认: false 
    directoryPerDB: true 
    # mongod使用fsync操作将数据flush到磁盘的时间间隔,仅mongod有效,不建议修改默认值。类型: number。默认: 60 
    syncPeriodSecs: 60 
    # mongod存储引擎类型,仅mongod有效,可选mmapv1、wiredTiger、inMemory(企业版专用)。3.2之后默认: wiredTiger 
    engine: wiredTiger 
    wiredTiger: 
        engineConfig: 
            # wiredTiger缓存工作集(working set)数据的内存的最大大小。mmapv1引擎没有改配置,会占用系统所有内存。 
            # 这个值需要合理的规划,如果过小会影响MongoDB读写性能,如果过大则会大量使用swap甚至进程会被Linux内存管理进程kill。 
            # 单位:GB,默认值最小256M,如果内存大于512M则默认50%。官方推荐不要将值设置为大于默认值。仅mongod有效 
            cacheSizeGB: 3 
            # 是否将集合数据和索引数据分两个目录存储,默认: false。仅mongod有效 
            directoryForIndexes: true replication: 
    # 指定oplog的最大尺寸。对于已经建立过oplog.rs的数据库,指定无效。 
    # 默认为磁盘的5%。仅mongod有效 
    # oplogSizeMB:  
    # 指定副本集的名称。仅mongod有效 
    replSetName: shard1 
    # 指定副本集成员在接受oplog之前是否加载索引到内存。默认会加载所有的索引到内存。 
    # none,不加载;all,加载所有;_id_only,仅加载_id。仅mongod有效 
    secondaryIndexPrefetch: all 
sharding: 
    # 指定分片集的mongodb角色。configsvr: 配置服务器。shardsvr: 分片实例。仅mongod有效 
    clusterRole: shardsvr 
    # 在块移动过程中,该选项强制mongodb实例保存所有移动的文档到moveChunk目录。 
    # 在版本3.2及以后版本中默认值为false。 
    archiveMovedChunks: false

分别启动三个机器上的shard1 server:

[root@abc] numactl --interleave=all mongod --config /usr/local/mongodb/config/shard1.conf

当三个机器上的第一个分片服务都启动之后,然后随便选择一个服务登入,将三个配置服务节点添加到一个副本集中:

[root@abc] mongo --port > config => ...     _id: >> ...         { _id: , host: > ...         { _id: , host: > ...         { _id: , host: >>

priority 代表优先级,数值越大优先级越高。如果这里使用的是偶数个节点的话,那么就需要多加一个参数 {_id : 1, host : "172.23.102.57:27019", priority: 98, arbiterOnly: true } ,表示57这个机器为仲裁节点。

编写shard2 server配置文件,在三个机器中除 net.bindIp 配置需要对应到不同的机器之外,其他配置都一样:

systemLog: 
    # 日志级别,0:包含“info”信息,1~5,即大于0的值均会包含debug信息。类型: integer,默认: 0 
    verbosity: 0 
    # 发送所有的诊断信息日志文件的路径。systemLog.destination为file时有效。类型: string。 
    path: /data/mongodb/shard2/logs/shard2.log 
    # 如果是true,则mongod服务重启时会将日志追加到日志末尾,否则每次重启会备份已有的日志并创建新日志。 
    # 类型: boolean。默认: false。 
    logAppend: true 
    # 日志输出目的地,可以指定为“file”或者“syslog”,如果指定“file”则必须要设置systemLog.path。 
    # 如果不指定,则会输出到标准输出中(standard output)。 
    destination: file processManagement: 
    # 是否以守护进程(后台进程)的方式运行mongod/mongos进程。类型: boolean。默认: false。 
    # 在Linux下如果是使用npm包的方式安装,并使用自带的init script脚本,则不推荐修改默认值。 
    # 否则需要禁用默认的init script,而使用自己的init script。 
    fork: true 
    # 配合"fork:true"参数,将mongod/mongos进程ID写入指定的文件,如果不指定,将不会创建PID文件。类型: string 
    pidFilePath: /data/mongodb/shard2/logs/shard2.pid 
net: 
    # mongod/mongos服务侦听客户端连接的端口。类型: int。默认: 27017。 
    port: 27020 
    # mongod/monogs应用侦听客户端的IP地址或者完整UNIX域套接字路径,如果想要绑定多个地址使用逗号分隔。 
    # 若要绑定到所有IPv4地址,请输入0.0.0.0。与net.bindIpAll配置互斥,不能同时配置两个。 
    # 类型: string。默认: localhost 
    bindIp: 127.0.0.1,172.23.102.56 / 127.0.0.1,172.23.102.57 / 127.0.0.1,172.23.102.58 #这里三个设备分别对应 
security: 
    # 密钥文件的路径,它存储MongoDB实例在共享的集群或副本集中相互验证的共享密钥。 
    # 必须设置security.authorization为enable。类型: string 
    keyFile: /usr/local/mongodb/keyFile.file 
    # 集群成员之间的认证模式。类型: string。可选: keyFile、sendKeyFile、sendX509、x509。默认: keyFile。 
    clusterAuthMode: keyFile 
    # 打开访问数据库和进行操作的用户角色认证,仅mongod有效。disabled: 关闭; enabled: 开启(默认开启) 
    authorization: enabled 
    # 启用或禁用服务器端JavaScript执行,仅mongod有效。 
    # 如果为false,那么任何与javascript相关的功能都不能使用。类型: boolean。默认: true 
    javascriptEnabled: true setParameter: 
    # 如果开启,则允许本机(localhost/127.0.0.1)第一次访问时不需要密码认证,以便于创建第一个admin数据库的用户 
    # true/1或者false/0,默认为true。mongods和mongod有效,建议mongod关闭该功能。 
    enableLocalhostAuthBypass: true 
    # 认证机制,可选值为“SCRAM-SHA-1”、“MONGODB-CR”、“PLAN”等,建议为“SCRAM-SHA-1” 
    authenticationMechanisms: SCRAM-SHA-1 storage: 
    # mongod实例存储数据库文件路径,仅mongod有效。类型: string 
    dbPath: /data/mongodb/shard2/data 
    journal: 
        # 记录操作日志,防止数据丢失。64bit默认为true,32bit默认为false 
        enabled: true 
    # 是否将不同DB的数据存储在不同的目录中,dbPath的子目录,目录名为db的名称,仅mongod有效。类型: boolean。默认: false 
    directoryPerDB: true 
    # mongod使用fsync操作将数据flush到磁盘的时间间隔,仅mongod有效,不建议修改默认值。类型: number。默认: 60 
    syncPeriodSecs: 60 
    # mongod存储引擎类型,仅mongod有效,可选mmapv1、wiredTiger、inMemory(企业版专用)。3.2之后默认: wiredTiger 
    engine: wiredTiger 
    wiredTiger: 
        engineConfig: 
            # wiredTiger缓存工作集(working set)数据的内存的最大大小。mmapv1引擎没有改配置,会占用系统所有内存。 
            # 这个值需要合理的规划,如果过小会影响MongoDB读写性能,如果过大则会大量使用swap甚至进程会被Linux内存管理进程kill。 
            # 单位:GB,默认值最小256M,如果内存大于512M则默认50%。官方推荐不要将值设置为大于默认值。仅mongod有效 
            cacheSizeGB: 3 
            # 是否将集合数据和索引数据分两个目录存储,默认: false。仅mongod有效 
            directoryForIndexes: true replication: 
    # 指定oplog的最大尺寸。对于已经建立过oplog.rs的数据库,指定无效。 
    # 默认为磁盘的5%。仅mongod有效 
    # oplogSizeMB:  
    # 指定副本集的名称。仅mongod有效 
    replSetName: shard2 
    # 指定副本集成员在接受oplog之前是否加载索引到内存。默认会加载所有的索引到内存。 
    # none,不加载;all,加载所有;_id_only,仅加载_id。仅mongod有效 
    secondaryIndexPrefetch: all 
sharding: 
    # 指定分片集的mongodb角色。configsvr: 配置服务器。shardsvr: 分片实例。仅mongod有效 
    clusterRole: shardsvr 
    # 在块移动过程中,该选项强制mongodb实例保存所有移动的文档到moveChunk目录。 
    # 在版本3.2及以后版本中默认值为false。 
    archiveMovedChunks: false

分别启动三个机器上的shard2 server:

[root@abc] numactl --interleave=all mongod --config /usr/local/mongodb/config/shard2.conf

当三个机器上的第二个分片服务都启动之后,然后随便选择一个服务登入,将三个配置服务节点添加到一个副本集中:

[root@abc] mongo --port > config => ...     _id: >> ...         { _id: , host: > ...         { _id: , host: > ...         { _id: , host: >>

priority 代表优先级,数值越大优先级越高。如果这里使用的是偶数个节点的话,那么就需要多加一个参数 {_id : 0, host : "172.23.102.56:27020", priority: 98, arbiterOnly: true } ,表示56这个机器为仲裁节点。

编写shard3 server配置文件,在三个机器中除 net.bindIp 配置需要对应到不同的机器之外,其他配置都一样:

systemLog: 
    # 日志级别,0:包含“info”信息,1~5,即大于0的值均会包含debug信息。类型: integer,默认: 0 
    verbosity: 0 
    # 发送所有的诊断信息日志文件的路径。systemLog.destination为file时有效。类型: string。 
    path: /data/mongodb/shard3/logs/shard3.log 
    # 如果是true,则mongod服务重启时会将日志追加到日志末尾,否则每次重启会备份已有的日志并创建新日志。 
    # 类型: boolean。默认: false。 
    logAppend: true 
    # 日志输出目的地,可以指定为“file”或者“syslog”,如果指定“file”则必须要设置systemLog.path。 
    # 如果不指定,则会输出到标准输出中(standard output)。 
    destination: file processManagement: 
    # 是否以守护进程(后台进程)的方式运行mongod/mongos进程。类型: boolean。默认: false。 
    # 在Linux下如果是使用npm包的方式安装,并使用自带的init script脚本,则不推荐修改默认值。 
    # 否则需要禁用默认的init script,而使用自己的init script。 
    fork: true 
    # 配合"fork:true"参数,将mongod/mongos进程ID写入指定的文件,如果不指定,将不会创建PID文件。类型: string 
    pidFilePath: /data/mongodb/shard3/logs/shard3.pid 
net: 
    # mongod/mongos服务侦听客户端连接的端口。类型: int。默认: 27017。 
    port: 27021 
    # mongod/monogs应用侦听客户端的IP地址或者完整UNIX域套接字路径,如果想要绑定多个地址使用逗号分隔。 
    # 若要绑定到所有IPv4地址,请输入0.0.0.0。与net.bindIpAll配置互斥,不能同时配置两个。 
    # 类型: string。默认: localhost 
    bindIp: 127.0.0.1,172.23.102.56 / 127.0.0.1,172.23.102.57 / 127.0.0.1,172.23.102.58 #这里三个设备分别对应 
security: 
    # 密钥文件的路径,它存储MongoDB实例在共享的集群或副本集中相互验证的共享密钥。 
    # 必须设置security.authorization为enable。类型: string 
    keyFile: /usr/local/mongodb/keyFile.file 
    # 集群成员之间的认证模式。类型: string。可选: keyFile、sendKeyFile、sendX509、x509。默认: keyFile。 
    clusterAuthMode: keyFile 
    # 打开访问数据库和进行操作的用户角色认证,仅mongod有效。disabled: 关闭; enabled: 开启(默认开启) 
    authorization: enabled 
    # 启用或禁用服务器端JavaScript执行,仅mongod有效。 
    # 如果为false,那么任何与javascript相关的功能都不能使用。类型: boolean。默认: true 
    javascriptEnabled: true setParameter: 
    # 如果开启,则允许本机(localhost/127.0.0.1)第一次访问时不需要密码认证,以便于创建第一个admin数据库的用户 
    # true/1或者false/0,默认为true。mongods和mongod有效,建议mongod关闭该功能。 
    enableLocalhostAuthBypass: true 
    # 认证机制,可选值为“SCRAM-SHA-1”、“MONGODB-CR”、“PLAN”等,建议为“SCRAM-SHA-1” 
    authenticationMechanisms: SCRAM-SHA-1 storage: 
    # mongod实例存储数据库文件路径,仅mongod有效。类型: string 
    dbPath: /data/mongodb/shard3/data 
    journal: 
        # 记录操作日志,防止数据丢失。64bit默认为true,32bit默认为false 
        enabled: true 
    # 是否将不同DB的数据存储在不同的目录中,dbPath的子目录,目录名为db的名称,仅mongod有效。类型: boolean。默认: false 
    directoryPerDB: true 
    # mongod使用fsync操作将数据flush到磁盘的时间间隔,仅mongod有效,不建议修改默认值。类型: number。默认: 60 
    syncPeriodSecs: 60 
    # mongod存储引擎类型,仅mongod有效,可选mmapv1、wiredTiger、inMemory(企业版专用)。3.2之后默认: wiredTiger 
    engine: wiredTiger 
    wiredTiger: 
        engineConfig: 
            # wiredTiger缓存工作集(working set)数据的内存的最大大小。mmapv1引擎没有改配置,会占用系统所有内存。 
            # 这个值需要合理的规划,如果过小会影响MongoDB读写性能,如果过大则会大量使用swap甚至进程会被Linux内存管理进程kill。 
            # 单位:GB,默认值最小256M,如果内存大于512M则默认50%。官方推荐不要将值设置为大于默认值。仅mongod有效 
            cacheSizeGB: 3 
            # 是否将集合数据和索引数据分两个目录存储,默认: false。仅mongod有效 
            directoryForIndexes: true replication: 
    # 指定oplog的最大尺寸。对于已经建立过oplog.rs的数据库,指定无效。 
    # 默认为磁盘的5%。仅mongod有效 
    # oplogSizeMB:  
    # 指定副本集的名称。仅mongod有效 
    replSetName: shard3 
    # 指定副本集成员在接受oplog之前是否加载索引到内存。默认会加载所有的索引到内存。 
    # none,不加载;all,加载所有;_id_only,仅加载_id。仅mongod有效 
    secondaryIndexPrefetch: all 
sharding: 
    # 指定分片集的mongodb角色。configsvr: 配置服务器。shardsvr: 分片实例。仅mongod有效 
    clusterRole: shardsvr 
    # 在块移动过程中,该选项强制mongodb实例保存所有移动的文档到moveChunk目录。 
    # 在版本3.2及以后版本中默认值为false。 
    archiveMovedChunks: false

分别启动三个机器上的shard3 server:

[root@abc] numactl --interleave=all mongod --config /usr/local/mongodb/config/shard3.conf

当三个机器上的第三个分片服务都启动之后,然后随便选择一个服务登入,将三个配置服务节点添加到一个副本集中:

[root@abc] mongo --port > config => ...     _id: >> ...         { _id: , host: > ...         { _id: , host: > ...         { _id: , host: >>

priority 代表优先级,数值越大优先级越高。如果这里使用的是偶数个节点的话,那么就需要多加一个参数 {_id : 2, host : "172.23.102.58:27021", priority: 99, arbiterOnly: true } ,表示58这个机器为仲裁节点。

编写mongos server配置文件,在三个机器中除 net.bindIp 配置需要对应到不同的机器之外,其他配置都一样:

systemLog: 
    # 日志级别,0:包含“info”信息,1~5,即大于0的值均会包含debug信息。类型: integer,默认: 0 
    verbosity: 0 
    # 发送所有的诊断信息日志文件的路径。systemLog.destination为file时有效。类型: string。 
    path: /data/mongodb/mongos/logs/mongos.log 
    # 如果是true,则mongod服务重启时会将日志追加到日志末尾,否则每次重启会备份已有的日志并创建新日志。 
    # 类型: boolean。默认: false。 
    logAppend: true 
    # 日志输出目的地,可以指定为“file”或者“syslog”,如果指定“file”则必须要设置systemLog.path。 
    # 如果不指定,则会输出到标准输出中(standard output)。 
    destination: file processManagement: 
    # 是否以守护进程(后台进程)的方式运行mongod/mongos进程。类型: boolean。默认: false。 
    # 在Linux下如果是使用npm包的方式安装,并使用自带的init script脚本,则不推荐修改默认值。 
    # 否则需要禁用默认的init script,而使用自己的init script。 
    fork: true 
    # 配合"fork:true"参数,将mongod/mongos进程ID写入指定的文件,如果不指定,将不会创建PID文件。类型: string 
    pidFilePath: /data/mongodb/mongos/logs/mongos.pid 
net: 
    # mongod/mongos服务侦听客户端连接的端口。类型: int。默认: 27017。 
    port: 27017 
    # mongod/monogs应用侦听客户端的IP地址或者完整UNIX域套接字路径,如果想要绑定多个地址使用逗号分隔。 
    # 若要绑定到所有IPv4地址,请输入0.0.0.0。与net.bindIpAll配置互斥,不能同时配置两个。 
    # 类型: string。默认: localhost 
    bindIp: 127.0.0.1,172.23.102.56 / 127.0.0.1,172.23.102.57 / 127.0.0.1,172.23.102.58 #这里三个设备分别对应 
security: 
    # 密钥文件的路径,它存储MongoDB实例在共享的集群或副本集中相互验证的共享密钥。类型: string 
    keyFile: /usr/local/mongodb/keyFile.file 
    # 集群成员之间的认证模式。类型: string。可选: keyFile、sendKeyFile、sendX509、x509。默认: keyFile。 
    clusterAuthMode: keyFile 
setParameter: 
    # 如果开启,则允许本机(localhost/127.0.0.1)第一次访问时不需要密码认证,以便于创建第一个admin数据库的用户 
    # true/1或者false/0,默认为true。mongods和mongod有效,建议mongod关闭该功能。 
    enableLocalhostAuthBypass: true 
    # 认证机制,可选值为“SCRAM-SHA-1”、“MONGODB-CR”、“PLAN”等,建议为“SCRAM-SHA-1” 
    authenticationMechanisms: SCRAM-SHA-1 sharding: 
    # 配置分片块大小,默认64(MB)。MongoDB 3.4已删除该配置。 
    # chunkSize: 64 
    # 配置服务器副本集地址。MongoDB 3.2必须将配置服务部署为副本集, 
    # 配置服务副本必须以默认的WiredTiger存储引擎存储。 
    configDB: config/172.23.102.56:21018,172.23.102.57:21018,172.23.102.58:21018

分别启动三个机器上的mongos server,当然也可以只启动一个,一个客户端也只能连接一个mongos:

[root@abc] mongos --config /usr/local/mongodb/config/mongos.conf

当mongos服务都启动之后登入服务,我们创建集群用户注意这里同样只有一次机会。mongos没有security.authorization配置,一般如果集群成员之间需要进行鉴权,那么mongos就会启用security相关配置,这样mongos就必须要进行用户名和密码认证了:

[root@abc] mongo 
... 
> use admin 
... 
> db.createUser({user: "root", pwd: "root", roles: [{role: "root", db: "admin"}]}) 
... 
> db.auth("root", "root") 
...

接下来将副本集添加到集群中(其实就是保存在配置服务中):

[root@abc] mongo --port >> .addShard(> .addShard(> .addShard(> .status()  #查看集群状态
...

至此MongoDB分片和副本集集群已搭建完成。MongoDB数据库默认会有一个主分片,如果没有指明数据库中的集合十分片集合,那么该数据库的所有集合和文档都默认会存储在这个主分片之上。接下来我们来启用分片集合,首先指明一个数据库是分片数据库:

>> db.auth(, > .enableSharding(> .status()  # 查看分片情况
...

注意,这里如果被启用分片的数据库不存在,那么MongoDB会自动创建该数据库。这里虽然启用了分片,但还得指明是哪个集合需要分片,使用集合里面的那一个字段作为片键,以什么方式进行分片:

[root@abc] mongo 
... 
> use admin 
... 
> db.auth("root", "root") 
... 
> sh.enableSharding("testdb")  # 指明testdb库启用分片 
... 
> sh.status()  # 查看分片情况 
... 
# 指定testdb库下面的mycollection集合以username字段为片键进行hash分片 
> sh.shardCollection("testdb.mycollection", {"username": "hashed"}) 
... 
> sh.status()  # 查看分片情况 
...

这里使用的分片测是hash分片,适合大规模插入、高并发、数据能够平均分布可充分利用整个集群的性能。还可以进行范围分片和指定分片(指定拿一些片键存储在那个分片上)等策略进行分片,建议线上大规模读写情况下使用hash分片。接下来可以批量插入一些数据,然后查看集合情况:

[root@abc] mongo 
... 
> use admin 
... 
> db.auth("root", "root") 
... 
> sh.enableSharding("testdb")  # 指明testdb库启用分片 
... 
> sh.status()  # 查看分片情况 
... 
# 指定testdb库下面的mycollection集合以username字段为片键进行hash分片 
> sh.shardCollection("testdb.mycollection", {"username": "hashed"}) 
... 
> sh.status()  # 查看分片情况 
... 
> use testdb 
... 
> db.mycollection.stats() 
...

注意,分片集合的片键必须有索引。在给集合分片的时候,如果集合不存则会自动创建集合,然后为片键创建索引。如果集合存在并且已经有了数据,那么就必须手动为片键创建索引,才能为集合分片成功。集合一旦分片成功,片键是不能够修改的,所以选择片键的时候需要谨慎。至此集合分片完成。

如果后期需要直接访问testdb数据库,则必须在testdb数据库下创建用户。注意用户信息是全部存储在admin数据库下的,用户必须归属为某一个数据库,admin数据库下的用户可以操作所有数据库,但是直接在非admin数据库下对admin数据库的用户进行认证是不成功的,必须要先切换到admin下进行认证然后在切换到其他库才可,如果想直接认证则必须在需要认证的数据库下创建用户:

[root@abc] mongo 
... 
> use admin 
... 
> db.auth("root", "root") 
... 
> use testdb 
... 
# 注意只有admin数据库才有root角色,其他数据库的管理类角色可以选择:dbOwner、dbAdmin、userAdmin等 
> db.createUser({user: "testdb", pwd: "testdb", roles: [{role: "dbOwner", db: "testdb"}]}) 
... 
# 可以切换到admin数据库下查看用户信息 
> use admin 
... 
> db.system.users.find({}) 
... 
# 也可以删除用户 
> db.system.users.remove({ _id: "...", user: "..." }) 
...

六、配置说明

   yaml配置中,缩进只能只用空格,不可以使用tab键。如果需要查阅跟多配置相关的信息,请翻阅MongoDB官方手册: https://docs.mongodb.com/manual/reference/configuration-options/

七、性能优化

  说到性能,那么肯定就是和硬件以及操作系统的设置有关了。首先说到硬盘如果是存储日志这种只需要顺序读写的数据,那么最好使用SATA类型硬盘。如果是存储数据库数据文件,这种文件都是随机读写,那么最好肯定就是SSD了。

  每个进程(或线程)都会从父进程继承NUMA策略,并分配有一个优先node。如果NUMA策略允许的话,进程可以调用其他node上的资源。NUMA的CPU分配策略有cpunodebind、physcpubind。cpunodebind规定进程运行在某几个node之上,而physcpubind可以更加精细地规定运行在哪些核上。NUMA的内存分配策略有localalloc、preferred、membind、interleave。localalloc规定进程从当前node上请求分配内存;而preferred比较宽松地指定了一个推荐的node来获取内存,如果被推荐的node上没有足够内存,进程可以尝试别的node。membind可以指定若干个node,进程只能从这些指定的node上请求分配内存。interleave规定进程从指定的若干个node上以RR算法交织地请求分配内存。

  NUMA的内存分配策略对于进程(或线程)之间来说,并不是公平的。在现有的Redhat Linux中,localalloc是默认的NUMA内存分配策略,这个配置选项导致资源独占程序很容易将某个node的内存用尽。而当某个node的内存耗尽时,Linux又刚好将这个node分配给了某个需要消耗大量内存的进程(或线程),swap就妥妥地产生了。尽管此时还有很多page cache可以释放,甚至还有很多的free内存。要解决这个问题,直接在启动mongodb之前加上:numactl --interleave=all命令即可。由于只有mognod组建才需要存储数据,所以只有在启动配置服务和分片服务时才需要加上该参数。

  还可以优化内核参数,针对内核参数overcommit_memory,可选值:0(内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程)、1(表示内核允许分配所有的物理内存,而不管当前的内存状态如何)、2(表示内核允许分配超过所有物理内存和交换空间总和的内存),这里最好设置为0,即执行:echo 1 > /proc/sys/vm/overcommit_memory。针对zone_reclaim_mode内核参数,可选值为0(当某个节点可用内存不足时,那么系统会倾向于从其他节点分配内存)、1(当某个节点可用内存不足时,那么系统会倾向于从本地节点回收Cache内存多数时候),缓存对性能很重要,所以最好选择0,即执行:echo 0 > /proc/sys/vm/zone_reclaim_mode

发布评论

分享到:

IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

大厂们的 redis 集群方案详解
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。