【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和關係型數據庫對比:

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

之前寫的博客被刪掉了,說是使用了外鏈。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章