Mongodb-複製

複製:兩種架構

1、一個master(讀寫),多個slave(讀),但是mongodb這種架構無法實現故障自動轉移

2、副本集:

複製集、副本集:Replica set,至少三個節點,通過選舉選出1個主節點和2個備節點。主節點負責讀寫,備節點監控主節點並從主節點上獲得其心跳信息。萬一主節點掛了,則剩下的節點通過選舉選出新的主節點,備節點則自動將其主節點指向新的主節點。能實現自動故障轉移。在實現複製時,必須指明處於哪個副本集,所有節點都要明確工作於某個副本之上,只在此副本實現主從架構。如果還有其他節點,但其他節點所處的集羣名稱不一樣的話,就處於不同的複製架構中。集羣名稱通過副本集名稱定義的。主節點將所有的寫操作寫在一個日誌文件(oplog)中,從節點複製寫操作並在本地執行一遍。這個複製是異步的。

還有一種情況:

    三個節點中有一個節點不存任何數據,只有選舉權,而沒有被選舉權。這樣會導致假如一個節點掛了後,剩下的一個節點沒有從節點,這樣那個活動節點要降級爲只讀模式,因爲它無法保證數據有副本存放的。

副本集參數:

replset:副本集名稱

oplogsize:日誌大小

fastsync:快速同步

replindexprefetch:在實現複製時,根據索引實現數據預取。這種特性可以實現快速裝載主節點上的數據,尤其在修改量比較大的集羣上,非常有意義,在2.2.2版本實現


實驗:

條件:

所有節點時間同步

配置文件中的集羣名稱一致

三個節點都安裝mongodb

三個節點的/etc/hosts文件設置如下:

圖片.png

三個節點都創建數據目錄、更改屬主屬組、修改配置文件請看上文

配置文件最後加上:

圖片.png

rest = true 顯示按鈕的相關信息

複製配置文件到另外兩個節點:

圖片.png

啓動服務:(三個節點都啓動)

連接到任意節點執行副本集初始化命令即可。(rs命令)

圖片.png

rs.status:顯示rs狀態

rs.initiate:初始化,第一次實現創建副本集要用這個命令初始化

rs.initiate(cfg):通過配置文件來初始化,配置文件由下面的命令獲得

rs.conf:獲取配置文件

rs.reconfig(cfg):重新初始化

rs.add(hostportstr):添加從節點的端口號

rs.add(membercfgobj):添加從節點

初始化:

圖片.png

查看狀態:

圖片.png

查看是否爲主節點:

圖片.png

添加從節點並查看信息:

testrs0:PRIMARY> rs.add("192.168.0.22:27017")
{ "ok" : 1 }
testrs0:PRIMARY> rs.status()
{
    "set" : "testrs0",
    "date" : ISODate("2016-11-29T14:25:50Z"),
    "myState" : 1,
    "members" : [
        {
            "_id" : 0,
            "name" : "node1:27017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 557,
            "optime" : Timestamp(1480429519, 1),
            "optimeDate" : ISODate("2016-11-29T14:25:19Z"),
            "self" : true
        },
        {
            "_id" : 1,
            "name" : "192.168.0.22:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 31,
            "optime" : Timestamp(1480429519, 1),
            "optimeDate" : ISODate("2016-11-29T14:25:19Z"),
            "lastHeartbeat" : ISODate("2016-11-29T14:25:49Z"),
            "lastHeartbeatRecv" : ISODate("2016-11-29T14:25:50Z"),
            "pingMs" : 0,
            "syncingTo" : "node1:27017"
        }
    ],
    "ok" : 1
}

添加第二個節點並查看狀態:(不知爲何會不一樣)

testrs0:PRIMARY> rs.add("192.168.0.23:27017")
{ "down" : [ "192.168.0.23:27017" ], "ok" : 1 }
testrs0:PRIMARY> rs.status()
{
    "set" : "testrs0",
    "date" : ISODate("2016-11-29T14:28:05Z"),
    "myState" : 1,
    "members" : [
        {
            "_id" : 0,
            "name" : "node1:27017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 692,
            "optime" : Timestamp(1480429663, 1),
            "optimeDate" : ISODate("2016-11-29T14:27:43Z"),
            "self" : true
        },
        {
            "_id" : 1,
            "name" : "192.168.0.22:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 166,
            "optime" : Timestamp(1480429663, 1),
            "optimeDate" : ISODate("2016-11-29T14:27:43Z"),
            "lastHeartbeat" : ISODate("2016-11-29T14:28:04Z"),
            "lastHeartbeatRecv" : ISODate("2016-11-29T14:28:04Z"),
            "pingMs" : 0,
            "syncingTo" : "node1:27017"
        },
        {
            "_id" : 2,
            "name" : "192.168.0.23:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 22,
            "optime" : Timestamp(1480429663, 1),
            "optimeDate" : ISODate("2016-11-29T14:27:43Z"),
            "lastHeartbeat" : ISODate("2016-11-29T14:28:03Z"),
            "lastHeartbeatRecv" : ISODate("2016-11-29T14:28:04Z"),
            "pingMs" : 2,
            "syncingTo" : "node1:27017"
        }
    ],
    "ok" : 1
}

查看master:

圖片.png

在主節點創建數據,看從能否獲取到

主節點:

testrs0:PRIMARY> use testdb
switched to db testdb
testrs0:PRIMARY> db.testcoll.insert({Name:'test',Age:50,Gender:'F'})
testrs0:PRIMARY> db.testcoll.find({Name:'test'})
{ "_id" : ObjectId("583d92d63b539fcc9aef4fd4"), "Name" : "test", "Age" : 50, "Gender" : "F"

從節點:

從節點不能直接查詢的,必須使用rs.slaveOk()把自己提升爲可以接受查詢的從節點

testrs0:SECONDARY> rs.slaveOk()
testrs0:SECONDARY> use testdb
switched to db testdb
testrs0:SECONDARY> db.testcoll.find({Name:'test'})
{ "_id" : ObjectId("583d92d63b539fcc9aef4fd4"), "Name" : "test", "Age" : 50, "Gender" : "F" }

讓主節點掛點,看是否有一個會提升爲主的:

停止主節點的服務即可:

[root@node1 ~]# service mongod stop
Stopping mongod:                                           [  OK   ]

在剛纔的備節點查看狀態:

testrs0:SECONDARY> rs.status()
{
    "set" : "testrs0",
    "date" : ISODate("2016-11-29T14:45:20Z"),
    "myState" : 1,
    "members" : [
        {
            "_id" : 0,
            "name" : "node1:27017",
            "health" : 0,
            "state" : 8,
            "stateStr" : "(not reachable/healthy)",
            "uptime" : 0,
            "optime" : Timestamp(1480430294, 1),
            "optimeDate" : ISODate("2016-11-29T14:38:14Z"),
            "lastHeartbeat" : ISODate("2016-11-29T14:45:19Z"),
            "lastHeartbeatRecv" : ISODate("2016-11-29T14:44:00Z"),
            "pingMs" : 0
        },
        {
            "_id" : 1,
            "name" : "192.168.0.22:27017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 1210,
            "optime" : Timestamp(1480430294, 1),
            "optimeDate" : ISODate("2016-11-29T14:38:14Z"),
            "self" : true
        },
        {
            "_id" : 2,
            "name" : "192.168.0.23:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 1056,
            "optime" : Timestamp(1480430294, 1),
            "optimeDate" : ISODate("2016-11-29T14:38:14Z"),
            "lastHeartbeat" : ISODate("2016-11-29T14:45:19Z"),
            "lastHeartbeatRecv" : ISODate("2016-11-29T14:45:19Z"),
            "pingMs" : 1,
            "lastHeartbeatMessage" : "syncing to: 192.168.0.22:27017",
            "syncingTo" : "192.168.0.22:27017"
        }
    ],
    "ok" : 1
}
testrs0:PRIMARY>   #這裏已經改爲主的了

圖片.png

在新的主節點添加數據:

圖片.png

然後在從節點查看:

圖片.png

讓之前的主節點從新上線:

圖片.png

testrs0:PRIMARY> rs.status()
{
    "set" : "testrs0",
    "date" : ISODate("2016-11-29T14:50:31Z"),
    "myState" : 1,
    "members" : [
        {
            "_id" : 0,
            "name" : "node1:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",   #其狀態不再是主的了
            "uptime" : 45,
            "optime" : Timestamp(1480430874, 1),
            "optimeDate" : ISODate("2016-11-29T14:47:54Z"),
            "lastHeartbeat" : ISODate("2016-11-29T14:50:30Z"),
            "lastHeartbeatRecv" : ISODate("2016-11-29T14:50:29Z"),
            "pingMs" : 1,
            "lastHeartbeatMessage" : "syncing to: 192.168.0.22:27017",
            "syncingTo" : "192.168.0.22:27017"
        },
        {
            "_id" : 1,
            "name" : "192.168.0.22:27017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 1521,
            "optime" : Timestamp(1480430874, 1),
            "optimeDate" : ISODate("2016-11-29T14:47:54Z"),
            "self" : true
        },
        {
            "_id" : 2,
            "name" : "192.168.0.23:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 1367,
            "optime" : Timestamp(1480430874, 1),
            "optimeDate" : ISODate("2016-11-29T14:47:54Z"),
            "lastHeartbeat" : ISODate("2016-11-29T14:50:29Z"),
            "lastHeartbeatRecv" : ISODate("2016-11-29T14:50:29Z"),
            "pingMs" : 1,
            "syncingTo" : "192.168.0.22:27017"
        }
    ],
    "ok" : 1
}

打印複製信息:

圖片.png



圖片.png


圖片.png


配置優先級:

rs.conf()顯示現有的配置

testrs0:SECONDARY> rs.conf()
{
    "_id" : "testrs0",
    "version" : 3,
    "members" : [
        {
            "_id" : 0,
            "host" : "node1:27017"
        },
        {
            "_id" : 1,
            "host" : "192.168.0.22:27017"
        },
        {
            "_id" : 2,
            "host" : "192.168.0.23:27017"
        }
    ]
}

編輯配置文件:

方式1:rs.conf({id:xxx}),這種方式比較麻煩

方式2:把內容保存到文件中,重新應用就可以了

cfg=rs.conf()保存文件

cfg.members[0].priority=2設置優先級

rs.reconfig(cfg)重新應用

只能在主節點進行配置:

圖片.png

40-45從看

三個節點理由有一個可以不被選舉,只參與選舉,無法觸發選舉,但可以參與選舉。這種節點的優先級爲0

觸發重新選舉:

    一個幾點只能以從節點的身份去上線,然後主節點主持重新選舉。

    優先級爲0的節點:無權觸發,僅參與選舉

添加優先級爲0的節點:rs.addArb(hostportstr)

移除節點:rs.remove(hostportstr)



Sharding:把一個很大的表的數據切割後放到不同的節點,各節點只存放一部分。每個服務器成爲一個sharding節點。把每個collection分割爲多片,平均分配到各節點。均勻分配。

用途:

    複製集很大、吞吐量大

    高併發查詢可能耗盡cpu的處理能力

    海量數據集超出某一個節點的存儲能力

    降低單臺服務器的io壓力

sharding架構:

圖片.png

config servers:存儲元數據

shard:存儲數據

讀操作:請求過來了,app server先去查找元數據,再查找shard。性能不好,因爲各索引在shard節點中

寫操作:shard特長

shard必須和業務數據相關聯。

生產環境中應該至少有三個config server節點,這些服務器壓力很小,所以可以放到運行其他應用的節點

mongos:端口28017,用來接收用戶請求,合併數據,扮演前段的代理服務器。router之間不會通信。mongos1個也可以,mongos也可以直接安裝到應用服務器中

shard:至少有2個


實驗:1個mongos,1個config server,2個shard

1、配置config server

2、配置mongos

3、配置shard


配置config server:192.168.0.22

圖片.png

圖片.png

保存退出,重啓服務

圖片.png

端口:

圖片.png

配置mongos:

圖片.png

圖片.png

圖片.png

圖片.png

啓動shard:

只需改下數據目錄,重啓服務即可


下圖中的A爲主shard:

圖片.png

連接mongos:

圖片.png

查看shard狀態:

圖片.png

添加shard:在192.168.0.22上添加

 圖片.png

使用分區功能:sh.enableSharding(dbname)

圖片.png

collection支持分區功能:sh.shardCollection(fullName,key,unique)

圖片.png

圖片.png


添加數據:

圖片.png

在mongos上查看分片:192.168.0.21

圖片.png


圖片.png

完成重新均衡:

sh.addShard(host)添加新的shade

sh.setBalancerState均衡

查看是否均衡:

圖片.png


補充:

php訪問mongodb,需要編譯相應的驅動。

aubiter:僅參與選舉,不持有任何數據

0優先級的節點:持有數據,參與選舉,但不能成爲主節點

shard:

    讀:不離散

    寫:離散


選擇sharding key的標準:

    應該在哪裏存儲數據

    應該從哪裏得到希望的數據

    

基本法則:

    sharding key應該是主鍵

    sharding key應該能儘量保證避免跨分片查詢


自學:

    1、新增shard

    2、移除shard


命令:

    mongodump:備份

    mongorestore:恢復

    mongoexport:導出

    mongoimport:導入

    mongostat:監控

    mongotop:

    mongooplog:

    mongoperf:性能評估

    mongofiles:查看和修改GridFS文件系統













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