21.26 mongodb介绍

介绍:

  • 官网www.mongodb.com, 当前最新版3.4

  • C++ 编写,基于分布式的,属于 NoSQL 的一种

  • 在 NoSQL 中是最像关系型数据库的

  • MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档、数组及文档数组。

  • 关于JSON http://www.w3school.com.cn/json/index.asp

  • 因为基于分布式,所以很容易扩展

MongoDB和关系型数据库对比:

111.png

关系型数据库数据结构:

112.png

MongoDB数据结构:

113.png

21.27 mongodb安装

epel自带的mongodb版本为2.6,我们需要安装3.4版本

官方安装文档 docs.mongodb.com/manual/tutorial/install-mongodb-on-red-hat/

1、制作 yum 源

[root@arslinux-01 ~]# cd /etc/yum.repos.d/
[root@arslinux-01 yum.repos.d]# vim mongo.repo
[mongodb-org-3.4]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.4/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.4.asc

2、查看可安装的 mogodb 版本

[root@arslinux-01 yum.repos.d]# yum list |grep mongodb
mongodb-org.x86_64                      3.4.21-1.el7                   mongodb-org-3.4
mongodb-org-mongos.x86_64               3.4.21-1.el7                   mongodb-org-3.4
mongodb-org-server.x86_64               3.4.21-1.el7                   mongodb-org-3.4
mongodb-org-shell.x86_64                3.4.21-1.el7                   mongodb-org-3.4
mongodb-org-tools.x86_64                3.4.21-1.el7                   mongodb-org-3.4
mongodb-server.x86_64                   2.6.12-6.el7                   epel
mongodb-test.x86_64                     2.6.12-6.el7                   epel
nodejs-mongodb.noarch                   1.4.7-1.el7                    epel
php-mongodb.noarch                      1.0.4-1.el7                    epel
php-pecl-mongodb.x86_64                 1.1.10-1.el7                   epel
poco-mongodb.x86_64                     1.6.1-3.el7                    epel

3、yum 安装

[root@arslinux-01 yum.repos.d]# yum install mongodb-org


21.28 连接mongodb

1、启动 MongoDB

[root@arslinux-01 ~]# systemctl start mongod
[root@arslinux-01 ~]# ps aux|grep mongo
mongod     8597  1.7  3.8 973456 38076 ?        Sl   12:39   0:00 /usr/bin/mongod -f /etc/mongod.conf
root       8620  0.0  0.0 112724   988 pts/0    R+   12:39   0:00 grep --color=auto mongo
[root@arslinux-01 ~]# netstat -lntp|grep mongo
tcp        0      0 127.0.0.1:27017         0.0.0.0:*               LISTEN      8597/mongod

2、进入 MongoDB

[root@arslinux-01 ~]# mongo
MongoDB shell version v3.4.21
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.21
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
Server has startup warnings:
2019-07-16T12:39:35.723+0800 I CONTROL  [initandlisten]
2019-07-16T12:39:35.723+0800 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2019-07-16T12:39:35.723+0800 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2019-07-16T12:39:35.723+0800 I CONTROL  [initandlisten]
2019-07-16T12:39:35.723+0800 I CONTROL  [initandlisten]
2019-07-16T12:39:35.723+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2019-07-16T12:39:35.723+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2019-07-16T12:39:35.723+0800 I CONTROL  [initandlisten]
2019-07-16T12:39:35.723+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2019-07-16T12:39:35.723+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2019-07-16T12:39:35.723+0800 I CONTROL  [initandlisten]
>

3、如果mongodb监听端口并不是默认的27017,则在连接的时候需要加--port 选项

例如:mongo --port 27018

连接远程mongodb,需要加--host,例如

mongo --host  127.0.0.1

4、如果设置了验证,则在连接的时候需要带用户名和密码

mongo -uusername -ppasswd --authenticationDatabase db //这个和 MySQL挺像


21.29 mongodb用户管理

1、创建用户,添加密码

> use admin
switched to db admin
> db.createUser( { user: "admin", customData: {description: "superuser"}, pwd: "admin122", roles: [ { role: "root", db: "admin" } ] } )
Successfully added user: {
    "user" : "admin",
    "customData" : {
        "description" : "superuser"
    },
    "roles" : [
        {
            "role" : "root",
            "db" : "admin"
        }
    ]
}

user 指定用户;customData 为说明字段,可以省略;pwd 为密码;roles 指定用户的角色;db 指定库名

2、列出所有用户,需要切换到admin库

> use admin
switched to db admin
> db.system.users.find()
{ "_id" : "admin.admin", "user" : "admin", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : 
{ "iterationCount" : 10000, "salt" : "JeDsJTa/kJYAXFhd9CKb2A==", "storedKey" : 
"YW+dUA7OTWw5ZmA8AN+HqHz677U=", "serverKey" : "LjyBIPucqbf0vqz6+5dTfmpVFqE=" } }, 
"customData" : { "description" : "superuser" }, "roles" : [ { "role" : "root", "db" : "admin" } ] }

3、查看当前库下所有的用户

> show users
{
    "_id" : "admin.admin",
    "user" : "admin",
    "db" : "admin",
    "customData" : {
    "description" : "superuser"
    },
    "roles" : [
        {
            "role" : "root",
            "db" : "admin"
        }
    ]
}

4、删除用户 db.dropUser('admin')

> db.createUser( { user: "arslinux",  pwd: "123456", roles: [ { role: "read", db: "testdb" } ] } )
Successfully added user: {
    "user" : "arslinux",
    "roles" : [
        {
            "role" : "read",
            "db" : "testdb"
        }
    ]
}
> db.dropUser('arslinux')
true
> show users
{
    "_id" : "admin.admin",
    "user" : "admin",
    "db" : "admin",
    "customData" : {
        "description" : "superuser"
    },
    "roles" : [
        {
            "role" : "root",
            "db" : "admin"
        }
    ]
}

5、用户生效

1)先重新创建回用户 arslinux

> db.createUser({user:"arslinx",pwd:"123456",roles:[{role:"read",db:"testdb"}]})
Successfully added user: {
    "user" : "arslinx",
    "roles" : [
        {
            "role" : "read",
            "db" : "testdb"
        }
    ]
}

2)编辑启动脚本 /usr/lib/systemd/system/mongod.service,在OPTIONS= 后面增 --auth

[root@arslinux-01 ~]# vim /usr/lib/systemd/system/mongod.service
Environment="OPTIONS=--auth -f /etc/mongod.conf"
[root@arslinux-01 ~]# systemctl restart mongod
Warning: mongod.service changed on disk. Run 'systemctl daemon-reload' to reload units.
[root@arslinux-01 ~]# systemctl daemon-reload
[root@arslinux-01 ~]# systemctl restart mongod

3)加了 --auth 后,普通方法登录后,出现没有授权(not authorized)

[root@arslinux-01 ~]# mongo --host 127.0.0.1 --port 27017
MongoDB shell version v3.4.21
connecting to: mongodb://127.0.0.1:27017/
MongoDB server version: 3.4.21
> use admin
switched to db admin
> show users
2019-07-16T20:25:00.524+0800 E QUERY    [thread1] Error: not authorized on admin to execute command { usersInfo: 1.0 } :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
DB.prototype.getUsers@src/mongo/shell/db.js:1539:1
shellHelper.show@src/mongo/shell/utils.js:797:9
shellHelper@src/mongo/shell/utils.js:704:15
@(shellhelp2):1:1

4)重新登录,做认证

[root@arslinux-01 ~]# mongo --host 127.0.0.1 --port 27017 -u admin -p admin122 --authenticationDatabase "admin"

可以登录成功

5)哪个库中创建的用户,需要先到哪个库认证后再操作,否则会提示验证失败

> db.createUser({user:"test1",pwd:"123aaa",roles:[{role:"readWrite",db:"db1"},{role:"read",db:"db2"}]})
Successfully added user: {
    "user" : "test1",
    "roles" : [
        {
            "role" : "readWrite",
            "db" : "db1"
        },
        {
            "role" : "read",
            "db" : "db2"
        }
    ]
}
> show users
{
    "_id" : "db1.test1",
    "user" : "test1",
    "db" : "db1",
    "roles" : [
        {
            "role" : "readWrite",
            "db" : "db1"
        },
        {
            "role" : "read",
            "db" : "db2"
        }
    ]
}

test1 用户对 db1 库读写,对 db2 库只读。

之所以先 use db1,表示用户在 db1 库中创建,就一定要 db1 库验证身份,即用户的信息跟随数据库。比如上述 test1 虽然有 db2 库的读取权限,但是一定要先在 db1 库进行身份验证,直接访问会提示验证失败。

> use db2
switched to db db2
> db.auth('test1','123aaa')
Error: Authentication failed.
0
> use db1
switched to db db1
> db.auth('test1','123aaa')
1

MongoDB用户角色:

·Read:允许用户读取指定数据库

·readWrite:允许用户读写指定数据库

·dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问·system.profile

·userAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户

·clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。

·readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限

·readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限

·userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限

·dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。

·root:只在admin数据库中可用。超级账号,超级权限


21.30 mongodb创建集合、数据管理

创建集合:

  • db.version() 查看版本

  • use userdb 如果库存在就切换,不存在就创建

  • show dbs 查看库,此时userdb并没有出现,这是因为该库是空的,还没有任何集合,只需要创建一个集合就能看到了

  • db.createCollection(name,options) 创建集合,在当前库下面创建

> db.createCollection("mycol",{capped:true,size:6142800,max:10000})
{ "ok" : 1 }

  • name 就是集合的名字,options 可选,用来配置集合的参数,参数如下

  • capped true/false (可选)如果为 true,则启用封顶集合。封顶集合是固定大小的集合,当它达到其最大大小,会自动覆盖最早的条目。如果指定 true,则也需要指定尺寸参数。

  • size(可选)指定最大大小字节封顶集合。如果封顶如果是 true,那么你还需要指定这个字段。单位 B

  • max(可选)指定封顶集合允许在文件的最大数量


数据管理:

  • show collections 或 show tables      查看集合

> show collections
mycol
> show tables
mycol
  • db.集合名.insert({格式:...........})        插入数据,定义格式。Account 是库名

如果集合不存在,直接插入数据,则 mongodb 会自动创建集合

> db.Account.insert({AccountID:1,UserName:"123",password:"123456"})
WriteResult({ "nInserted" : 1 })
> show tables
Account
mycol
> db.Account.insert({AccountID:2,UserName:"zhangsan",password:"abcde"})
WriteResult({ "nInserted" : 1 })
  • db.集合名.update({集合名ID:...},{动作}:{"字段":值})      更新

> db.Account.update({AccountID:1},{"$set":{"Age":20}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
  • db.集合名.find()          查看所有文档

{ "_id" : ObjectId("5d2dd565a1976b473ed539f8"), "AccountID" : 1, "UserName" : "123", "password" : "123456", "Age" : 20 }
{ "_id" : ObjectId("5d2dd5c6a1976b473ed539f9"), "AccountID" : 2, "UserName" : "zhangsan", "password" : "abcde" }
  • db.集合名.find({条件})          根据条件查询

> db.Account.find({AccountID:1})
{ "_id" : ObjectId("5d2dd565a1976b473ed539f8"), "AccountID" : 1, "UserName" : "123", "password" : "123456", "Age" : 20 }
> db.Account.find({AccountID:2})
{ "_id" : ObjectId("5d2dd5c6a1976b473ed539f9"), "AccountID" : 2, "UserName" : "zhangsan", "password" : "abcde" }
  • db.集合名.remove({条件})          根据条件删除

> db.Account.remove({AccountID:1})
WriteResult({ "nRemoved" : 1 })
> db.Account.find()
{ "_id" : ObjectId("5d2dd5c6a1976b473ed539f9"), "AccountID" : 2, "UserName" : "zhangsan", "password" : "abcde" }
  • db.集合名.drop()          删除所有文档,即删除集合

> db.Account.drop()
true
> show tables
mycol
  • db.printCollectionStats()          查看集合状态

> db.printCollectionStats()


21.31 php的mongodb扩展


方法一:

[root@arslinux-01 ~]# cd /usr/local/src/
[root@arslinux-01 src]# git clone https://github.com/mongodb/mongo-php-driver
[root@arslinux-01 src]# cd mongo-php-driver
[root@arslinux-01 mongo-php-driver]# git submodule update --init
[root@arslinux-01 mongo-php-driver]# /usr/local/php/bin/phpize
[root@arslinux-01 mongo-php-driver]# ./configure --with-php-config=/usr/local/php/bin/php-config
[root@arslinux-01 mongo-php-driver]# make && make install
[root@arslinux-01 src]# vi /usr/local/php/etc/php.ini //增加 extension = mongodb.so
[root@arslinux-01 src]# /usr/local/php/bin/php -m

方法二:

1、下载、解压

[root@arslinux-01 ~]# cd /usr/local/src/
[root@arslinux-01 ~]# wget https://pecl.php.net/get/mongodb-1.3.0.tgz
[root@arslinux-01 ~]# tar xvf mongodb-1.3.0.tgz
[root@arslinux-01 ~]# cd mongodb-1.3.0/

2、生成 configure 文件

[root@arslinux-01 mongodb-1.3.0]# /usr/local/php-fpm/bin/phpize
Configuring for:
PHP Api Version:         20131106
Zend Module Api No:      20131226
Zend Extension Api No:   220131226

3、编译安装

[root@arslinux-01 mongodb-1.3.0]# ./configure --with-php-config=/usr/local/php-fpm/bin/php-config
[root@arslinux-01 mongodb-1.3.0]# make && make install
Installing shared extensions:     /usr/local/php-fpm/lib/php/extensions/no-debug-non-zts-20131226/
[root@arslinux-01 mongodb-1.3.0]# ls /usr/local/php-fpm/lib/php/extensions/no-debug-non-zts-20131226/
memcache.so  mongodb.so  opcache.a  opcache.so  redis.so

4、编辑 php.ini,添加 mongodb.so,检测是否存在

[root@arslinux-01 mongodb-1.3.0]# vim /usr/local/php-fpm/etc/php.ini
extension=mongodb.so
[root@arslinux-01 mongodb-1.3.0]# /usr/local/php-fpm/bin/php -m |grep mongodb
mongodb

5、重启 php-fpm

[root@arslinux-01 mongodb-1.3.0]# /etc/init.d/php-fpm restart
Gracefully shutting down php-fpm . done
Starting php-fpm  done



21.32 php的mongo扩展

mongo.so 扩展适用于 php 5.x 的版本,比较老,以后就不在使用了

1、下载、解压

[root@arslinux-01 src]# wget https://pecl.php.net/get/mongo-1.6.16.tgz
[root@arslinux-01 src]# tar xvf mongo-1.6.16.tgz
[root@arslinux-01 src]# cd mongo-1.6.16/

2、生成 configure 文件

[root@arslinux-01 mongo-1.6.16]# /usr/local/php-fpm/bin/phpize
Configuring for:
PHP Api Version:         20131106
Zend Module Api No:      20131226
Zend Extension Api No:   220131226

3、编译安装

[root@arslinux-01 mongo-1.6.16]# ./configure --with-php-config=/usr/local/php-fpm/bin/php-config
[root@arslinux-01 mongo-1.6.16]# make && make install
Installing shared extensions:     /usr/local/php-fpm/lib/php/extensions/no-debug-non-zts-20131226/
[root@arslinux-01 mongo-1.6.16]# ls /usr/local/php-fpm/lib/php/extensions/no-debug-non-zts-20131226/
memcache.so  mongodb.so  mongo.so  opcache.a  opcache.so  redis.so

4、编辑 php.ini,添加 mongo.so,检测是否存在

[root@arslinux-01 mongo-1.6.16]# vim /usr/local/php-fpm/etc/php.ini
extension=mongo.so
[root@arslinux-01 mongo-1.6.16]# /usr/local/php-fpm/bin/php -m |grep mongo
mongo
mongodb

5、重启 php-fpm

[root@arslinux-01 mongo-1.6.16]# /etc/init.d/php-fpm restart
Gracefully shutting down php-fpm . done
Starting php-fpm  done

测试:

1、去掉 mongodb 的认证,重启 mongod

[root@arslinux-01 src]# vim /usr/lib/systemd/system/mongod.service

去掉 --auth

重启:

[root@arslinux-01 src]# systemctl restart mongod
Warning: mongod.service changed on disk. Run 'systemctl daemon-reload' to reload units.
[root@arslinux-01 src]# systemctl daemon-reload
[root@arslinux-01 src]# systemctl restart mongod

2、是否能正常解析,php命令是创建 test 库中 runoob 的集合

[root@arslinux-01 src]# vim /data/wwwroot/default.com/mongo.php
<?php
$m = new MongoClient();         // 连接
$db = $m->test;                 // 获取名称为 "test" 的数据库
$collection = $db->createCollection("runoob");
echo "集合创建成功";
?>
[root@arslinux-01 src]# curl localhost/mongo.php
集合创建成功

3、查看 mongodb 库里有没有 test 库、runoob 集合

[root@arslinux-01 src]# mongo --host 127.0.0.1 --port 27017
略
> use test
switched to db test
> show tables
runoob

成功!!

只安装 mongodb.so,不安装 mongo.so,是会失败的


21.33 mongodb副本集介绍

  • 早期版本使用 master-slave,一主一从和 MySQL 类似,但 slave 在此架构中为只读,当主库宕机后,从库不能自动切换为主

  • 目前已经淘汰 master-slave 模式,改为副本集,这种模式下有一个主(primary),和多个从(secondary),只读。支持给它们设置权重,当主宕掉后,权重最高的从切换为主

  • 在此架构中还可以建立一个仲裁(arbiter)的角色,它只负责裁决,而不存储数据

  • 再此架构中读写数据都是在主上,要想实现负载均衡的目的需要手动指定读库的目标 server

副本集架构图:

clipboard1.png

clipboard2.png

21.34 mongodb副本集搭建

1、准备:

三台机器:

192.168.194.130(primary)

192.168.194.132(secondary)

192.168.194.133(secondary)

三台机器全部安装 mongodb:

[root@arslinux-02 ~]# vim /etc/yum.repos.d/mongo.repo
[mongodb-org-3.4]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.4/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.4.asc
[root@arslinux-02 ~]#  yum install mongodb-org/

2、编辑三台机器配置文件 /etc/mongod.conf

[root@arslinux-01 ~]# vim /etc/mongod.conf
bindIp: 127.0.0.1,192.168.194.130
replication:
oplogSizeMB: 20              //oplog 大小
replSetName: arslinux        // 定义副本集名称

同样方法编辑另外两台机器参数,注意 ip 要是本机 ip

编辑完重启 mongod

3、连接主

[root@arslinux-01 ~]# mongo
MongoDB shell version v3.4.21
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.21
> use admin
switched to db admin
> config={_id:"arslinux",members:[{_id:0,host:"192.168.194.130:27017"},{_id:1,host:"192.168.194.132:27017"},{_id:2,host:"192.168.194.133:27017"}]}
{
    "_id" : "arslinux",
    "members" : [
        {
            "_id" : 0,
            "host" : "192.168.194.130:27017"
        },
        {
            "_id" : 1,
            "host" : "192.168.194.132:27017"
        },
        {
            "_id" : 2,
            "host" : "192.168.194.133:27017"
        }
    ]
}
> rs.initiate(config)                //初始化
{ "ok" : 1 }
arslinux:OTHER> rs.status()        //查看状态
{
    "set" : "arslinux",
    "date" : ISODate("2019-07-20T11:13:02.115Z"),
    "myState" : 1,
    "term" : NumberLong(1),
    "syncingTo" : "",
    "syncSourceHost" : "",
    "syncSourceId" : -1,
    "heartbeatIntervalMillis" : NumberLong(2000),
    "optimes" : {
        "lastCommittedOpTime" : {
            "ts" : Timestamp(1563621178, 1),
            "t" : NumberLong(1)
        },
        "appliedOpTime" : {
            "ts" : Timestamp(1563621178, 1),
            "t" : NumberLong(1)
        },
        "durableOpTime" : {
            "ts" : Timestamp(1563621178, 1),
            "t" : NumberLong(1)
        }
    },
    "members" : [
        {
            "_id" : 0,
            "name" : "192.168.194.130:27017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 497,
            "optime" : {
                "ts" : Timestamp(1563621178, 1),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2019-07-20T11:12:58Z"),
            "syncingTo" : "",
            "syncSourceHost" : "",
            "syncSourceId" : -1,
            "infoMessage" : "could not find member to sync from",
            "electionTime" : Timestamp(1563621157, 1),
            "electionDate" : ISODate("2019-07-20T11:12:37Z"),
            "configVersion" : 1,
            "self" : true,
            "lastHeartbeatMessage" : ""
        },
        {
            "_id" : 1,
            "name" : "192.168.194.132:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 35,
            "optime" : {
                "ts" : Timestamp(1563621178, 1),
                "t" : NumberLong(1)
            },
            "optimeDurable" : {
                "ts" : Timestamp(1563621178, 1),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2019-07-20T11:12:58Z"),
            "optimeDurableDate" : ISODate("2019-07-20T11:12:58Z"),
            "lastHeartbeat" : ISODate("2019-07-20T11:13:01.095Z"),
            "lastHeartbeatRecv" : ISODate("2019-07-20T11:13:02.073Z"),
            "pingMs" : NumberLong(0),
            "lastHeartbeatMessage" : "",
            "syncingTo" : "192.168.194.133:27017",
            "syncSourceHost" : "192.168.194.133:27017",
            "syncSourceId" : 2,
            "infoMessage" : "",
            "configVersion" : 1
        },
        {
            "_id" : 2,
            "name" : "192.168.194.133:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 35,
            "optime" : {
                "ts" : Timestamp(1563621178, 1),
                "t" : NumberLong(1)
            },
            "optimeDurable" : {
                "ts" : Timestamp(1563621178, 1),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2019-07-20T11:12:58Z"),
            "optimeDurableDate" : ISODate("2019-07-20T11:12:58Z"),
            "lastHeartbeat" : ISODate("2019-07-20T11:13:01.087Z"),
            "lastHeartbeatRecv" : ISODate("2019-07-20T11:13:02.054Z"),
            "pingMs" : NumberLong(0),
            "lastHeartbeatMessage" : "",
            "syncingTo" : "192.168.194.130:27017",
            "syncSourceHost" : "192.168.194.130:27017",
            "syncSourceId" : 0,
            "infoMessage" : "",
            "configVersion" : 1
        }
    ],
    "ok" : 1
}

在哪一台机器上操作 config ,哪一台就会被自动定位 Primary


21.35 mongodb副本集测试

主上建库,建集合

arslinux:PRIMARY> use mydb
switched to db mydb
arslinux:PRIMARY> db.acc.insert({AccountID:1,UserName:"123",password:"123456"})
WriteResult({ "nInserted" : 1 })
arslinux:PRIMARY> show dbs;
admin  0.000GB
db1    0.000GB
local  0.000GB
mydb   0.000GB
test   0.000GB
arslinux:PRIMARY> use mydb
switched to db mydb
arslinux:PRIMARY> show tables
acc

从 1 上查看  192.168.194.132

arslinux:SECONDARY> show dbs;
2019-07-20T19:44:16.286+0800 E QUERY    [thread1] Error: listDatabases failed:{
    "ok" : 0,
    "errmsg" : "not master and slaveOk=false",
    "code" : 13435,
    "codeName" : "NotMasterNoSlaveOk"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1
shellHelper.show@src/mongo/shell/utils.js:814:19
shellHelper@src/mongo/shell/utils.js:704:15
@(shellhelp2):1:1

若出现以上错误需要执行 rs.slaveOk()

arslinux:SECONDARY> rs.slaveOk()
arslinux:SECONDARY> show dbs
admin  0.000GB
db1    0.000GB
local  0.000GB
mydb   0.000GB
test   0.000GB
arslinux:SECONDARY> use mydb
switched to db mydb
arslinux:SECONDARY> show tables
acc

从 2 上查看 192.168.194.133

arslinux:SECONDARY> rs.slaveOK()
2019-07-20T19:50:06.677+0800 E QUERY    [thread1] TypeError: rs.slaveOK is not a function :
@(shell):1:1
arslinux:SECONDARY> rs.slaveOk()
arslinux:SECONDARY> show tables
acc

副本集更改权重模拟主宕机:

默认三台机器权重都为1,如果任何一个权重设置为比其他的高,则该台机器马上切换为primary角色

所以我们预设三台机器的权重分别为:130:3,132:2,133:1

1、查看机器权重,priority 即为权重

arslinux:PRIMARY> rs.config()
{
    "_id" : "arslinux",
    "version" : 1,
    "protocolVersion" : NumberLong(1),
    "members" : [
        {
            "_id" : 0,
            "host" : "192.168.194.130:27017",
            "arbiterOnly" : false,
            "buildIndexes" : true,
            "hidden" : false,
            "priority" : 1,
            "tags" : {
            
            },
            "slaveDelay" : NumberLong(0),
            "votes" : 1
        },
        {
            "_id" : 1,
            "host" : "192.168.194.132:27017",
            "arbiterOnly" : false,
            "buildIndexes" : true,
            "hidden" : false,
            "priority" : 1,
            "tags" : {
            
            },
            "slaveDelay" : NumberLong(0),
            "votes" : 1
        },
        {
            "_id" : 2,
            "host" : "192.168.194.133:27017",
            "arbiterOnly" : false,
            "buildIndexes" : true,
            "hidden" : false,
            "priority" : 1,
            "tags" : {
            
            },
            "slaveDelay" : NumberLong(0),
            "votes" : 1
        }
    ],
    "settings" : {
        "chainingAllowed" : true,
        "heartbeatIntervalMillis" : 2000,
        "heartbeatTimeoutSecs" : 10,
        "electionTimeoutMillis" : 10000,
        "catchUpTimeoutMillis" : 60000,
        "getLastErrorModes" : {
        
        },
        "getLastErrorDefaults" : {
            "w" : 1,
            "wtimeout" : 0
        },
        "replicaSetId" : ObjectId("5d32f71aa3c7c7bdec0d9e86")
    }
}

2、设置权重

在主上执行

arslinux:PRIMARY> cfg = rs.conf()
arslinux:PRIMARY> cfg.members[0].priority = 3
3
arslinux:PRIMARY> cfg.members[1].priority = 2
2
arslinux:PRIMARY> cfg.members[2].priority = 1
1
arslinux:PRIMARY> rs.reconfig(cfg)            //让参数生效
{ "ok" : 1 }

3、查看修改后的权重

arslinux:PRIMARY> rs.config()
{
    "_id" : "arslinux",
    "version" : 2,
    "protocolVersion" : NumberLong(1),
    "members" : [
        {
            "_id" : 0,
            "host" : "192.168.194.130:27017",
            "arbiterOnly" : false,
            "buildIndexes" : true,
            "hidden" : false,
            "priority" : 3,
            "tags" : {
            
            },
            "slaveDelay" : NumberLong(0),
            "votes" : 1
        },
        {
            "_id" : 1,
            "host" : "192.168.194.132:27017",
            "arbiterOnly" : false,
            "buildIndexes" : true,
            "hidden" : false,
            "priority" : 2,
            "tags" : {
            
            },
            "slaveDelay" : NumberLong(0),
            "votes" : 1
        },
    {
            "_id" : 2,
            "host" : "192.168.194.133:27017",
            "arbiterOnly" : false,
            "buildIndexes" : true,
            "hidden" : false,
            "priority" : 1,
            "tags" : {
            
            },
            "slaveDelay" : NumberLong(0),
            "votes" : 1
        }
    ],
    "settings" : {
        "chainingAllowed" : true,
        "heartbeatIntervalMillis" : 2000,
        "heartbeatTimeoutSecs" : 10,
        "electionTimeoutMillis" : 10000,
        "catchUpTimeoutMillis" : 60000,
        "getLastErrorModes" : {
    
        },
        "getLastErrorDefaults" : {
            "w" : 1,
            "wtimeout" : 0
        },
        "replicaSetId" : ObjectId("5d32f71aa3c7c7bdec0d9e86")
    }
}

权重越高,优先级越高

4、模拟主机宕机

[root@arslinux-01 ~]# iptables -I INPUT -p tcp --dport 27017 -j DROP

5、从1上查看,主已经切换到从1上了


21.36 mongodb分片介绍

  • 分片就是将数据库进行拆分,将大型集合分隔到不同服务器上。比如,本来100G的数据,可以分割成10份存储到10台服务器上,这样每台机器只有10G的数据。

  • 通过一个mongos的进程(路由)实现分片后的数据存储与访问,也就是说mongos是整个分片架构的核心,对客户端而言是不知道是否有分片的,客户端只需要把读写操作转达给mongos即可。

  • 虽然分片会把数据分隔到很多台服务器上,但是每一个节点都是需要有一个备用角色的,这样能保证数据的高可用。

  • 当系统需要更多空间或者资源的时候,分片可以让我们按需方便扩展,只需要把mongodb服务的机器加入到分片集群中即可

MongoDB 分片架构图:

clipboard3.png

MongoDB 分片相关概念:

  • mongos: 数据库集群请求的入口,所有的请求都通过mongos进行协调,不需要在应用程序添加一个路由选择器,mongos自己就是一个请求分发中心,它负责把对应的数据请求请求转发到对应的shard服务器上。在生产环境通常有多mongos作为请求的入口,防止其中一个挂掉所有的mongodb请求都没有办法操作。

  • config server: 配置服务器,存储所有数据库元信息(路由、分片)的配置。mongos本身没有物理存储分片服务器和数据路由信息,只是缓存在内存里,配置服务器则实际存储这些数据。mongos第一次启动或者关掉重启就会从 config server 加载配置信息,以后如果配置服务器信息变化会通知到所有的 mongos 更新自己的状态,这样 mongos 就能继续准确路由。在生产环境通常有多个 config server 配置服务器,因为它存储了分片路由的元数据,防止数据丢失!

  • shard: 存储了一个集合部分数据的MongoDB实例,每个分片是单独的mongodb服务或者副本集,在生产环境中,所有的分片都应该是副本集。


21.37/21.38/21.39 mongodb分片搭建

1、准备

三台机器 A B C

A 搭建:mongos、config server、副本集 1 主节点、副本集 2 仲裁、副本集 3 从节点

B 搭建:mongos、config server、副本集 1 从节点、副本集 2 主节点、副本集 3 仲裁

C 搭建:mongos、config server、副本集 1 仲裁、副本集 2 从节点、副本集 3 主节点

端口分配:mongos 20000、config 21000、副本集1 27001、副本集2 27002、副本集3 27003

三台机器全部关闭 firewalld 和 selinux,或者增加对应端口的规则

2、三台机器上分别创建各角色所需要的目录

[root@arslinux-01 ~]# mkdir -p /data/mongodb/mongos/log
[root@arslinux-01 ~]# mkdir -p /data/mongodb/config/{data,log}
[root@arslinux-01 ~]# mkdir -p /data/mongodb/shard1/{data,log}
[root@arslinux-01 ~]# mkdir -p /data/mongodb/shard2/{data,log}
[root@arslinux-01 ~]# mkdir -p /data/mongodb/shard3/{data,log}

3、分片搭建——config server 配置

1)对 config sever 创建副本集,添加配置文件(三台机器都要操作,ip 要改)

[root@arslinux-01 ~]# mkdir /etc/mongod/
[root@arslinux-01 ~]# vim /etc/mongod/config.conf
pidfilepath = /var/run/mongodb/configsrv.pid
dbpath = /data/mongodb/config/data
logpath = /data/mongodb/config/log/congigsrv.log
logappend = true
bind_ip = 192.168.194.130
port = 21000
fork = true
configsvr = true                 //表示这是一个config server
replSet=configs                  //副本集名称
maxConns=20000                   //设置最大连接数

2、分别启动三台机器 config server:mongod -f /etc/mongod/config.conf

[root@arslinux-01 ~]# mongod -f /etc/mongod/config.conf
about to fork child process, waiting until server is ready for connections.
forked process: 15501
child process started successfully, parent exiting

3、登录任意一台机器的21000端口,初始化副本集

[root@arslinux-01 ~]# mongo --host 192.168.194.130 --port 21000
MongoDB shell version v3.4.21
connecting to: mongodb://192.168.194.130:21000/
MongoDB server version: 3.4.21
Server has startup warnings:
2019-07-21T10:45:47.344+0800 I CONTROL  [initandlisten]
2019-07-21T10:45:47.344+0800 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2019-07-21T10:45:47.344+0800 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2019-07-21T10:45:47.344+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2019-07-21T10:45:47.344+0800 I CONTROL  [initandlisten]
2019-07-21T10:45:47.345+0800 I CONTROL  [initandlisten]
2019-07-21T10:45:47.345+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2019-07-21T10:45:47.345+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2019-07-21T10:45:47.345+0800 I CONTROL  [initandlisten]
2019-07-21T10:45:47.345+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2019-07-21T10:45:47.345+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2019-07-21T10:45:47.345+0800 I CONTROL  [initandlisten]
> config={_id:"configs",members:[{_id:0,host:"192.168.194.130:21000"},{_id:1,host:"192.168.194.132:21000"},{_id:2,host:"192.168.194.133:21000"}]}
{
    "_id" : "configs",
    "members" : [
        {
            "_id" : 0,
            "host" : "192.168.194.130:21000"
        },
        {
            "_id" : 1,
            "host" : "192.168.194.132:21000"
        },
        {
            "_id" : 2,
            "host" : "192.168.194.133:21000"
        }
    ]
}
> rs.initiate(config)
{ "ok" : 1 }
rs.status()
{
    "set" : "configs",
    "date" : ISODate("2019-07-21T02:53:52.177Z"),
    "myState" : 1,
    "term" : NumberLong(1),
    "syncingTo" : "",
    "syncSourceHost" : "",
    "syncSourceId" : -1,
    "configsvr" : true,
    "heartbeatIntervalMillis" : NumberLong(2000),
    "optimes" : {
        "lastCommittedOpTime" : {
            "ts" : Timestamp(1563677627, 1),
            "t" : NumberLong(1)
        },
        "readConcernMajorityOpTime" : {
            "ts" : Timestamp(1563677627, 1),
            "t" : NumberLong(1)
        },
        "appliedOpTime" : {
            "ts" : Timestamp(1563677627, 1),
            "t" : NumberLong(1)
        },
        "durableOpTime" : {
            "ts" : Timestamp(1563677627, 1),
            "t" : NumberLong(1)
        }
    },
    "members" : [
        {
            "_id" : 0,
            "name" : "192.168.194.130:21000",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 486,
            "optime" : {
                "ts" : Timestamp(1563677627, 1),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2019-07-21T02:53:47Z"),
            "syncingTo" : "",
            "syncSourceHost" : "",
            "syncSourceId" : -1,
            "infoMessage" : "could not find member to sync from",
            "electionTime" : Timestamp(1563677587, 1),
            "electionDate" : ISODate("2019-07-21T02:53:07Z"),
            "configVersion" : 1,
            "self" : true,
            "lastHeartbeatMessage" : ""
        },
        {
            "_id" : 1,
            "name" : "192.168.194.132:21000",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 55,
            "optime" : {
                "ts" : Timestamp(1563677627, 1),
                "t" : NumberLong(1)
            },
            "optimeDurable" : {
                "ts" : Timestamp(1563677627, 1),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2019-07-21T02:53:47Z"),
            "optimeDurableDate" : ISODate("2019-07-21T02:53:47Z"),
            "lastHeartbeat" : ISODate("2019-07-21T02:53:51.665Z"),
            "lastHeartbeatRecv" : ISODate("2019-07-21T02:53:50.695Z"),
            "pingMs" : NumberLong(0),
            "lastHeartbeatMessage" : "",
            "syncingTo" : "192.168.194.130:21000",
            "syncSourceHost" : "192.168.194.130:21000",
            "syncSourceId" : 0,
            "infoMessage" : "",
            "configVersion" : 1
        },
        {
            "_id" : 2,
            "name" : "192.168.194.133:21000",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 55,
            "optime" : {
                "ts" : Timestamp(1563677627, 1),
                "t" : NumberLong(1)
            },
            "optimeDurable" : {
                "ts" : Timestamp(1563677627, 1),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2019-07-21T02:53:47Z"),
            "optimeDurableDate" : ISODate("2019-07-21T02:53:47Z"),
            "lastHeartbeat" : ISODate("2019-07-21T02:53:51.684Z"),
            "lastHeartbeatRecv" : ISODate("2019-07-21T02:53:50.756Z"),
            "pingMs" : NumberLong(0),
            "lastHeartbeatMessage" : "",
            "syncingTo" : "192.168.194.130:21000",
            "syncSourceHost" : "192.168.194.130:21000",
            "syncSourceId" : 0,
            "infoMessage" : "",
            "configVersion" : 1
        }
    ],
    "ok" : 1
}
configs:PRIMARY>

4、分片搭建——分片配置

1)添加 shard1 配置文件(三台机器都操作)

[root@arslinux-01 ~]# vim /etc/mongod/shard1.conf
pidfilepath = /var/run/mongodb/shard1.pid
dbpath = /data/mongodb/shard1/data
logpath = /data/mongodb/shard1/log/shard1.log
logappend = true
bind_ip = 192.168.194.130            //ip可以是0.0.0.0,安全起见分别设置对应 ip 比较好
port = 27001
fork = true
httpinterface=true                   //打开web监控
rest=true
replSet=shard1                       //副本集名称
shardsvr = true                      //定义这是一个 shard 副本集
maxConns=20000                       //设置最大连接数

2)添加 shard2 配置文件(三台机器都操作)

[root@arslinux-01 ~]# vim /etc/mongod/shard2.conf
pidfilepath = /var/run/mongodb/shard2.pid
dbpath = /data/mongodb/shard2/data
logpath = /data/mongodb/shard2/log/shard2.log
logappend = true
bind_ip = 192.168.194.130            //不同机器,ip 不同
port = 27002
fork = true
httpinterface=true                   //打开web监控
rest=true
replSet=shard2                       //副本集名称
shardsvr = true                      //定义这是一个 shard 副本集
maxConns=20000                       //设置最大连接数

3)添加 shard3 配置文件(三台机器都操作)

[root@arslinux-01 ~]# vim /etc/mongod/shard3.conf
pidfilepath = /var/run/mongodb/shard3.pid
dbpath = /data/mongodb/shard3/data
logpath = /data/mongodb/shard3/log/shard3.log
logappend = true
bind_ip = 192.168.194.130            //不同机器,ip 不同
port = 27003
fork = true
httpinterface=true                   //打开web监控
rest=true
replSet=shard3                       //副本集名称
shardsvr = true                      //定义这是一个 shard 副本集
maxConns=20000                       //设置最大连接数

4)启动 shard1(三台机器都需要操作)

[root@arslinux-01 ~]# mongod -f /etc/mongod/shard1.conf
[root@arslinux-02 ~]# mongod -f /etc/mongod/shard1.conf
[root@arslinux-03 ~]# mongod -f /etc/mongod/shard1.conf

5)初始化副本集 shard1

登陆 A 或 B 机器,初始化副本集,因为 C 机器是仲裁节点

[root@arslinux-01 ~]# mongo --host 192.168.194.130 --port 27001
> use admin
switched to db admin
> config = { _id: "shard1", members: [ {_id : 0, host : "192.168.194.130:27001"}, {_id: 1,host : "192.168.194.132:27001"},{_id : 2, host : "192.168.194.133:27001",arbiterOnly:true}] }
{
    "_id" : "shard1",
    "members" : [
        {
            "_id" : 0,
            "host" : "192.168.194.130:27001"
        },
        {
            "_id" : 1,
            "host" : "192.168.194.132:27001"
        },
        {
            "_id" : 2,
            "host" : "192.168.194.133:27001",
            "arbiterOnly" : true
        }
    ]
}
> rs.initiate(config)
{ "ok" : 1 }
shard1:OTHER>
shard1:PRIMARY>

6)启动 shard2(三台机器都需要操作)

[root@arslinux-01 ~]# mongod -f /etc/mongod/shard2.conf
[root@arslinux-02 ~]# mongod -f /etc/mongod/shard2.conf
[root@arslinux-03 ~]# mongod -f /etc/mongod/shard2.conf

7)初始化副本集 shard2

登陆 B 或 C 机器,初始化副本集,因为 A 机器是仲裁节点

[root@arslinux-02 ~]# mongo --host 192.168.194.132 --port 27002
> use admin
switched to db admin
> config = { _id: "shard2", members: [ {_id : 0, host : "192.168.194.130:27002" ,arbiterOnly:true},{_id : 1, host : "192.168.194.132:27002"},{_id : 2, host : "192.168.194.133:27002"}] }
{
    "_id" : "shard2",
    "members" : [
        {
            "_id" : 0,
            "host" : "192.168.194.130:27002",
            "arbiterOnly" : true
        },
        {
            "_id" : 1,
            "host" : "192.168.194.132:27002"
        },
        {
            "_id" : 2,
            "host" : "192.168.194.133:27002"
        }
    ]
}
> rs.initiate(config)
{ "ok" : 1 }
shard2:OTHER>
shard2:PRIMARY>

8)启动 shard3(三台机器都需要操作)

[root@arslinux-01 ~]# mongod -f /etc/mongod/shard3.conf
[root@arslinux-02 ~]# mongod -f /etc/mongod/shard3.conf
[root@arslinux-03 ~]# mongod -f /etc/mongod/shard3.conf

9)初始化副本集 shard3

登陆 A 或 C 机器,初始化副本集,因为 B 机器是仲裁节点

[root@arslinux-02 ~]# mongo --host 192.168.194.132 --port 27002
> use admin
switched to db admin
> config = { _id: "shard3", members: [ {_id : 0, host : "192.168.194.130:27003" },{_id : 1, host : "192.168.194.132:27003",arbiterOnly:true},{_id : 2, host : "192.168.194.133:27003"}] }
{
    "_id" : "shard3",
    "members" : [
        {
            "_id" : 0,
            "host" : "192.168.194.130:27003"
        },
        {
            "_id" : 1,
            "host" : "192.168.194.132:27003",
            "arbiterOnly" : true
        },
        {
            "_id" : 2,
            "host" : "192.168.194.133:27003"
        }
    ]
}
> rs.initiate(config)
{ "ok" : 1 }
shard3:OTHER>
shard3:PRIMARY>

5、分片搭建——配置路由服务器

1)编辑配置文件(三台机器都操作)

[root@arslinux-01 ~]# vim /etc/mongod/mongos.conf
dfilepath = /var/run/mongodb/mongos.pid
logpath = /data/mongodb/mongos/log/mongos.log
logappend = true
bind_ip = 0.0.0.0                            //ip 最好是本机 ip,0.0.0.0 可能不安全
port = 20000
fork = true
configdb = configs/192.168.194.130:21000,192.168.194.132:21000,192.168.194.133:21000
#监听的配置服务器,只能有1个或者3个,configs为配置服务器的副本集名字
maxConns=20000                              //设置最大连接数

2)启动 mongos(三台机器都操作)

[root@arslinux-01 ~]# mongos -f /etc/mongod/mongos.conf
[root@arslinux-02 ~]# mongos -f /etc/mongod/mongos.conf
[root@arslinux-03 ~]# mongos -f /etc/mongod/mongos.conf

6、分片搭建——启用分片

1)登录任何一台机器的 20000 端口

[root@arslinux-01 ~]# mongo --host 192.168.194.130 --port 20000
mongos>

2)把所有分片和路由器串联(ip中间不能有空格)

mongos> sh.addShard("shard1/192.168.194.130:27001,192.168.194.132:27001,192.168.194.133:27001")
{ "shardAdded" : "shard1", "ok" : 1 }
mongos> sh.addShard("shard2/192.168.194.130:27002,192.168.194.132:27002,192.168.194.133:27002")
{ "shardAdded" : "shard2", "ok" : 1 }
mongos> sh.addShard("shard3/192.168.194.130:27003,192.168.194.132:27003,192.168.194.133:27003")
{ "shardAdded" : "shard3", "ok" : 1 }

3)查看集群状态

mongos> sh.status()
--- Sharding Status ---
    sharding version: {
         "_id" : 1,
         "minCompatibleVersion" : 5,
         "currentVersion" : 6,
         "clusterId" : ObjectId("5d33d395fb77650f834a9fef")
    }
    shards:
        {  "_id" : "shard1",  "host" : "shard1/192.168.194.130:27001,192.168.194.132:27001",  "state" : 1 }
        {  "_id" : "shard2",  "host" : "shard2/192.168.194.132:27002,192.168.194.133:27002",  "state" : 1 }
        {  "_id" : "shard3",  "host" : "shard3/192.168.194.130:27003,192.168.194.133:27003",  "state" : 1 }
    active mongoses:
        "3.4.21" : 3
    autosplit:
        Currently enabled: yes
    balancer:
        Currently enabled:  yes
        Currently running:  no
    NaN
        Failed balancer rounds in last 5 attempts:  0
        Migration Results for the last 24 hours:
            No recent migrations
    databases:

创建成功!!!


21.40 mongodb分片测试

1、登录任一台机器 20000 端口

use admin

db.runCommand({ enablesharding : "testdb"}) 或者

sh.enableSharding("testdb")                                 //指定要分片的数据库

db.runCommand( { shardcollection : "testdb.table1",key : {id: 1} } ) 或者

sh.shardCollection("testdb.table1",{"id":1} )          //#指定数据库里需要分片的集合和片键

[root@arslinux-01 ~]# mongo --host 192.168.194.130 --port 20000
mongos> use admin
switched to db admin
mongos> sh.enableSharding("testdb")
{ "ok" : 1 }
mongos> sh.shardCollection("testdb.table1",{"id":1} )
{ "collectionsharded" : "testdb.table1", "ok" : 1 }
mongos> sh.status()
--- Sharding Status ---
sharding version: {
     "_id" : 1,
     "minCompatibleVersion" : 5,
     "currentVersion" : 6,
     "clusterId" : ObjectId("5d33d395fb77650f834a9fef")
}
shards:
    {  "_id" : "shard1",  "host" : "shard1/192.168.194.130:27001,192.168.194.132:27001",  "state" : 1 }
    {  "_id" : "shard2",  "host" : "shard2/192.168.194.132:27002,192.168.194.133:27002",  "state" : 1 }
    {  "_id" : "shard3",  "host" : "shard3/192.168.194.130:27003,192.168.194.133:27003",  "state" : 1 }
active mongoses:
    "3.4.21" : 2
autosplit:
    Currently enabled: yes
balancer:
    Currently enabled:  yes
    Currently running:  no
NaN
    Failed balancer rounds in last 5 attempts:  0
    Migration Results for the last 24 hours:
        No recent migrations
databases:
    {  "_id" : "testdb",  "primary" : "shard2",  "partitioned" : true }
        testdb.table1
            shard key: { "id" : 1 }
            unique: false
            balancing: true
            chunks:
                shard21
            { "id" : { "$minKey" : 1 } } -->> { "id" : { "$maxKey" : 1 } } on : shard2 Timestamp(1, 0)

2)插入测试数据

mongos> use testdb
switched to db testdb
mongos> for (var i = 1; i <= 10000; i++) db.table1.save({id:i,"test1":"testval1"})
WriteResult({ "nInserted" : 1 })

3)继续创建多个库

{ "ok" : 1 }
mongos> sh.shardCollection("db2.cl2",{"id":1} )
{ "collectionsharded" : "db2.cl2", "ok" : 1 }
mongos> sh.enableSharding("db3")
{ "ok" : 1 }
mongos> sh.shardCollection("db3.cl3",{"id":1} )
{ "collectionsharded" : "db3.cl3", "ok" : 1 }

4)查看状态

mongos> sh.status()
--- Sharding Status ---
sharding version: {
     "_id" : 1,
     "minCompatibleVersion" : 5,
     "currentVersion" : 6,
     "clusterId" : ObjectId("5d33d395fb77650f834a9fef")
}
    shards:
        {  "_id" : "shard1",  "host" : "shard1/192.168.194.130:27001,192.168.194.132:27001",  "state" : 1 }
        {  "_id" : "shard2",  "host" : "shard2/192.168.194.132:27002,192.168.194.133:27002",  "state" : 1 }
        {  "_id" : "shard3",  "host" : "shard3/192.168.194.130:27003,192.168.194.133:27003",  "state" : 1 }
most recently active mongoses:
    "3.4.21" : 2
autosplit:
    Currently enabled: yes
balancer:
    Currently enabled:  yes
    Currently running:  no
NaN
        Failed balancer rounds in last 5 attempts:  0
        Migration Results for the last 24 hours:
            No recent migrations
databases:
    {  "_id" : "testdb",  "primary" : "shard2",  "partitioned" : true }
        testdb.table1
            shard key: { "id" : 1 }
            unique: false
            balancing: true
            chunks:
                shard21
            { "id" : { "$minKey" : 1 } } -->> { "id" : { "$maxKey" : 1 } } on : shard2 Timestamp(1, 0)
    {  "_id" : "db2",  "primary" : "shard3",  "partitioned" : true }
        db2.cl2
            shard key: { "id" : 1 }
            unique: false
            balancing: true
            chunks:
                shard31
            { "id" : { "$minKey" : 1 } } -->> { "id" : { "$maxKey" : 1 } } on : shard3 Timestamp(1, 0)
    {  "_id" : "db3",  "primary" : "shard3",  "partitioned" : true }
            db3.cl3
            shard key: { "id" : 1 }
            unique: false
            balancing: true
            chunks:
                shard31
        { "id" : { "$minKey" : 1 } } -->> { "id" : { "$maxKey" : 1 } } on : shard3 Timestamp(1, 0)

可以看到,数据被分到了 shard2、shard3 下

数据量非常大的情况下,才会均匀分布


21.41 mongodb备份恢复

1、备份指定库

mongodump --host --port -d 数据库 -o 备份到哪里

[root@arslinux-01 ~]# mongodump --host 192.168.194.130 --port 20000 -d testdb -o /tmp/mongobak/
2019-07-21T16:23:27.581+0800writing testdb.table1 to
2019-07-21T16:23:27.769+0800done dumping testdb.table1 (10000 documents)
[root@arslinux-01 ~]# ls /tmp/mongobak/
testdb
[root@arslinux-01 ~]# ls /tmp/mongobak/testdb/
table1.bson  table1.metadata.json
[root@arslinux-01 ~]# du -sh /tmp/mongobak/testdb/*
528K/tmp/mongobak/testdb/table1.bson
4.0K/tmp/mongobak/testdb/table1.metadata.json
[root@arslinux-01 ~]# cat /tmp/mongobak/testdb/table1.metadata.json
{"options":{},"indexes":[{"v":2,"key":{"_id":1},"name":"_id_","ns":"testdb.table1"},{"v":2,"key":{"id":1.0},"name":"id_1","ns":"testdb.table1"}]}

2、备份所有库

mongodump --host --port -o 备份到哪里

[root@arslinux-01 ~]# mongodump --host 192.168.194.130 --port 20000 -o /tmp/mongobak2/
[root@arslinux-01 ~]# ll /tmp/mongobak2/
总用量 0
drwxrwxr-x 2 root root  80 7月  21 16:31 admin
drwxrwxr-x 2 root root 480 7月  21 16:31 config
drwxrwxr-x 2 root root  80 7月  21 16:31 db2
drwxrwxr-x 2 root root  80 7月  21 16:31 db3
drwxrwxr-x 2 root root  80 7月  21 16:31 testdb

3、备份指定的集合

mongodump --host --port -d 数据库 -c 集合 -o 备份到哪里
[root@arslinux-01 ~]# mongodump --host 192.168.194.130 --port 20000 -d testdb -c table1 -o /tmp/mongobak3/
2019-07-21T16:34:17.219+0800writing testdb.table1 to
2019-07-21T16:34:17.414+0800done dumping testdb.table1 (10000 documents)
[root@arslinux-01 ~]# ll /tmp/mongobak3/
总用量 0
drwxrwxr-x 2 root root 80 7月  21 16:34 testdb

4、导出集合为 json 文件

[root@arslinux-01 ~]# mongoexport --host 192.168.194.130 --port 20000 -d testdb -c table1 -o /tmp/table1.json
2019-07-21T16:38:59.255+0800connected to: 192.168.194.130:20000
2019-07-21T16:38:59.581+0800exported 10000 records

table1.json 中就是我们插入的一条一条的数据

5、恢复所有库

1)先删除几个库

[root@arslinux-01 ~]# mongo --host 192.168.194.130 --port 20000
mongos> use testdb
switched to db testdb
mongos> db.dropDatabase()
{ "dropped" : "testdb", "ok" : 1 }
mongos> use db2
switched to db db2
mongos> db.dropDatabase()
{ "dropped" : "db2", "ok" : 1 }
mongos> use db3
switched to db db3
mongos> db.dropDatabase()
{ "dropped" : "db3", "ok" : 1
mongos> show databases
admin   0.000GB
config  0.001GB

2)config 是没办法恢复的,备份中先删除 config 和 admin

[root@arslinux-01 ~]# rm -rf /tmp/mongobak2/admin/
[root@arslinux-01 ~]# rm -rf /tmp/mongobak2/config/

3)恢复

[root@arslinux-01 ~]# mongorestore --host 192.168.194.130 --port 20000 --drop /tmp/mongobak2/
[root@arslinux-01 ~]# mongo --host 192.168.194.130 --port 20000
mongos> show databases
admin   0.000GB
config  0.001GB
db2     0.000GB
db3     0.000GB
testdb  0.000GB

6、恢复指定库

[root@arslinux-01 ~]# mongorestore --host 192.168.194.130 --port 20000 -d testdb --drop

7、恢复集合(这里要指定 bson 文件)


[root@arslinux-01 ~]# mongorestore --host 192.168.194.130 --port 20000 -d testdb -c table1 --drop /tmp/mongobak/testdb/table1.bson

8、导入集合

[root@arslinux-01 ~]# mongoimport --host 192.168.194.130 --port 20000 -d testdb -c table1 --file /tmp/mongobak/testdb/table1.metadata.json
2019-07-21T16:55:31.703+0800connected to: 192.168.194.130:20000
2019-07-21T16:55:31.756+0800imported 1 document

之前写的博客被删掉了,说是使用了外链。。。