天天看點

【0716】NoSQL——mogodb

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和關系型資料庫對比:

【0716】NoSQL——mogodb

關系型資料庫資料結構:

【0716】NoSQL——mogodb

MongoDB資料結構:

【0716】NoSQL——mogodb

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 的版本,比較老,以後就不在使用了

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

副本集架構圖:

【0716】NoSQL——mogodb
【0716】NoSQL——mogodb

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 分片架構圖:

【0716】NoSQL——mogodb

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