mongoDB入门实战

2017年8月1日

原文:http://www.cnblogs.com/biglittleant/p/7267357.html

mongoDB入门实战

 

mongod-入门

摘要:
本篇文档,带你快速启动一个mongod,到搭建主从+复制集模式的入门。
内容包括:单实例安装,复制集构建,分片构建,分片及复制集整合。

软件相关信息介绍

MongoDB 是一款开源的文档数据库,并且是业内领先的 NoSQL 数据库,用 C++ 编写而成。

软件包介绍

MongoDB 提供的官方支持的软件包是在自己的软件库中编译的。软件库通过软下列件包提供 MongoDB 相关软件。

  • mongodb-org: 这个包是一个 元包 ( metapackage ),它会自动安装下列4个软件包。
  • mongodb-org-server: 这个软件包中包含 mongod 守护进程和相关的配置以及初始化脚本。
  • mongodb-org-mongos: 这个包中包含 mongos 守护进程。
  • mongodb-org-shell: 这个包中包含 mongo 命令行工具。
  • mongodb-org-tools:这个包中包含下列 MongoDB 工具: mongoimport bsondump, mongodump, mongoexport, mongofiles, mongoimport, mongooplog, mongoperf, mongorestore, mongostat, and mongotop

mongodb功能

  1. 面向集合的存储:适合存储对象及 JSON 形式的数据。
  2. 动态查询:MongoDB 支持丰富的查询表达式。查询指令使用 JSON 形式的标记,可轻易查询文档中内嵌的对象及数组。
  3. 完整的索引支持:包括文档内嵌对象及数组。MongoDB 的查询优化器会分析查询表达式,并生成一个高效的查询计划。
  4. 查询监视:MongoDB 包?一系列监视工具用于分析数据库操作的性能。
  5. 复制及自动故障转移:MongoDB 数据库支持服务器之间的数据复制,支持主-从模式及服务器之间的相互复制。复制的主要目标是提供冗余及自动故障转移。
  6. 高效的传统存储方式:支持二进制数据及大型对象(如照片或图片)。
  7. 自动分片以支持云级?的伸缩性:自动分片功能支持水平的数据库集群,可动态添加额外的机器。

适合场景

  • 网站数据:MongoDB 非常适合实时的插入,更新与查询,并具备网站实时数据存储所 需的复制及高度伸缩性。
  • 缓存:由于性能很高,MongoDB 也适合作为信息基础设施的缓存层。在系统重启之后, 由 MongoDB 搭建的持久化缓存层可以避免下层的数据源过载。
  • ?大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵,在 此之前,很多时候程序员往往会选择传统的文件进行存储。
  • 高伸缩性的场景:MongoDB 非常适合由数十或数百台服务器组成的数据库。MongoDB 的路线图中已经包?对 MapReduce 引擎的内置支持。
  • 用于对象及 JSON 数据的存储:MongoDB 的 BSON 数据格式非常适合文档化格式的存储及查询。

数据逻辑结构

  • MongoDB 的逻辑结构是一种层次结构。主要由: 文档(document)、集合(collection)、数据库(database)这三部分组成的。逻辑结构是面向用户 的,用户使用 MongoDB 开发应用程序使用的就是逻辑结构。
  • MongoDB 的文档(document),相当于关系数据库中的一行记录。
  • ?多个文档组成一个集合(collection),相当于关系数据库的表。
  • 多个集合(collection),逻辑上组织在一起,就是数据库(database)。一个 MongoDB 实例支持多个数据库(database)。

逻辑结构对比

MongoDB 关系型数据库
文档(document) 行(ROW)
集合(collection) 表(table)
数据库(database) 数据库(database)

数据存储结构

MongoDB 的默认数据目录是/data/db,它负责存储所有的 MongoDB 的数据文件。在 MongoDB 内部,每个数据库都包?一个.ns 文件和一些数据文件,而且这些数据文件会随着数据量的 增加而变得越来越多。所以如果系统中有一个叫做 foo 的数据库,那么构成 foo 这个数据库 的文件就会由 foo.ns,foo.0,foo.1,foo.2 等等组成,具体如下:

[root@localhost db]# ll /data/db/
-rw------- 1 root root 16777216 04-21 17:30 foo.0
-rw------- 1 root root 33554432 04-21 17:30 foo.1
-rw------- 1 root root 67108864 04-21 17:30 foo.2
-rw------- 1 root root 16777216 04-21 17:30 foo.ns

MongoDB 内部有预分配空间的机制,每个预分配的文件都用 0 进行填充,由于有了这个机制, MongoDB 始终保持额外的空间和空余的数据文件,从而有效避免了由于数据暴增而带来 的磁盘压力过大的问题。
由于表中数据量的增加,数据文件每新分配一次,它的大小都会是上一个数据文件大小的 2 倍,每个数据文件最大 2G。这样的机制有利于防止较小的数据库浪费过多的磁盘空间,同 时又能保证较大的数据库有相应的预留空间使用。
数据库的每张表都对应一个命名空间,每个索引也有对应的命名空间。这些命名空间的元数据都集中在*.ns 文件中。

mongod实战

mongodb 在 bin目录下的工具简介:

  • ? bsondump: 将 bson 格式的文件转储为 json 格式的数据。
  • mongo: 客户端命令行工具,其实也是一个 js 解释器,支持 js 语法。
  • mongod: 数据库服务端,每个实例启动一个进程,可以 fork 为后台运行。
  • mongodump/ mongorestore: 数据库备份和恢复工具。
  • mongoexport/ mongoimport: 数据导出和导入工具。
  • mongofiles: GridFS 管理工具,可实现二制文件的存取。
  • mongos: 分片路由,如果使用了 sharding 功能,则应用程序连接的是mongos 而不是 mongod。
  • mongosniff: 这一工具的作用类似于tcpdump,不同的是他只监控MongoDB相关的包请 求,并且是以指定的可读性的形式输出。
  • mongostat: 实时性能监控工具。

单实例配置

cd /usr/lcoal/src
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-3.4.6.tgz
tar -zxf mongodb-linux-x86_64-rhel70-3.4.6.tgz 
mv mongodb-linux-x86_64-rhel70-3.4.6 /data/app/
ln -s /data/app/mongodb-linux-x86_64-rhel70-3.4.6 /data/app/mongod
mkdir /data/app/mongod/{db,logs,config}
cat >/data/app/mongod/config/mongo.conf <<EOF
# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /data/app/mongod/logs/mongod.log

# Where and how to store data.
storage:
  dbPath: /data/app/mongod/db
  journal:
    enabled: true
#  engine:
#  mmapv1:
#  wiredTiger:

# how the process runs
processManagement:
  fork: true
  pidFilePath: /data/app/mongod/mongod.pid

# network interfaces
net:
  port: 27017
  bindIp: 192.168.56.13
EOF
/data/app/mongod/bin/mongod --config /data/app/mongod/config/mongo.conf

查看日志文件cat /data/app/mongod/logs/mongod.log出现如下字样,表示启动成功。

[initandlisten] waiting for connections on port <port>

mongodb复制集配置

  • 安装包参考上面的单实例安装。
  • 下面的命令在三台服务器上批量执行。
mkdir /data/app/mongod/db/replset -p
cat >/data/app/mongod/config/replset.conf <<EOF
# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /data/app/mongod/logs/replset.log

# Where and how to store data.
storage:
  dbPath: /data/app/mongod/db/replset
  directoryPerDB: true
  journal:
    enabled: true

# how the process runs
processManagement:
  fork: true
  pidFilePath: /data/app/mongod/replset.pid

# network interfaces
net:
  port: 22000
  bindIp: 0.0.0.0
replication:
  replSetName: replset0
EOF

启动三台服务器的mongod服务

/data/app/mongod/bin/mongod --config /data/app/mongod/config/replset.conf  
### 检查端口是否启动
ss -lntup |grep 22000

连接一台mongod服务,配置相关分片设置

/data/app/mongod/bin/mongo --host 192.168.56.11 --port 22000

rs.initiate(
{
   "_id" : "replset0",
   "version" : 1,
   "members" : [
      {
         "_id" : 1,
         "host" : "192.168.56.11:22000"
      }
   ]
}
)

rs.add("192.168.56.12:22000")
rs.add("192.168.56.13:22000")

查看集群分片状态

/data/app/mongod/bin/mongo --host 192.168.56.11 --port 22000
rs.conf() ## 查看集群配置信息
replset0:PRIMARY> rs.status()
{
        "set" : "replset0",
        "date" : ISODate("2017-08-01T02:48:51.672Z"),
        "myState" : 1,
        "term" : NumberLong(1),
        "heartbeatIntervalMillis" : NumberLong(2000),
        "optimes" : {
                "lastCommittedOpTime" : {
                        "ts" : Timestamp(1501555722, 1),
                        "t" : NumberLong(1)
                },
                "appliedOpTime" : {
                        "ts" : Timestamp(1501555722, 1),
                        "t" : NumberLong(1)
                },
                "durableOpTime" : {
                        "ts" : Timestamp(1501555722, 1),
                        "t" : NumberLong(1)
                }
        },
        "members" : [
                {
                        "_id" : 1,
                        "name" : "192.168.56.11:22000",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 397,
                        "optime" : {
                                "ts" : Timestamp(1501555722, 1),
                                "t" : NumberLong(1)
                        },
                        "optimeDate" : ISODate("2017-08-01T02:48:42Z"),
                        "electionTime" : Timestamp(1501555501, 2),
                        "electionDate" : ISODate("2017-08-01T02:45:01Z"),
                        "configVersion" : 3,
                        "self" : true
                },
                {
                        "_id" : 2,
                        "name" : "192.168.56.12:22000",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 186,
                        "optime" : {
                                "ts" : Timestamp(1501555722, 1),
                                "t" : NumberLong(1)
                        },
                        "optimeDurable" : {
                                "ts" : Timestamp(1501555722, 1),
                                "t" : NumberLong(1)
                        },
                        "optimeDate" : ISODate("2017-08-01T02:48:42Z"),
                        "optimeDurableDate" : ISODate("2017-08-01T02:48:42Z"),
                        "lastHeartbeat" : ISODate("2017-08-01T02:48:50.961Z"),
                        "lastHeartbeatRecv" : ISODate("2017-08-01T02:48:49.953Z"),
                        "pingMs" : NumberLong(0),
                        "syncingTo" : "192.168.56.11:22000",
                        "configVersion" : 3
                },
                {
                        "_id" : 3,
                        "name" : "192.168.56.13:22000",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 184,
                        "optime" : {
                                "ts" : Timestamp(1501555722, 1),
                                "t" : NumberLong(1)
                        },
                        "optimeDurable" : {
                                "ts" : Timestamp(1501555722, 1),
                                "t" : NumberLong(1)
                        },
                        "optimeDate" : ISODate("2017-08-01T02:48:42Z"),
                        "optimeDurableDate" : ISODate("2017-08-01T02:48:42Z"),
                        "lastHeartbeat" : ISODate("2017-08-01T02:48:51.031Z"),
                        "lastHeartbeatRecv" : ISODate("2017-08-01T02:48:50.225Z"),
                        "pingMs" : NumberLong(0),
                        "syncingTo" : "192.168.56.12:22000",
                        "configVersion" : 3
                }
        ],
        "ok" : 1
}

mongodb分片配置

要构建一个 MongoDB Sharding Cluster,需要三种角色:
? Shard Server
即存储实际数据的分片,每个 Shard 可以是一个 mongod 实例,也可以是一组 mongod 实例 构成的 Replica Set。为了实现每个 Shard 内部的 auto-failover,MongoDB 官方建议每个 Shard 为一组 Replica Set。
? Config Server
为了将一个特定的 collection 存储在多个 shard 中,需要为该 collection 指定一个 shard key, 例如{age: 1} ,shard key 可以决定该条记录属于哪个 chunk。Config Servers 就是用来存储: 所有 shard 节点的配置信息、每个 chunk 的 shard key 范围、chunk 在各 shard 的分布情况、 该集群中所有 DB 和 collection 的 sharding 配置信息。
? Route Process
这是一个前端路由,客户端由此接入,然后询问 Config Servers 需要到哪个 Shard 上查询或 保存记录,再连接相应的 Shard 进行操作,最后将结果返回给客户端。客户端只需要将原本 发给 mongod 的查询或更新请求原封不动地发给 Routing Process,而不必关心所操作的记录 存储在哪个 Shard 上。

何时分片:

  • 机器的磁盘不够用了。
  • 单个mongod已经不能满足写数据的性能需要了。
  • 想将大量数据放在内存中提高性能。

创建相关目录

mkdir -p /data/app/mongod/db/{shard0,shard1,config}

编写相应的配置文件:

cat >/data/app/mongod/config/shard0.conf <<EOF
# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /data/app/mongod/logs/shard0.log

# Where and how to store data.
storage:
  dbPath: /data/app/mongod/db/shard0
  directoryPerDB: true
  journal:
    enabled: true

# how the process runs
processManagement:
  fork: true
  pidFilePath: /data/app/mongod/shard0.pid

# network interfaces
net:
  port: 20000
  bindIp: 192.168.56.13
replication:
  replSetName: rs0
sharding:
  clusterRole: shardsvr
EOF
cat >/data/app/mongod/config/shard1.conf <<EOF
# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /data/app/mongod/logs/shard1.log

# Where and how to store data.
storage:
  dbPath: /data/app/mongod/db/shard1
  directoryPerDB: true
  journal:
    enabled: true

# how the process runs
processManagement:
  fork: true
  pidFilePath: /data/app/mongod/shard1.pid

# network interfaces
net:
  port: 20001
  bindIp: 192.168.56.13
replication:
  replSetName: rs0
sharding:
  clusterRole: shardsvr
EOF

启动config server

 cat >/data/app/mongod/config/config.conf <<EOF
# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /data/app/mongod/logs/config.log

# Where and how to store data.
storage:
  dbPath: /data/app/mongod/db/config
  directoryPerDB: true
  journal:
    enabled: true

# how the process runs
processManagement:
  fork: true
  pidFilePath: /data/app/mongod/config.pid

# network interfaces
net:
  port: 30000
  bindIp: 192.168.56.13
replication:
  replSetName: configRS
sharding:
  clusterRole: configsvr
EOF

启动mongod配置:

/data/app/mongod/bin/mongod --config /data/app/mongod/config/shard0.conf  
/data/app/mongod/bin/mongod --config /data/app/mongod/config/shard1.conf  
/data/app/mongod/bin/mongod --config /data/app/mongod/config/config.conf  

初始化config服务

/data/app/mongod/bin/mongo --host 192.168.56.13 --port 30000
 rs.initiate(
  {
    _id: "configRS",
    configsvr: true,
    members: [
      { _id : 0, host : "192.168.56.13:30000" },
    ]
  }
)

初始化shard分片服务

/data/app/mongod/bin/mongo --host 192.168.56.13 --port 20000
rs.initiate(
  {
    _id : "rs0",
    members: [
      { _id : 0, host : "192.168.56.13:20000" },
    ]
  }
)

/data/app/mongod/bin/mongo --host 192.168.56.13 --port 20001
rs.initiate(
  {
    _id : "rs1",
    members: [
      { _id : 0, host : "192.168.56.13:20001" },
    ]
  }
)

启动route server

 cat >/data/app/mongod/config/route.conf <<EOF
# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /data/app/mongod/logs/route.log

# how the process runs
processManagement:
  fork: true
  pidFilePath: /data/app/mongod/route.pid

# network interfaces
net:
  port: 40000
  bindIp: 192.168.56.13
sharding:
  configDB: configRS/192.168.56.13:30000
EOF
/data/app/mongod/bin/mongos --config /data/app/mongod/config/route.conf

配置分片服务设置

/data/app/mongod/bin/mongo --host 192.168.56.13 --port 40000
sh.addShard( "rs0/192.168.56.13:20000")
sh.addShard( "rs1/192.168.56.13:20001")
sh.enableSharding("test")
sh.shardCollection("test.users", { _id:1 } )

如何配置分片

分片和复制集整合配置

根据Replica Set、Sharding策略部署mongod。将两个sharding组部署到三台服务器上,每个sharding组有三个replica set成员。

前提:保证三台服务器时间相同。

服务器规划

主机名 shard0 shard1 config route
192.168.56.11 20000 20001 30000 40000
192.168.56.12 20000 20001 30000 40000
192.168.56.13 20000 20001 30000 40000

初始化三台机器的mongod实例
三台服务器上都执行

cd /usr/lcoal/src
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-3.4.6.tgz
tar -zxf mongodb-linux-x86_64-rhel70-3.4.6.tgz 
mv mongodb-linux-x86_64-rhel70-3.4.6 /data/app/
ln -s /data/app/mongodb-linux-x86_64-rhel70-3.4.6 /data/app/mongod
mkdir /data/app/mongod/{db,logs,config}
mkdir -p /data/app/mongod/db/{shard0,shard1,config}

在三台服务器上批量执行如下命令:

先创建两台shard实例

cat >/data/app/mongod/config/shard0.conf <<EOF
# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /data/app/mongod/logs/shard0.log

# Where and how to store data.
storage:
  dbPath: /data/app/mongod/db/shard0
  directoryPerDB: true
  journal:
    enabled: true

# how the process runs
processManagement:
  fork: true
  pidFilePath: /data/app/mongod/shard0.pid

# network interfaces
net:
  port: 20000
  bindIp: 0.0.0.0
replication:
  replSetName: rs0
sharding:
  clusterRole: shardsvr
EOF
cat >/data/app/mongod/config/shard1.conf <<EOF
# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /data/app/mongod/logs/shard1.log

# Where and how to store data.
storage:
  dbPath: /data/app/mongod/db/shard1
  directoryPerDB: true
  journal:
    enabled: true

# how the process runs
processManagement:
  fork: true
  pidFilePath: /data/app/mongod/shard1.pid

# network interfaces
net:
  port: 20001
  bindIp: 0.0.0.0
replication:
  replSetName: rs1
sharding:
  clusterRole: shardsvr
EOF

启动config server

 cat >/data/app/mongod/config/config.conf <<EOF
# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /data/app/mongod/logs/config.log

# Where and how to store data.
storage:
  dbPath: /data/app/mongod/db/config
  directoryPerDB: true
  journal:
    enabled: true

# how the process runs
processManagement:
  fork: true
  pidFilePath: /data/app/mongod/config.pid

# network interfaces
net:
  port: 30000
  bindIp: 0.0.0.0
replication:
  replSetName: configRS
sharding:
  clusterRole: configsvr
EOF

启动shard0,shard1,config服务:

/data/app/mongod/bin/mongod --config /data/app/mongod/config/shard0.conf  
/data/app/mongod/bin/mongod --config /data/app/mongod/config/shard1.conf  
/data/app/mongod/bin/mongod --config /data/app/mongod/config/config.conf  

连上其中一台服务器的config端口,配置实例化参数,让三台config互相认识。

/data/app/mongod/bin/mongo --host 192.168.56.11 --port 30000
rs.initiate(
 {
   _id: "configRS",
   configsvr: true,
   members: [
     { _id : 0, host : "192.168.56.11:30000" },
     { _id : 1, host : "192.168.56.12:30000" },
     { _id : 2, host : "192.168.56.13:30000" },
   ]
 }
)
/data/app/mongod/bin/mongo --host 192.168.56.11 --port 20000
rs.initiate(
  {
    _id : "rs0",
    members: [
      { _id : 0, host : "192.168.56.11:20000" },
      { _id : 1, host : "192.168.56.12:20000" },
      { _id : 2, host : "192.168.56.13:20000" },
    ]
  }
)

/data/app/mongod/bin/mongo --host 192.168.56.11 --port 20001
rs.initiate(
  {
    _id : "rs1",
    members: [
      { _id : 0, host : "192.168.56.11:20001" },
      { _id : 1, host : "192.168.56.12:20001" },
      { _id : 2, host : "192.168.56.13:20001" },
    ]
  }
)

配置route服务器

 cat >/data/app/mongod/config/route.conf <<EOF
# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /data/app/mongod/logs/route.log

# how the process runs
processManagement:
  fork: true
  pidFilePath: /data/app/mongod/route.pid

# network interfaces
net:
  port: 40000
  bindIp: 0.0.0.0
sharding:
  configDB: configRS/192.168.56.11:30000,192.168.56.12:30000,192.168.56.13:30000
EOF

启动route server

/data/app/mongod/bin/mongos --config /data/app/mongod/config/route.conf

配置分片服务设置

/data/app/mongod/bin/mongo --host 192.168.56.11 --port 40000
sh.addShard( "rs0/192.168.56.11:20000,192.168.56.12:20000,192.168.56.13:20000")
sh.addShard( "rs1/192.168.56.11:20001,192.168.56.12:20001,192.168.56.13:20001")
sh.enableSharding("test")
sh.shardCollection("test.users", { _id:1 } 

要使单个Collection分片存储,需要给Collection指定一个分片key。

  1. 分片的collection系统会自动创建一个索引(也可用户提前创建好)
  2. 分片的collection只能有一个在分片key上的唯一索引,其它唯一索引不被允许

检查shard分片结果是否正常

mongos> use admin;
switched to db admin
mongos> db.runCommand( { listshards : 1 } );
{
        "shards" : [
                {
                        "_id" : "rs0",
                        "host" : "rs0/192.168.56.11:20000,192.168.56.12:20000,192.168.56.13:20000",
                        "state" : 1
                },
                {
                        "_id" : "rs1",
                        "host" : "rs1/192.168.56.11:20001,192.168.56.12:20001,192.168.56.13:20001",
                        "state" : 1
                }
        ],
        "ok" : 1
}
mongos> 

如果列出(sharding)了以上二个你加的shards,表示shards已经配置成功。

查看Sharding状态

use admin;
db.printShardingStatus();

来查看分片状态。

use test;
db.users.stats();

总结:

  1. 一个或多个分片,其中每个分片持有部分数据(自动管理)。读写操作自动路由到合适的分片上。每个分片是一个replica set。
  2. 一个replica set是一台或多台服务器,每台机器持有相同数据的拷贝。在特定的时间点,一台机器是主节点而其他机器是从节点。如果主节点死掉了,其中一台从节点自动接管为主节点。所有的写操作和一致性读操作都进入主节点,而所有的最终一致性读操作分布到所有从节点上。
  3. 多台配置服务器,其中每台配置服务器持有表明数据位于哪个分片的元数据的拷贝。
  4. 一个或多个路由器,其中每个路由器都作为一个或多个客户端的服务器。客户端向路由器发起查询和更新,路由器询问配置服务器后将请求分发到合适的分片上。
  5. 一个或多个客户端,其中每个客户端都是用户应用程序的一部分,它使用自身语言的mongo客户端驱动向路由器发起请求。
  6. 当集群中某个分片宕掉以后,只要不涉及到该节点的操纵仍然能进行。当宕掉的节点重启后,集群能自动从故障中恢复过来。

帮助文档

官方文档配置文件的解释
如何配置分片

附录

mongod 2.x 配置文件解释

  • replSet=setname
  • oplogSize=1024复制集log的大小。
  • keyFile=/path/to/keyfile: 指定存储身份验证信息的密钥文件的路径。

  • logpath=/var/log/mongodb/mongod.log: log文件路径。
  • logappend=true: 以追加方式写入日志。
  • fork=true: 是否以守护进程方式运行
  • port=27017: 默认27017
  • dbpath=/var/lib/mongo: 数据库文件位置
  • pidfilepath=/var/run/mongodb/mongod.pid: PID文件的位置
  • bind_ip=127.0.0.1: 配置监听的端口。
  • nojournal=true: Disables write-ahead journaling。
  • cpu=true: 启用定期记录CPU利用率和 I/O 等待
  • noauth=true: 以不安全认证方式运行,默认是不认证的非安全方式
  • auth=true: 以安全认证方式运行。
  • verbose=true: 详细记录输出
  • objcheck=true: 用于开发驱动程序时验证客户端请求
  • quota=true: 启用数据库配额管理
  • diaglog=0: 设置oplog记录等级

    • 0=off (default)
    • 1=W
    • 2=R
    • 3=both
    • 7=W+some reads
  • nohints=true: 忽略查询提示
  • httpinterface=true: 禁用http界面,默认为localhost:28017
  • noscripting=true: 关闭服务器端脚本,这将极大的限制功能
  • notablescan=true: 关闭扫描表,任何查询将会是扫描失败
  • noprealloc=true: 关闭数据文件预分配
  • nssize=<size>: 为新数据库指定.ns文件的大小,单位:MB
  • directoryPerDB: true: 是否一个库一个文件夹

mongod主从配置

复制集模式官方已经不推荐,推荐使用分片,或者分片加复制集

master 服务器写入配置文件

cat >/data/app/mongodb/config/mongo.conf <<EOF
logpath=/data/app/mongodb/logs/mongod.log
logappend=true
fork=true
port=27017
dbpath=/data/app/mongodb/db
pidfilepath=/data/app/mongodb/mongod.pid
bind_ip=192.168.56.12
nojournal=true
verbose=true
master=true
EOF

slave 服务器写入配置

cat >/data/app/mongodb/config/mongo.conf <<EOF
logpath=/data/app/mongodb/logs/mongod.log
logappend=true
fork=true
port=27017
dbpath=/data/app/mongodb/db
pidfilepath=/data/app/mongodb/mongod.pid
bind_ip=192.168.56.13
nojournal=true
verbose=true
slave = true  
source = 192.168.56.12:27017 
EOF

关键参数

  • master=true
  • slave=true
  • source=192.168.56.12:27017

报错汇总

报错一:第一次连接数据库时报错。

[root@localhost etc]# /application/mongodb/bin/mongo
MongoDB shell version: 3.0.4
connecting to: test
Server has startup warnings: 

[initandlisten] 
[initandlisten] ** WARNING: Readahead for /data/db/ is set to 4096KB
[initandlisten] **          We suggest setting it to 256KB (512 sectors) or less
[initandlisten] **          http://dochub.mongodb.org/core/readahead
[initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
[initandlisten] 
[initandlisten] 
[initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
[initandlisten] **        We suggest setting it to 'never'
[initandlisten] 
[initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
[initandlisten] **        We suggest setting it to 'never'
[initandlisten] 
> 

解决办法:
默认:

[root@localhost etc]# cat /sys/kernel/mm/transparent_hugepage/enabled 
[always] madvise never
[root@localhost etc]# cat /sys/kernel/mm/transparent_hugepage/defrag 
[always] madvise never

更改为:

echo "never" > /sys/kernel/mm/transparent_hugepage/enabled
echo "never" > /sys/kernel/mm/transparent_hugepage/defrag

结果:

[root@localhost etc]# cat /sys/kernel/mm/transparent_hugepage/enabled            
always madvise [never]
[root@localhost etc]# cat /sys/kernel/mm/transparent_hugepage/defrag            
always madvise [never]

报错二:插入数据是报错:

for ( var i = 1; i < 10; i++ ) db.things.save(n:7,h:i);
2015-06-29T22:22:27.689+0800 E QUERY    SyntaxError: Unexpected token :

解决办法:格式错误。

for ( var i = 1; i < 10; i++ ) db.things.save( { n:7,h:i } );
WriteResult({ "nInserted" : 1 })

报错三:初始化复制集报错:

> rs.initiate(config_rs1);
{
        "ok" : 0,
        "errmsg" : "replSetInitiate quorum check failed because not all proposed set members responded affirmatively: localhost:28012 failed with not running with --replSet",
        "code" : 74
}
> exit

解决办法:

/application/mongodb/bin/mongod --replSet rs1 --keyFile /data/key/r2 --fork --port 28012 --dbpath /data/data/r2 --logpath=/data/log/r2.log --logappend

报错四:在从节点上删除另一个从节点报错:

rs1:SECONDARY> rs.remove("localhost:28012")
{
        "ok" : 0,
        "errmsg" : "replSetReconfig should only be run on PRIMARY, but my state is SECONDARY; use the \"force\" argument to override",
        "code" : 10107
}
rs1:SECONDARY> 

解决办法:从节点没有权限去更改,rs的配置。

报错五:关闭一个节点在启动复制集时,不能正常启动:

[initandlisten] journal dir=/data/data/r0/journal
[initandlisten] recover : no journal files present, no recovery needed
 [initandlisten] 
[initandlisten] Insufficient free space for journal files
[initandlisten] Please make at least 3379MB available in /data/data/r0/journal or use --smallfiles
initandlisten] 
initandlisten] exception in initAndListen: 15926 Insufficient free space for journals, terminating
[initandlisten] ReplicationCoordinatorImpl::shutdown() called before startReplication() finished.  Shutting down without cleaning up the replication system
[initandlisten] now exiting
[initandlisten] shutdown: go

解决办法:(原因是因为硬盘空间不够了)

/application/mongodb/bin/mongod --config /application/mongodb/etc/mongodb.conf.r0 --smallfiles

报错六:配置分片时,在路由端添加后端真实服务器提示权限错误:

mongos> db.runCommand({addshard:"localhost:20000"})
{
        "ok" : 0,
        "errmsg" : "failed listing localhost:20000's databases:{ ok: 0.0, errmsg: \"not authorized on admin to execute command { listDatabases: 1 }\", code: 13 }"
}

解决办法:开启真实服务器的时候不要加auth选项。

报错七:配置route来管理config服务器的时候,报错:

 error upgrading config database to v6 :: caused by :: Distributed ClockSkewed clock skew of the cluster 192.168.2.145:30000,192.168.2.149:30000,192.168.2.147:30000 is too far out of bounds to allow distributed locking.

解决办法:三台服务器的时间不一样。将服务器时间设置相同。问题解决。

报错八:配置完复制集后,登陆数据库操作,即使在主数据库操作也提示需要认证。

解决办法:
如果 MongoDB 服务器启动时使用了 --auth 或 --keyFile 参数,你就必须在进行任何操作前进行认证。 你可以在连接时进行认证。方法是在链接字符串中指定用户名密码,或者在 MongoClient::__construct() 构造函数中指定 "username" 和 "password"。

因为在配置集群时,使用了keyfile的原因,所以必须使用认证登录。
而不是和 db.auth() 命令有关系。

报错八:IP配置错误

配置--conigdb的时候ip地址不能填localhost或127.0.0.1否则添加分片时会返回如下错误信息:

{
           "ok" : 0,
           "errmsg" : "can't use localhost as a shard since all shards need to communicate. either use all shards and configdbs in localhost or all in actual IPs  host: 192.168.71.43:27017 isLocalHost:0"
}

没有评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注