阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

高可用MongoDB集群部署详解

145次阅读
没有评论

共计 38406 个字符,预计需要花费 97 分钟才能阅读完成。

一、概述
NoSQL,指的是非关系型的数据库。NoSQL 有时也称作 Not Only SQL 的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称。
NoSQL 用于超大规模数据的存储。(例如谷歌或 Facebook 每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。
今天我们可以通过第三方平台(如:Google,Facebook 等)可以很容易的访问和抓取数据。用户的个人信息,社交网络,地理位置,用户生成的数据和用户操作日志已经成倍的增加。我们如果要对这些用户数据进行挖掘,那 SQL 数据库已经不适合这些应用了, NoSQL 数据库的发展也却能很好的处理这些大的数据。
 
NoSQL 的优点
高可扩展性 可以横向扩展也可以纵向扩展
分布式计算
低成本高性能
架构的灵活性,半结构化数据
没有复杂的关系
MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库. 支持类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。所以这个非常方便,我们可以用 sql 操作 MongoDB,从关系型数据库迁移过来,开发人员学习成本会大大减少。如果再对底层的 sql API 做一层封装,开发基本可以感觉不到 mongodb 和关系型数据库的区别。同样 MongoDB 也是号称自己能够快速搭建一个高可用可扩展的的分布式集群。

二、安装配置与应用
MongoDB 可以在 windows 上安装使用,同样支持 linux 平台。我这里选的是 linux 平台安装。
1. 首先下载并解压安装包
curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.6.tgz    # 下载
tar  -zxvf mongodb-linux-x86_64-3.0.6.tgz                  # 解压
mv  mongodb-linux-x86_64-3.0.6/  /usr/local/mongodb            # 将解压包拷贝到指定目录

把 MongoDB 的可执行文件路径加到 PATH 变量中(~/.bash_profile)
PATH=$PATH:$HOME/bin:/usr/local/mongodb/bin

2. 创建所 mongodb 启动需要的路径和文件
mkdir /data/db #创建存放 mongodb 的数据文件夹
mkdir /usr/local/mongodb/logs/ #创建存放 mongodb 日志的文件夹
touch /usr/local/mongodb/logs/mongodb.log #创建存放 mongodb 的日志文件

3. 启动 mongodb 服务。命令窗口直接执行就行
[root@DB ~]# mongod 
2017-11-14T13:14:19.809+0800 I JOURNAL  [initandlisten] journal dir=/data/db/journal
2017-11-14T13:14:19.809+0800 I JOURNAL  [initandlisten] recover : no journal files present, no recovery needed
2017-11-14T13:14:19.815+0800 I JOURNAL  [durability] Durability thread started
2017-11-14T13:14:19.815+0800 I JOURNAL  [journal writer] Journal writer thread started
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] MongoDB starting : pid=4287 port=27017 dbpath=/data/db 64-bit host=DB
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] 
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] 
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is ‘always’.
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] **        We suggest setting it to ‘never’
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] 
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is ‘always’.
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] **        We suggest setting it to ‘never’
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] 
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] ** WARNING: soft rlimits too low. rlimits set to 16384 processes, 65536 files. Number of processes should be at least 32768 : 0.5 times number of files.
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] 
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] db version v3.0.6
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] git version: 1ef45a23a4c5e3480ac919b28afcba3c615488f2
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] build info: Linux build6.ny.cbi.10gen.cc 2.6.32-431.3.1.el6.x86_64 #1 SMP Fri Jan 3 21:39:27 UTC 2014 x86_64 BOOST_LIB_VERSION=1_49
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] allocator: tcmalloc
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] options: {}
2017-11-14T13:14:19.849+0800 I NETWORK  [initandlisten] waiting for connections on port 27017

可以看到 mongodb 服务进程以及启动,开启了 27017 端口等待连接了
另开一个命令窗口,使用 mongo 命令可以与 mongodb 进行交互。由于它是一个 JavaScript Shell,可以输入简单的算术运算测试一下:
[root@DB mongodb]# mongo 
MongoDB shell version: 3.0.6
connecting to: test
Server has startup warnings: 
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] 
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] 
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is ‘always’.
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] **        We suggest setting it to ‘never’
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] 
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is ‘always’.
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] **        We suggest setting it to ‘never’
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] 
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] ** WARNING: soft rlimits too low. rlimits set to 16384 processes, 65536 files. Number of processes should be at least 32768 : 0.5 times number of files.
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] 
> 3+2
5

也可以插入一些简单数据,查询验证:
> db.a.insert({a:1})
WriteResult({“nInserted” : 1})
> db.a.find()
{“_id” : ObjectId(“5a0a7fa7766decd974b3ad3f”), “a” : 1 }
>

三、mongodb 启动命令参数说明
mongod 的主要参数有:
 
–quiet# 安静输出
–port arg# 指定服务端口号,默认端口 27017
–bind_ip arg# 绑定服务 IP,若绑定 127.0.0.1,则只能本机访问,不指定默认本地所有 IP
–logpath arg# 指定 MongoDB 日志文件,注意是指定文件不是目录
–logappend# 使用追加的方式写日志
–pidfilepath arg# PID File 的完整路径,如果没有设置,则没有 PID 文件
–keyFile arg# 集群的私钥的完整路径,只对于 Replica Set 架构有效
–unixSocketPrefix arg# UNIX 域套接字替代目录,(默认为 /tmp)
–fork# 以守护进程的方式运行 MongoDB,创建服务器进程
–auth# 启用验证
–cpu# 定期显示 CPU 的 CPU 利用率和 iowait
–dbpath arg# 指定数据库路径
–diaglog arg# diaglog 选项 0=off 1=W 2=R 3=both 7=W+some reads
–directoryperdb# 设置每个数据库将被保存在一个单独的目录
–journal# 启用日志选项,MongoDB 的数据操作将会写入到 journal 文件夹的文件里
–journalOptions arg# 启用日志诊断选项
–ipv6# 启用 IPv6 选项
–jsonp# 允许 JSONP 形式通过 HTTP 访问(有安全影响)
–maxConns arg# 最大同时连接数 默认 2000
–noauth# 不启用验证
–nohttpinterface# 关闭 http 接口,默认关闭 27018 端口访问
–noprealloc# 禁用数据文件预分配(往往影响性能)
–noscripting# 禁用脚本引擎
–notablescan# 不允许表扫描
–nounixsocket# 禁用 Unix 套接字监听
–nssize arg (=16)# 设置信数据库.ns 文件大小(MB)
–objcheck# 在收到客户数据, 检查的有效性,
–profile arg# 档案参数 0=off 1=slow, 2=all
–quota# 限制每个数据库的文件数,设置默认为 8
–quotaFiles arg# number of files allower per db, requires –quota
–rest# 开启简单的 rest API
–repair# 修复所有数据库 run repair on all dbs
–repairpath arg# 修复库生成的文件的目录, 默认为目录名称 dbpath
–slowms arg (=100)# value of slow for profile and console log
–smallfiles# 使用较小的默认文件
–syncdelay arg (=60)# 数据写入磁盘的时间秒数(0=never, 不推荐)
–sysinfo# 打印一些诊断系统信息
–upgrade# 如果需要升级数据库  * Replicaton 参数
 
——————————————————————————–
 
–fastsync# 从一个 dbpath 里启用从库复制服务,该 dbpath 的数据库是主库的快照,可用于快速启用同步
–autoresync# 如果从库与主库同步数据差得多,自动重新同步,
–oplogSize arg# 设置 oplog 的大小(MB)  * 主 / 从参数
 
——————————————————————————–
 
–master# 主库模式
–slave# 从库模式
–source arg# 从库 端口号
–only arg# 指定单一的数据库复制
–slavedelay arg# 设置从库同步主库的延迟时间  * Replica set(副本集) 选项:
 
——————————————————————————–
 
–replSet arg# 设置副本集名称  * Sharding(分片)选项
 
——————————————————————————–
–configsvr# 声明这是一个集群的 config 服务, 默认端口 27019,默认目录 /data/configdb
–shardsvr# 声明这是一个集群的分片, 默认端口 27018
–noMoveParanoia# 关闭偏执为 moveChunk 数据保存
 
可以把上述参数都写进 mongodb.conf 配置文件里:
[root@DB mongodb]# cat mongodb.conf 
dbpath=/data/db
logpath=/usr/local/mongodb/logs/mongodb.log
logappend=true
port=27017
fork=true
auth=false
nohttpinterface=false
bind_ip=192.168.221.160
journal=true
quiet=true

启动的时候使用 -f���数引用这个位置即可
[root@DB mongodb]# mongod -f /usr/local/mongodb/mongodb.conf 
about to fork child process, waiting until server is ready for connections.
forked process: 4319
child process started successfully, parent exiting
[root@DB mongodb]# ps -ef  |grep mongo
root      4319      1  1 13:36 ?        00:00:00 mongod -f /usr/local/mongodb/mongodb.conf
[root@DB mongodb]# mongo 192.168.221.160 
MongoDB shell version: 3.0.6
connecting to: 192.168.221.160/test
Server has startup warnings: 
2017-11-14T13:36:25.213+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2017-11-14T13:36:25.213+0800 I CONTROL  [initandlisten] 
2017-11-14T13:36:25.214+0800 I CONTROL  [initandlisten] 
2017-11-14T13:36:25.214+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is ‘always’.
2017-11-14T13:36:25.214+0800 I CONTROL  [initandlisten] **        We suggest setting it to ‘never’
2017-11-14T13:36:25.214+0800 I CONTROL  [initandlisten] 
2017-11-14T13:36:25.214+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is ‘always’.
2017-11-14T13:36:25.214+0800 I CONTROL  [initandlisten] **        We suggest setting it to ‘never’
2017-11-14T13:36:25.214+0800 I CONTROL  [initandlisten] 
2017-11-14T13:36:25.214+0800 I CONTROL  [initandlisten] ** WARNING: soft rlimits too low. rlimits set to 16384 processes, 65536 files. Number of processes should be at least 32768 : 0.5 times number of files.
2017-11-14T13:36:25.214+0800 I CONTROL  [initandlisten] 
> db.a.find()
{“_id” : ObjectId(“5a0a7fa7766decd974b3ad3f”), “a” : 1 }
>

我们都知道,这种单实例的配置只适合学习开发时使用,生产肯定不会这么使用,不然单节点挂掉整条数据流全丢了
接下来一篇我们继续学习 mongodb 主从的配置···

 

在之前我们使用 mysql 数据库或者 redis 时大家广泛用到,采用双机备份后主节点挂掉了后从节点可以接替主机继续服务。所以这种模式比单节点的高可用性要好很多。
1、环境准备
实际应用中,需要两台机器一主一从。我这里因资源问题,使用一台机器解决。
192.168.221.161:27021 当做 master
192.168.221.161:27022 当做 slave
2、分别建立两个文件夹 /data/db_master,/data/db_slave
3、分别配置两个配置文件 mongodb_master.conf,mongodb_salve.conf
[root@MidApp mongodb]# cat mongodb_master.conf 
dbpath=/data/db_master
logpath=/usr/local/mongodb/logs/mongodb_master.log
logappend=true
port=27021
fork=true
auth=false
nohttpinterface=false
bind_ip=192.168.221.161
journal=true
quiet=true
master=true

 

[root@MidApp mongodb]# cat mongodb_salve.conf 
dbpath=/data/db_slave
logpath=/usr/local/mongodb/logs/mongodb_slave.log
logappend=true
port=27022
fork=true
auth=false
nohttpinterface=false
bind_ip=192.168.221.161
journal=true
quiet=true
slave=true
source=192.168.221.161:27021

4. 启动 master 节点
[root@MidApp mongodb]# mongod -f mongodb_master.conf 
about to fork child process, waiting until server is ready for connections.
forked process: 55489
child process started successfully, parent exiting

Master 上输出日志内容如下:
2017-11-14T09:02:39.999-0800 I CONTROL  [initandlisten] options: {config: “mongodb_master.conf”, master: true, net: { bindIp: “192.168.221.161”, http: { enabled: true}, port: 27021 }, processManagement: {fork: true}, security: {authorization: “disabled”}, storage: {dbPath: “/data/db_master”, journal: { enabled: true} }, systemLog: {destination: “file”, logAppend: true, path: “/usr/local/mongodb/logs/mongodb_master.log”, quiet: true} }
2017-11-14T09:02:40.014-0800 I INDEX    [initandlisten] allocating new ns file /data/db_master/local.ns, filling with zeroes…
2017-11-14T09:02:40.018-0800 I NETWORK  [websvr] admin web console waiting for connections on port 28021
2017-11-14T09:02:40.254-0800 I STORAGE  [FileAllocator] allocating new datafile /data/db_master/local.0, filling with zeroes…
2017-11-14T09:02:40.254-0800 I STORAGE  [FileAllocator] creating directory /data/db_master/_tmp
2017-11-14T09:02:40.263-0800 I STORAGE  [FileAllocator] done allocating datafile /data/db_master/local.0, size: 64MB,  took 0.001 secs
2017-11-14T09:02:40.318-0800 I REPL    [initandlisten] ******
2017-11-14T09:02:40.318-0800 I REPL    [initandlisten] creating replication oplog of size: 990MB…
2017-11-14T09:02:40.319-0800 I STORAGE  [FileAllocator] allocating new datafile /data/db_master/local.1, filling with zeroes…
2017-11-14T09:02:40.349-0800 I STORAGE  [FileAllocator] done allocating datafile /data/db_master/local.1, size: 1024MB,  took 0.029 secs
2017-11-14T09:02:40.354-0800 I REPL    [initandlisten] ******
2017-11-14T09:02:40.358-0800 I NETWORK  [initandlisten] waiting for connections on port 27021

5. 启动从节点
[root@MidApp mongodb]# mongod -f mongodb_salve.conf 
about to fork child process, waiting until server is ready for connections.
forked process: 55577
child process started successfully, parent exiting

Slave 上输出日志如下:
2017-11-14T09:05:10.757-0800 I CONTROL  [initandlisten] allocator: tcmalloc
2017-11-14T09:05:10.757-0800 I CONTROL  [initandlisten] options: {config: “mongodb_salve.conf”, net: { bindIp: “192.168.221.161”, http: { enabled: true}, port: 27022 }, processManagement: {fork: true}, security: {authorization: “disabled”}, slave: true, source: “192.168.221.161:27021”, storage: {dbPath: “/data/db_slave”, journal: { enabled: true} }, systemLog: {destination: “file”, logAppend: true, path: “/usr/local/mongodb/logs/mongodb_slave.log”, quiet: true} }
2017-11-14T09:05:10.759-0800 I INDEX    [initandlisten] allocating new ns file /data/db_slave/local.ns, filling with zeroes…
2017-11-14T09:05:10.763-0800 I NETWORK  [websvr] admin web console waiting for connections on port 28022
2017-11-14T09:05:11.039-0800 I STORAGE  [FileAllocator] allocating new datafile /data/db_slave/local.0, filling with zeroes…
2017-11-14T09:05:11.039-0800 I STORAGE  [FileAllocator] creating directory /data/db_slave/_tmp
2017-11-14T09:05:11.045-0800 I STORAGE  [FileAllocator] done allocating datafile /data/db_slave/local.0, size: 64MB,  took 0.001 secs
2017-11-14T09:05:11.066-0800 I NETWORK  [initandlisten] waiting for connections on port 27022

6. 验证一下主从复制
登录 master 插入数据:
[root@MidApp mongodb]# mongo 192.168.221.161:27021 
MongoDB shell version: 3.0.6
connecting to: 192.168.221.161:27021/test
> show dbs
local  1.078GB
> use test
switched to db test
> db.testdb.insert({“test1″:”item1”})
WriteResult({“nInserted” : 1})
> db.testdb.find()
{“_id” : ObjectId(“5a0b23702c969986fca777ed”), “test1” : “item1” }

登录 slave 节点,验证数据:
[root@MidApp mongodb]# mongo 192.168.221.161:27022
MongoDB shell version: 3.0.6
connecting to: 192.168.221.161:27022/test
> show dbs
2017-11-14T09:07:45.745-0800 E QUERY    Error: listDatabases failed:{“note” : “from execCommand”, “ok” : 0, “errmsg” : “not master”}
    at Error (<anonymous>)
    at Mongo.getDBs (src/mongo/shell/mongo.js:47:15)
    at shellHelper.show (src/mongo/shell/utils.js:630:33)
    at shellHelper (src/mongo/shell/utils.js:524:36)
    at (shellhelp2):1:1 at src/mongo/shell/mongo.js:47
> db.getMongo().setSlaveOk()# 由于 slave 节点默认是不可读的,需要先执行这句命令才能查询数据
> show dbs
local  0.078GB
> show dbs
local  0.078GB
test  0.078GB
> db.testdb.find()
{“_id” : ObjectId(“5a0b23702c969986fca777ed”), “test1” : “item1” }

从节点上可以通过命令 db.printReplicationInfo()查看服务状态:
> db.printReplicationInfo()
this is a slave, printing slave replication info.
source: 192.168.221.161:27021
syncedTo: Tue Nov 14 2017 09:12:04 GMT-0800 (PST)
7 secs (0 hrs) behind the freshest member (no primary available at the moment)

至此,mongodb 的主从架构已经完成了。为防止机器负载过大,也可以配置一主多从服务,master 节点只负责写操作,slave 节点只提供读操作。
不过,存在几个疑问:
a. 从服务器可以当做主服务器吗,也就是从服务器可写吗?
试一下:
> db.testdb.insert({“test3″:”item3”})
WriteResult({“writeError” : { “code” : undefined, “errmsg” : “not master”} })

可以看到,slave 节点是不可写的
b. 如果 master 挂掉,从服务器会自动接管主服务,变为可写吗?
把 master 进程杀掉:
kill -9 `ps -ef|grep mongod|grep -v grep|awk ‘{print $2}’`

测试 slave 节点:
> db.testdb.insert({“test3″:”item3”})
WriteResult({“writeError” : { “code” : undefined, “errmsg” : “not master”} })

发现,还是不可写!
这种情况只能手动干预了。。。
继续思考一个问题:
我们怎么实现主节点挂了之后能够自动切换?下一篇接着学习 mongodb 的集群搭建

一、概述
NoSQL,指的是非关系型的数据库。NoSQL 有时也称作 Not Only SQL 的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称。
NoSQL 用于超大规模数据的存储。(例如谷歌或 Facebook 每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。
今天我们可以通过第三方平台(如:Google,Facebook 等)可以很容易的访问和抓取数据。用户的个人信息,社交网络,地理位置,用户生成的数据和用户操作日志已经成倍的增加。我们如果要对这些用户数据进行挖掘,那 SQL 数据库已经不适合这些应用了, NoSQL 数据库的发展也却能很好的处理这些大的数据。
 
NoSQL 的优点
高可扩展性 可以横向扩展也可以纵向扩展
分布式计算
低成本高性能
架构的灵活性,半结构化数据
没有复杂的关系
MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库. 支持类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。所以这个非常方便,我们可以用 sql 操作 MongoDB,从关系型数据库迁移过来,开发人员学习成本会大大减少。如果再对底层的 sql API 做一层封装,开发基本可以感觉不到 mongodb 和关系型数据库的区别。同样 MongoDB 也是号称自己能够快速搭建一个高可用可扩展的的分布式集群。

二、安装配置与应用
MongoDB 可以在 windows 上安装使用,同样支持 linux 平台。我这里选的是 linux 平台安装。
1. 首先下载并解压安装包
curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.6.tgz    # 下载
tar  -zxvf mongodb-linux-x86_64-3.0.6.tgz                  # 解压
mv  mongodb-linux-x86_64-3.0.6/  /usr/local/mongodb            # 将解压包拷贝到指定目录

把 MongoDB 的可执行文件路径加到 PATH 变量中(~/.bash_profile)
PATH=$PATH:$HOME/bin:/usr/local/mongodb/bin

2. 创建所 mongodb 启动需要的路径和文件
mkdir /data/db #创建存放 mongodb 的数据文件夹
mkdir /usr/local/mongodb/logs/ #创建存放 mongodb 日志的文件夹
touch /usr/local/mongodb/logs/mongodb.log #创建存放 mongodb 的日志文件

3. 启动 mongodb 服务。命令窗口直接执行就行
[root@DB ~]# mongod 
2017-11-14T13:14:19.809+0800 I JOURNAL  [initandlisten] journal dir=/data/db/journal
2017-11-14T13:14:19.809+0800 I JOURNAL  [initandlisten] recover : no journal files present, no recovery needed
2017-11-14T13:14:19.815+0800 I JOURNAL  [durability] Durability thread started
2017-11-14T13:14:19.815+0800 I JOURNAL  [journal writer] Journal writer thread started
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] MongoDB starting : pid=4287 port=27017 dbpath=/data/db 64-bit host=DB
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] 
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] 
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is ‘always’.
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] **        We suggest setting it to ‘never’
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] 
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is ‘always’.
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] **        We suggest setting it to ‘never’
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] 
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] ** WARNING: soft rlimits too low. rlimits set to 16384 processes, 65536 files. Number of processes should be at least 32768 : 0.5 times number of files.
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] 
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] db version v3.0.6
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] git version: 1ef45a23a4c5e3480ac919b28afcba3c615488f2
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] build info: Linux build6.ny.cbi.10gen.cc 2.6.32-431.3.1.el6.x86_64 #1 SMP Fri Jan 3 21:39:27 UTC 2014 x86_64 BOOST_LIB_VERSION=1_49
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] allocator: tcmalloc
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] options: {}
2017-11-14T13:14:19.849+0800 I NETWORK  [initandlisten] waiting for connections on port 27017

可以看到 mongodb 服务进程以及启动,开启了 27017 端口等待连接了
另开一个命令窗口,使用 mongo 命令可以与 mongodb 进行交互。由于它是一个 JavaScript Shell,可以输入简单的算术运算测试一下:
[root@DB mongodb]# mongo 
MongoDB shell version: 3.0.6
connecting to: test
Server has startup warnings: 
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] 
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] 
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is ‘always’.
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] **        We suggest setting it to ‘never’
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] 
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is ‘always’.
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] **        We suggest setting it to ‘never’
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] 
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] ** WARNING: soft rlimits too low. rlimits set to 16384 processes, 65536 files. Number of processes should be at least 32768 : 0.5 times number of files.
2017-11-14T13:14:19.834+0800 I CONTROL  [initandlisten] 
> 3+2
5

也可以插入一些简单数据,查询验证:
> db.a.insert({a:1})
WriteResult({“nInserted” : 1})
> db.a.find()
{“_id” : ObjectId(“5a0a7fa7766decd974b3ad3f”), “a” : 1 }
>

三、mongodb 启动命令参数说明
mongod 的主要参数有:
 
–quiet# 安静输出
–port arg# 指定服务端口号,默认端口 27017
–bind_ip arg# 绑定服务 IP,若绑定 127.0.0.1,则只能本机访问,不指定默认本地所有 IP
–logpath arg# 指定 MongoDB 日志文件,注意是指定文件不是目录
–logappend# 使用追加的方式写日志
–pidfilepath arg# PID File 的完整路径,如果没有设置,则没有 PID 文件
–keyFile arg# 集群的私钥的完整路径,只对于 Replica Set 架构有效
–unixSocketPrefix arg# UNIX 域套接字替代目录,(默认为 /tmp)
–fork# 以守护进程的方式运行 MongoDB,创建服务器进程
–auth# 启用验证
–cpu# 定期显示 CPU 的 CPU 利用率和 iowait
–dbpath arg# 指定数据库路径
–diaglog arg# diaglog 选项 0=off 1=W 2=R 3=both 7=W+some reads
–directoryperdb# 设置每个数据库将被保存在一个单独的目录
–journal# 启用日志选项,MongoDB 的数据操作将会写入到 journal 文件夹的文件里
–journalOptions arg# 启用日志诊断选项
–ipv6# 启用 IPv6 选项
–jsonp# 允许 JSONP 形式通过 HTTP 访问(有安全影响)
–maxConns arg# 最大同时连接数 默认 2000
–noauth# 不启用验证
–nohttpinterface# 关闭 http 接口,默认关闭 27018 端口访问
–noprealloc# 禁用数据文件预分配(往往影响性能)
–noscripting# 禁用脚本引擎
–notablescan# 不允许表扫描
–nounixsocket# 禁用 Unix 套接字监听
–nssize arg (=16)# 设置信数据库.ns 文件大小(MB)
–objcheck# 在收到客户数据, 检查的有效性,
–profile arg# 档案参数 0=off 1=slow, 2=all
–quota# 限制每个数据库的文件数,设置默认为 8
–quotaFiles arg# number of files allower per db, requires –quota
–rest# 开启简单的 rest API
–repair# 修复所有数据库 run repair on all dbs
–repairpath arg# 修复库生成的文件的目录, 默认为目录名称 dbpath
–slowms arg (=100)# value of slow for profile and console log
–smallfiles# 使用较小的默认文件
–syncdelay arg (=60)# 数据写入磁盘的时间秒数(0=never, 不推荐)
–sysinfo# 打印一些诊断系统信息
–upgrade# 如果需要升级数据库  * Replicaton 参数
 
——————————————————————————–
 
–fastsync# 从一个 dbpath 里启用从库复制服务,该 dbpath 的数据库是主库的快照,可用于快速启用同步
–autoresync# 如果从库与主库同步数据差得多,自动重新同步,
–oplogSize arg# 设置 oplog 的大小(MB)  * 主 / 从参数
 
——————————————————————————–
 
–master# 主库模式
–slave# 从库模式
–source arg# 从库 端口号
–only arg# 指定单一的数据库复制
–slavedelay arg# 设置从库同步主库的延迟时间  * Replica set(副本集) 选项:
 
——————————————————————————–
 
–replSet arg# 设置副本集名称  * Sharding(分片)选项
 
——————————————————————————–
–configsvr# 声明这是一个集群的 config 服务, 默认端口 27019,默认目录 /data/configdb
–shardsvr# 声明这是一个集群的分片, 默认端口 27018
–noMoveParanoia# 关闭偏执为 moveChunk 数据保存
 
可以把上述参数都写进 mongodb.conf 配置文件里:
[root@DB mongodb]# cat mongodb.conf 
dbpath=/data/db
logpath=/usr/local/mongodb/logs/mongodb.log
logappend=true
port=27017
fork=true
auth=false
nohttpinterface=false
bind_ip=192.168.221.160
journal=true
quiet=true

启动的时候使用 -f���数引用这个位置即可
[root@DB mongodb]# mongod -f /usr/local/mongodb/mongodb.conf 
about to fork child process, waiting until server is ready for connections.
forked process: 4319
child process started successfully, parent exiting
[root@DB mongodb]# ps -ef  |grep mongo
root      4319      1  1 13:36 ?        00:00:00 mongod -f /usr/local/mongodb/mongodb.conf
[root@DB mongodb]# mongo 192.168.221.160 
MongoDB shell version: 3.0.6
connecting to: 192.168.221.160/test
Server has startup warnings: 
2017-11-14T13:36:25.213+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2017-11-14T13:36:25.213+0800 I CONTROL  [initandlisten] 
2017-11-14T13:36:25.214+0800 I CONTROL  [initandlisten] 
2017-11-14T13:36:25.214+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is ‘always’.
2017-11-14T13:36:25.214+0800 I CONTROL  [initandlisten] **        We suggest setting it to ‘never’
2017-11-14T13:36:25.214+0800 I CONTROL  [initandlisten] 
2017-11-14T13:36:25.214+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is ‘always’.
2017-11-14T13:36:25.214+0800 I CONTROL  [initandlisten] **        We suggest setting it to ‘never’
2017-11-14T13:36:25.214+0800 I CONTROL  [initandlisten] 
2017-11-14T13:36:25.214+0800 I CONTROL  [initandlisten] ** WARNING: soft rlimits too low. rlimits set to 16384 processes, 65536 files. Number of processes should be at least 32768 : 0.5 times number of files.
2017-11-14T13:36:25.214+0800 I CONTROL  [initandlisten] 
> db.a.find()
{“_id” : ObjectId(“5a0a7fa7766decd974b3ad3f”), “a” : 1 }
>

我们都知道,这种单实例的配置只适合学习开发时使用,生产肯定不会这么使用,不然单节点挂掉整条数据流全丢了
接下来一篇我们继续学习 mongodb 主从的配置···

 

MongoDB 复制原理就是主节点记录在其上的所有操作 oplog,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。
那什么是副本集呢?主从模式一主一从就是一个副本。MongoDB 复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性,并可以保证数据的安全性; 复制还允许您从硬件故障和服务中断中恢复数据。副本集具有多个副本保证了容错性,就算一个副本挂掉了还有很多副本存在,并且解决了之前的问题“主节点挂掉了,整个集群内会自动切换”。
 
副本集特征:
· N 个节点的集群
· 任何节点可作为主节点
· 所有写入操作都在主节点上
· 自动故障转移
· 自动恢复
副本集还有以下几个需要注意的地方:
1. 最小构成是:primary,secondary,arbiter,一般部署是:primary,2 secondary。
2. 成员数应该为奇数,如果为偶数的情况下添加 arbiter,arbiter 不保存数据,只投票。
3. 最大 50 members,但是只能有 7 voting members,其他是 non-voting members。
借用网上找的两张架构图说明一下:

高可用 MongoDB 集群部署详解

由图可以看到客户端连接到整个副本集,不关心具体哪一台机器是否挂掉。主服务器负责整个副本集的读写,副本集定期同步数据备份,一但主节点挂掉,副本节点就会选举一个新的主服务器,这一切对于应用服务器不需要关心。我们看一下主服务器挂掉后的架构:

高可用 MongoDB 集群部署详解
 
副本集中的副本节点在主节点挂掉后通过心跳机制检测到后,就会在集群内发起主节点的选举机制,自动选举一位新的主服务器。更加详细的副本机制请参考搭建高可用 mongodb 集群(三)—— 深入副本集内部机制
官方推荐的副本集机器数量至少为 3 个,我这里就以三个节点为例介绍。
1. 环境准备
192.168.221.161:27017 作为主节点,192.168.221.161:27018,192.168.221.161:27019 作为两个副本节点
2. 分别创建三个节点所需要的文件夹
mkdir /data/db{1..3} #存放三个节点数据文件
touch /usr/local/mongodb/mongodb{1..3}.log #存放三个节点的日志

 

3. 创建三个节点的配置文件
[root@MidApp mongodb]# cat mongodb1.conf 
dbpath=/data/db1
logpath=/usr/local/mongodb/logs/mongodb1.log
logappend=true
port=27017
fork=true
auth=false
nohttpinterface=false
bind_ip=192.168.221.161
journal=true
quiet=true
replSet=repset

 

[root@MidApp mongodb]# cat mongodb2.conf 
dbpath=/data/db2
logpath=/usr/local/mongodb/logs/mongodb2.log
logappend=true
port=27018
fork=true
auth=false
nohttpinterface=false
bind_ip=192.168.221.161
journal=true
quiet=true
replSet=repset

 

[root@MidApp mongodb]# cat mongodb3.conf 
dbpath=/data/db3
logpath=/usr/local/mongodb/logs/mongodb3.log
logappend=true
port=27019
fork=true
auth=false
nohttpinterface=false
bind_ip=192.168.221.161
journal=true
quiet=true
replSet=repset

4. 分别启动三个节点
mongod -f mongodb1.conf
mongod -f mongodb2.conf
mongod -f mongodb3.conf

查看日志输出,没有找到 replica 的配置信息
2017-11-13T16:34:46.212-0800 I CONTROL  [initandlisten] options: {config: “mongodb1.conf”, net: { bindIp: “192.168.221.160”, http: { enabled: true}, port: 27017 }, processManagement: {fork: true}, replication: {replSet: “repset”}, security: {authorization: “disabled”}, storage: {dbPath: “/data/db1”, journal: { enabled: true} }, systemLog: {destination: “file”, logAppend: true, path: “/usr/local/mongodb/logs/mongodb1.log”, quiet: true} }
2017-11-13T16:34:46.214-0800 I INDEX    [initandlisten] allocating new ns file /data/db1/local.ns, filling with zeroes…
2017-11-13T16:34:46.216-0800 I JOURNAL  [journal writer] Journal writer thread started
2017-11-13T16:34:46.492-0800 I STORAGE  [FileAllocator] allocating new datafile /data/db1/local.0, filling with zeroes…
2017-11-13T16:34:46.492-0800 I STORAGE  [FileAllocator] creating directory /data/db1/_tmp
2017-11-13T16:34:46.501-0800 I STORAGE  [FileAllocator] done allocating datafile /data/db1/local.0, size: 64MB,  took 0.001 secs
2017-11-13T16:34:46.520-0800 I REPL    [initandlisten] Did not find local replica set configuration document at startup;  NoMatchingDocument Did not find replica set configuration document in local.system.replset

5. 初始化副本集
任选一个节点登录进去,可以看到 show dbs 是不可用,因为还没初始化副本集
[root@MidApp mongodb]# mongo 192.168.221.161 
MongoDB shell version: 3.0.6
connecting to: 192.168.221.161/test
Welcome to the MongoDB shell.
For interactive help, type “help”.
For more comprehensive documentation, see
http://docs.mongodb.org/
Questions? Try the support group
http://groups.google.com/group/mongodb-user
> show dbs
2017-11-13T16:39:33.235-0800 E QUERY    Error: listDatabases failed:{“note” : “from execCommand”, “ok” : 0, “errmsg” : “not master”}
    at Error (<anonymous>)
    at Mongo.getDBs (src/mongo/shell/mongo.js:47:15)
    at shellHelper.show (src/mongo/shell/utils.js:630:33)
    at shellHelper (src/mongo/shell/utils.js:524:36)
    at (shellhelp2):1:1 at src/mongo/shell/mongo.js:47
> use admin
switched to db admin

 

定义副本集配置变量,这里的 _id:”repset”和上面配置文件的参数“–replSet repset”要保持一样
>config= {_id:”repset”,members:[
{_id:0,host:”192.168.221.161:27017″},
{_id:1,host:”192.168.221.161:27018″},
{_id:2,host:”192.168.221.161:27019″}]
}

 

查看输出信息:
 {
“_id” : “repset”,
“members” : [
{
“_id” : 0,
“host” : “192.168.221.161:27017”
},
{
“_id” : 1,
“host” : “192.168.221.161:27018”
},
{
“_id” : 2,
“host” : “192.168.221.161:27019”
}
]
}

 

初始化副本集配置
12 > rs.initiate(config);
{“ok” : 1}

 

查看集群节点状态:
repset:OTHER> rs.status()
{
“set” : “repset”,
“date” : ISODate(“2017-11-14T00:49:25.782Z”),
“myState” : 1,
“members” : [
{
“_id” : 0,
“name” : “192.168.221.161:27017”,
“health” : 1,
“state” : 1,
“stateStr” : “PRIMARY”,
“uptime” : 695,
“optime” : Timestamp(1510620540, 1),
“optimeDate” : ISODate(“2017-11-14T00:49:00Z”),
“electionTime” : Timestamp(1510620544, 1),
“electionDate” : ISODate(“2017-11-14T00:49:04Z”),
“configVersion” : 1,
“self” : true
},
{
“_id” : 1,
“name” : “192.168.221.161:27018”,
“health” : 1,
“state” : 2,
“stateStr” : “SECONDARY”,
“uptime” : 25,
“optime” : Timestamp(1510620540, 1),
“optimeDate” : ISODate(“2017-11-14T00:49:00Z”),
“lastHeartbeat” : ISODate(“2017-11-14T00:49:24.739Z”),
“lastHeartbeatRecv” : ISODate(“2017-11-14T00:49:24.762Z”),
“pingMs” : 0,
“configVersion” : 1
},
{
“_id” : 2,
“name” : “192.168.221.161:27019”,
“health” : 1,
“state” : 2,
“stateStr” : “SECONDARY”,
“uptime” : 25,
“optime” : Timestamp(1510620540, 1),
“optimeDate” : ISODate(“2017-11-14T00:49:00Z”),
“lastHeartbeat” : ISODate(“2017-11-14T00:49:24.739Z”),
“lastHeartbeatRecv” : ISODate(“2017-11-14T00:49:24.762Z”),
“pingMs” : 0,
“configVersion” : 1
}
],
“ok” : 1
}

整个副本及已经搭建成功了!
6. 测试副本集数据复制功能
在主节点登录 mongodb
[root@MidApp mongodb]# mongo 192.168.221.161:27017
MongoDB shell version: 3.0.6
connecting to: 192.168.221.161:27017/test
repset:PRIMARY> use test;
switched to db test
repset:PRIMARY> db.testdb.insert({“test1″:”item1”})
WriteResult({“nInserted” : 1})
repset:PRIMARY> exit
bye

在副本节点登录查看数据:
[root@MidApp logs]# mongo 192.168.221.161:27018
MongoDB shell version: 3.0.6
connecting to: 192.168.221.161:27018/test
repset:SECONDARY> use test
switched to db test
repset:SECONDARY> db.getMongo().setSlaveOk();#mongodb 默认是从主节点读写数据的,副本节点上不允许读,需要设置副本节点可以读
repset:SECONDARY> db.testdb.find()
{“_id” : ObjectId(“5a0a3e8d40637405ab003b39”), “test1” : “item1” }

7. 测试副本集 failover 功能
手动把现在的主节点停掉,查看集群状态:
repset:SECONDARY> rs.status()
{
“set” : “repset”,
“date” : ISODate(“2017-11-14T00:57:14.753Z”),
“myState” : 2,
“members” : [
{
“_id” : 0,
“name” : “192.168.221.161:27017”,
“health” : 0,
“state” : 8,
“stateStr” : “(not reachable/healthy)”,
“uptime” : 0,
“optime” : Timestamp(0, 0),
“optimeDate” : ISODate(“1970-01-01T00:00:00Z”),
“lastHeartbeat” : ISODate(“2017-11-14T00:57:13.304Z”),
“lastHeartbeatRecv” : ISODate(“2017-11-14T00:57:09.285Z”),
“pingMs” : 0,
“lastHeartbeatMessage” : “Failed attempt to connect to 192.168.221.161:27017; couldn’t connect to server 192.168.221.161:27017 (192.168.221.161), connection attempt failed”,
“configVersion” : -1
},
{
“_id” : 1,
“name” : “192.168.221.161:27018”,
“health” : 1,
“state” : 2,
“stateStr” : “SECONDARY”,
“uptime” : 1167,
“optime” : Timestamp(1510620813, 2),
“optimeDate” : ISODate(“2017-11-14T00:53:33Z”),
“infoMessage” : “could not find member to sync from”,
“configVersion” : 1,
“self” : true
},
{
“_id” : 2,
“name” : “192.168.221.161:27019”,
“health” : 1,
“state” : 1,
“stateStr” : “PRIMARY”,
“uptime” : 17,
“optime” : Timestamp(1510620813, 2),
“optimeDate” : ISODate(“2017-11-14T00:53:33Z”),
“lastHeartbeat” : ISODate(“2017-11-14T00:57:13.317Z”),
“lastHeartbeatRecv” : ISODate(“2017-11-14T00:57:13.330Z”),
“pingMs” : 0,
“electionTime” : Timestamp(1510621032, 1),
“electionDate” : ISODate(“2017-11-14T00:57:12Z”),
“configVersion” : 1
}
],
“ok” : 1
}

可以看到原来的主节点状态现在已经变成了不可达,192.168.221.161:27019 已经变成新的主节点
8. 再次启动原来的主节点,发现 192.168.221.161:27017 还是 SECONDARY
repset:SECONDARY> rs.status()
{
“set” : “repset”,
“date” : ISODate(“2017-11-14T17:02:13.837Z”),
“myState” : 2,
“members” : [
{
“_id” : 0,
“name” : “192.168.221.161:27017”,
“health” : 1,
“state” : 2,
“stateStr” : “SECONDARY”,
“uptime” : 5,
“optime” : Timestamp(1510620813, 2),
“optimeDate” : ISODate(“2017-11-14T00:53:33Z”),
“lastHeartbeat” : ISODate(“2017-11-14T17:02:12.642Z”),
“lastHeartbeatRecv” : ISODate(“2017-11-14T17:02:11.902Z”),
“pingMs” : 0,
“configVersion” : 1
},
{
“_id” : 1,
“name” : “192.168.221.161:27018”,
“health” : 1,
“state” : 2,
“stateStr” : “SECONDARY”,
“uptime” : 59066,
“optime” : Timestamp(1510620813, 2),
“optimeDate” : ISODate(“2017-11-14T00:53:33Z”),
“configVersion” : 1,
“self” : true
},
{
“_id” : 2,
“name” : “192.168.221.161:27019”,
“health” : 1,
“state” : 1,
“stateStr” : “PRIMARY”,
“uptime” : 57916,
“optime” : Timestamp(1510620813, 2),
“optimeDate” : ISODate(“2017-11-14T00:53:33Z”),
“lastHeartbeat” : ISODate(“2017-11-14T17:02:12.308Z”),
“lastHeartbeatRecv” : ISODate(“2017-11-14T17:02:12.080Z”),
“pingMs” : 0,
“electionTime” : Timestamp(1510621032, 1),
“electionDate” : ISODate(“2017-11-14T00:57:12Z”),
“configVersion” : 1
}
],
“ok” : 1
}

现在,mongodb 的副本集群已经完成了。
接下来是关于 mongodb 的读写分离和分片的内容

无论 Oracle 还是 mysql 数据库都有分区的概念,即同一张表物理上不在同一台机器上,有效缓解了表都集中存在一台机器的压力。当然,mongodb 也有类似的机制,即是分片。具体理论知识大家可以参考网上文档,我这里只记录下具体操作步骤
dc166a30dd685af75d234808f3f9cdf6.png
参考网络上一个图。我选用的是 2 个副本集 + 1 个仲裁。实际上我这里分片集群需要 3 个 mongos,3 个 config server,数据分片 3 个 shard server,对应着还有 3 个副本,3 个仲裁节点,总共需要 15 个实例。因为我资源确实紧张,又不想影响实验效果。冥思苦想了一阵,索性在一台机器上实现得了,分给不同的实例以不同的端口就好了。
闲话少说,开始搞起!!!
1. 资源划分(感觉这是最纠结的一步)

高可用 MongoDB 集群部署详解

2. mongdb 的安装
这个可以参考博主的前一篇章进行安装高可用 mongodb 集群的学习记录(一安装配置 MongoDB)
3. 创建所需要的目录
# 创建所需要的目录
[root@DB mongodb]# mkdir -p mongos{1..3}/log
[root@DB mongodb]# mkdir -p config{1..3}/log
[root@DB mongodb]# mkdir -p config{1..3}/data
[root@DB mongodb]# mkdir -p shard{1..3}_{1..3}/log
[root@DB mongodb]# mkdir -p shard{1..3}_{1..3}/data

4. 启动每一个配置服务器
# 启动配置服务器
mongod –configsvr –dbpath config1/data –port 21001 –logpath config1/log/config.log –fork
mongod –configsvr –dbpath config2/data –port 21002 –logpath config2/log/config.log –fork
mongod –configsvr –dbpath config3/data –port 21003 –logpath config3/log/config.log –fork

5. 启动 mongos 服务器
mongos –configdb 192.168.221.160:21001,192.168.221.160:21002,192.168.221.160:21003 –port 20001 –logpath mongos1/log/mongos.log –fork
mongos –configdb 192.168.221.160:21001,192.168.221.160:21002,192.168.221.160:21003 –port 20002 –logpath mongos2/log/mongos.log –fork
mongos –configdb 192.168.221.160:21001,192.168.221.160:21002,192.168.221.160:21003 –port 20003 –logpath mongos3/log/mongos.log –fork

6. 启动分片的副本集
 
mongod –shardsvr –replSet shard1 –port 21101 –dbpath shard1_1/data –logpath shard1_1/log/shard.log –fork –nojournal –oplogSize 10 
  mongod –shardsvr –replSet shard1 –port 21201 –dbpath shard1_2/data –logpath shard1_2/log/shard.log –fork –nojournal –oplogSize 10 
  mongod –shardsvr –replSet shard1 –port 21301 –dbpath shard1_3/data –logpath shard1_3/log/shard.log –fork –nojournal –oplogSize 10 
  mongod –shardsvr –replSet shard2 –port 21102 –dbpath shard2_1/data –logpath shard2_1/log/shard.log –fork –nojournal –oplogSize 10 
  mongod –shardsvr –replSet shard2 –port 21202 –dbpath shard2_2/data –logpath shard2_2/log/shard.log –fork –nojournal –oplogSize 10 
  mongod –shardsvr –replSet shard2 –port 21302 –dbpath shard2_3/data –logpath shard2_3/log/shard.log –fork –nojournal –oplogSize 10 
  mongod –shardsvr –replSet shard3 –port 21103 –dbpath shard3_1/data –logpath shard3_1/log/shard.log –fork –nojournal –oplogSize 10 
  mongod –shardsvr –replSet shard3 –port 21203 –dbpath shard3_2/data –logpath shard3_2/log/shard.log –fork –nojournal –oplogSize 10 
  mongod –shardsvr –replSet shard3 –port 21303 –dbpath shard3_3/data –logpath shard3_3/log/shard.log –fork –nojournal –oplogSize 10

7. 分别对每个分片配置副本集, 任意登录一个节点
# 设置第一个分片副本集
[root@DB ~]# mongo 192.168.221.160:21101
MongoDB shell version: 3.0.6
connecting to: 192.168.221.160:21101/test
> use admin
switched to db admin
# 定义副本集配置信息
> config = {_id:”shard1″,members:[{_id:0,host:”192.168.221.160:21101″},{_id:1,host:”192.168.221.160:21201″},{_id:2,host:”192.168.221.160:21301″,arbiterOnly:true}]}
{
“_id” : “shard1”,
“members” : [
{
“_id” : 0,
“host” : “192.168.221.160:21101”
},
{
“_id” : 1,
“host” : “192.168.221.160:21201”
},
{
“_id” : 2,
“host” : “192.168.221.160:21301”,
“arbiterOnly” : true
}
]
}
# 初始化副本集信息
> rs.initiate(config)
{“ok” : 1}
shard1:OTHER> 
 
# 设置第二个分片副本集
[root@DB ~]# mongo 192.168.221.160:21102
MongoDB shell version: 3.0.6
connecting to: 192.168.221.160:21102/test
> use admin
switched to db admin
> config = {_id:”shard2″,members:[{_id:0,host:”192.168.221.160:21102″},{_id:1,host:”192.168.221.160:21202″},{_id:2,host:”192.168.221.160:21302″,arbiterOnly:true}]}
{
“_id” : “shard2”,
“members” : [
{
“_id” : 0,
“host” : “192.168.221.160:21102”
},
{
“_id” : 1,
“host” : “192.168.221.160:21202”
},
{
“_id” : 2,
“host” : “192.168.221.160:21302”,
“arbiterOnly” : true
}
]
}
> rs.initiate(config)
{“ok” : 1}
shard2:OTHER> 
# 设置第三个分片副本集
[root@DB ~]# mongo 192.168.221.160:21103
MongoDB shell version: 3.0.6
connecting to: 192.168.221.160:21103/test
> use admin
switched to db admin
> config = {_id:”shard3″,members:[{_id:0,host:”192.168.221.160:21103″},{_id:1,host:”192.168.221.160:21203″},{_id:2,host:”192.168.221.160:21303″,arbiterOnly:true}]}
{
“_id” : “shard3”,
“members” : [
{
“_id” : 0,
“host” : “192.168.221.160:21103”
},
{
“_id” : 1,
“host” : “192.168.221.160:21203”
},
{
“_id” : 2,
“host” : “192.168.221.160:21303”,
“arbiterOnly” : true
}
]
}
> rs.initiate(config)
{“ok” : 1}
shard3:OTHER>

8. 登录到每一个 mongos,设置分片配置,让分片生效
# 串联路由服务器与分片副本集 1
[root@DB ~]# mongo 192.168.221.160:20001
MongoDB shell version: 3.0.6
connecting to: 192.168.221.160:20001/test
Server has startup warnings: 
2017-11-15T13:51:20.732+0800 I CONTROL  ** WARNING: You are running this process as the root user, which is not recommended.
2017-11-15T13:51:20.733+0800 I CONTROL 
mongos> use admin
switched to db admin
mongos> db.runCommand({addshard:”shard1/192.168.221.160:21101,192.168.221.160:21201,192.168.221.160:21301″})
{“shardAdded” : “shard1”, “ok” : 1}
mongos> 
# 串联路由服务器与分片副本集 2
[root@DB ~]# mongo 192.168.221.160:20002
MongoDB shell version: 3.0.6
connecting to: 192.168.221.160:20002/test
Server has startup warnings: 
2017-11-15T13:51:43.660+0800 I CONTROL  ** WARNING: You are running this process as the root user, which is not recommended.
2017-11-15T13:51:43.661+0800 I CONTROL 
mongos> use admin
switched to db admin
mongos> db.runCommand({addshard:”shard2/192.168.221.160:21102,192.168.221.160:21202,192.168.221.160:21302″})
{“shardAdded” : “shard2”, “ok” : 1}
mongos> 
 
# 串联路由服务器与分片副本集 3
[root@DB ~]# mongo 192.168.221.160:20003
MongoDB shell version: 3.0.6
connecting to: 192.168.221.160:20003/test
Server has startup warnings: 
2017-11-15T13:51:59.589+0800 I CONTROL  ** WARNING: You are running this process as the root user, which is not recommended.
2017-11-15T13:51:59.589+0800 I CONTROL 
mongos> use admin
switched to db admin
mongos> db.runCommand({addshard:”shard3/192.168.221.160:21103,192.168.221.160:21203,192.168.221.160:21303″})
{“shardAdded” : “shard3”, “ok” : 1}
mongos>

9. 查看分片服务器的配置信息:
mongos> db.runCommand({listshards:1})
{
“shards” : [
{
“_id” : “shard1”,
“host” : “shard1/192.168.221.160:21101,192.168.221.160:21201”
},
{
“_id” : “shard2”,
“host” : “shard2/192.168.221.160:21102,192.168.221.160:21202”
},
{
“_id” : “shard3”,
“host” : “shard3/192.168.221.160:21103,192.168.221.160:21203”
}
],
“ok” : 1
}
mongos>

 

    仲裁节点不储存数据,没有在这里显示出来
10. 连接 mongos 上,指定数据库、指定集合让分片生效
[root@DB ~]# mongo 192.168.221.160:20001
MongoDB shell version: 3.0.6
connecting to: 192.168.221.160:20001/test
mongos> db.runCommand({enablesharding:”testdb”})
{
“ok” : 0,
“errmsg” : “enableSharding may only be run against the admin database.”,
“code” : 13
}
mongos> use admin
switched to db admin
mongos> db.runCommand({enablesharding:”testdb”})
{“ok” : 1}
mongos> db.runCommand({shardcollection:”testdb.table1″,key:{id:1}})
{“collectionsharded” : “testdb.table1”, “ok” : 1}
mongos>

设置 testdb 的 table1 表需要分片,根据 id 自动分片到 shard1,shard2,shard3 上面去。要这样设置是因为不是所有 mongodb 的数据库和表都需要分片
 
11. 测试分片片配置效果
[root@DB ~]# mongo 192.168.221.160:20001
MongoDB shell version: 3.0.6
connecting to: 192.168.221.160:20001/test
Server has startup warnings: 
2017-11-15T13:51:20.732+0800 I CONTROL  ** WARNING: You are running this process as the root user, which is not recommended.
2017-11-15T13:51:20.733+0800 I CONTROL 
mongos> use testdb;
switched to db testdb
mongos> for (var i = 1;i<=10000;i++) db.table1.save({id:i,”test1″:”item1″})
WriteResult({“nInserted” : 1})
mongos> db.table1.stats()
{
“sharded” : true,
“paddingFactorNote” : “paddingFactor is unused and unmaintained in 3.0. It remains hard coded to 1.0 for compatibility only.”,
“userFlags” : 1,
“capped” : false,
“ns” : “testdb.table1”,
“count” : 10000,
“numExtents” : 7,
“size” : 1120000,
“storageSize” : 2809856,
“totalIndexSize” : 654080,
“indexSizes” : {
“_id_” : 351568,
“id_1” : 302512
},
“avgObjSize” : 112,
“nindexes” : 2,
“nchunks” : 3,
“shards” : {
“shard1” : {
“ns” : “testdb.table1”,
“count” : 9991,
“size” : 1118992,

“ok” : 1,
“$gleStats” : {
“lastOpTime” : Timestamp(0, 0),
“electionId” : ObjectId(“5a0bd9cf86a6b76e11b5d820”)
}
},
“shard2” : {
“ns” : “testdb.table1”,
“count” : 1,
“size” : 112,

“ok” : 1,
“$gleStats” : {
“lastOpTime” : Timestamp(0, 0),
“electionId” : ObjectId(“5a0bdadd74c5945a33a4ae46”)
}
},
“shard3” : {
“ns” : “testdb.table1”,
“count” : 8,
“size” : 896,

“ok” : 1,
“$gleStats” : {
“lastOpTime” : Timestamp(0, 0),
“electionId” : ObjectId(“5a0bdb6f1c75115f41ff92f9”)
}
}
},
“ok” : 1
}
mongos>

可以看到 testdb.table1 数据已经被分到三个分片,各自分片数量为 shard1“count”: 9991,shard2“count”: 1,shard3“count”: 8。我也不知道为啥分配的不均匀。纳闷 ing
好了,实验到此结束,关于 mongodb 的学习会继续进行 …

更多 MongoDB 相关教程见以下内容

MongoDB 文档、集合、数据库简介  http://www.linuxidc.com/Linux/2016-12/138529.htm

MongoDB 3 分片部署及故障模拟验证  http://www.linuxidc.com/Linux/2016-12/138529.htm

Linux CentOS 6.5 yum 安装 MongoDB  http://www.linuxidc.com/Linux/2016-12/137790.htm

CentOS 7 yum 方式快速安装 MongoDB  http://www.linuxidc.com/Linux/2016-11/137679.htm

MongoDB 的查询操作  http://www.linuxidc.com/Linux/2016-10/136581.htm

在 Azure 虚拟机上快速搭建 MongoDB 集群  http://www.linuxidc.com/Linux/2017-09/146778.htm

MongoDB 复制集原理  http://www.linuxidc.com/Linux/2017-09/146670.htm

MongoDB 3.4 远程连接认证失败  http://www.linuxidc.com/Linux/2017-06/145070.htm

Ubuntu 16.04 中安装 MongoDB3.4 数据库系统  http://www.linuxidc.com/Linux/2017-07/145526.htm

MongoDB 权威指南第 2 版 PDF 完整带书签目录 下载见 http://www.linuxidc.com/Linux/2016-12/138253.htm

MongoDB 的详细介绍:请点这里
MongoDB 的下载地址:请点这里

本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-11/148740.htm

正文完
星哥说事-微信公众号
post-qrcode
 
星锅
版权声明:本站原创文章,由 星锅 2022-01-22发表,共计38406字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中