MONGODB 叢集 配置及 用戶端PHP 串連

來源:互聯網
上載者:User

前面看MONGODB 的叢集配置,但一直沒關係用戶端是怎麼串連的。以為在沒有使用分區時,也可以使用mongos 及 config server 來處理。

在測試組態時,看到,並不是這回事。沒有share時,config server 是無法配置的。


同時在這次配置時,也遇到存取權限問題,主要還是沒理解叢集伺服器keyfile 的使用。(加了keyfile,必須使用使用者/密碼登入,功能類似於-- auth)


這裡做一個記錄。



mongodb 配置2資料節點+1仲裁節點的叢集


1 建立相關目錄:
    mkdir /opt/mongodb/key
    mkdir /opt/mongodb/config
    mkdir /opt/mongodb/db1
    mkdir /opt/mongodb/db2
    mkdir /opt/mongodb/db3


2.建立key 檔案

    2.1 添加檔案
    echo "this is key file" >> r1
    echo "this is key file" >> r2
    echo "this is key file" >> r3

    2.2 配置許可權,設定為唯讀
    chmod 600 r1 r2 r3


3.啟動進程

    /opt/mongodb/mongodb-linux-x86_64-2.5.5/bin/mongod --replSet rs1 --keyFile /opt/mongodb/key/r1 -dbpath=/opt/mongodb/db1 -logpath=/opt/mongodb/logs/mongodb_rep1.log --logappend  --directoryperdb --fork  --journal --port 28011

    /opt/mongodb/mongodb-linux-x86_64-2.5.5/bin/mongod --replSet rs1 --keyFile /opt/mongodb/key/r2 -dbpath=/opt/mongodb/db2 -logpath=/opt/mongodb/logs/mongodb_rep2.log --logappend  --directoryperdb --fork  --journal --port 28012

    /opt/mongodb/mongodb-linux-x86_64-2.5.5/bin/mongod --replSet rs1 --keyFile /opt/mongodb/key/r3 -dbpath=/opt/mongodb/db3 -logpath=/opt/mongodb/logs/mongodb_rep3.log --logappend  --directoryperdb --fork  --journal --port 28013

(注意: 添加了--directoryperdb 參數,如果沒有添加此參數不會成功)

4.初始化replica set

    用mongo串連其中一個mongod(例如:./mongo localhost:28011 )執行:

    > config = {_id:"rs1",members:[{_id:0,host:'localhost:28011'},{_id:1,host:'localhost:28012'}]}

        --,{_id:2,host:'localhost:28013',"arbiterOnly":true}                                                                                            
    > rs.initiate(config);

        也可以使用另外加入第三個節點的方式配置
        因為是在同一台伺服器配置叢集,為了節省磁碟空間,第3個節點會設定成是一個仲裁節點,(沒有資料)
        rs.add({_id:2,"host":"localhost:28013","arbiterOnly":true});



完成後查看狀態:

    rs1:PRIMARY> rs.status()
    {
        "set" : "rs1",
        "date" : ISODate("2014-06-04T15:24:37Z"),
        "myState" : 1,
        "members" : [
            {
                "_id" : 0,
                "name" : "localhost:28011",
                "health" : 1,
                "state" : 1,
                "stateStr" : "PRIMARY",
                "uptime" : 454,
                "optime" : Timestamp(1401895370, 1),
                "optimeDate" : ISODate("2014-06-04T15:22:50Z"),
                "self" : true
            },
            {
                "_id" : 1,
                "name" : "localhost:28012",
                "health" : 1,
                "state" : 2,
                "stateStr" : "SECONDARY",
                "uptime" : 140,
                "optime" : Timestamp(1401895370, 1),
                "optimeDate" : ISODate("2014-06-04T15:22:50Z"),
                "lastHeartbeat" : ISODate("2014-06-04T15:24:35Z"),
                "lastHeartbeatRecv" : ISODate("2014-06-04T15:24:35Z"),
                "pingMs" : 0,
                "syncingTo" : "localhost:28011"
            },
            {
                "_id" : 3,
                "name" : "localhost:28013",
                "health" : 1,
                "state" : 7,
                "stateStr" : "ARBITER",
                "uptime" : 107,
                "lastHeartbeat" : ISODate("2014-06-04T15:24:36Z"),
                "lastHeartbeatRecv" : ISODate("2014-06-04T15:24:35Z"),
                "pingMs" : 0
            }
        ],
        "ok" : 1
    }




測試:
先在測試表中插入一條記錄
    > db.test.insert(_id:1,userid:1,name:'tang');
    2014-06-04T11:35:24.335+0000 SyntaxError: Unexpected token :
    > db.test.insert({_id:1,userid:1,name:'tang'});
    SingleWriteResult({
        "writeErrors" : [ ],
        "writeConcernErrors" : [ ],
        "nInserted" : 1,
        "nUpserted" : 0,
        "nUpdated" : 0,
        "nModified" : 0,
        "nRemoved" : 0,
        "upserted" : [ ]
    })
    > db.test.find()
    { "_id" : ObjectId("5302c433b5b61e345817fb07"), "userid" : 1, "name" : "maketion ltd", "email" : "admin@maketion.com", "password" : "psd" }
    { "_id" : ObjectId("53871082ed9422a9e22abc0c"), "company" : "" }
    { "_id" : ObjectId("53871098ed9422a9e22abc0d"), "company" : { "_mongo" : { "slaveOk" : false, "host" : "localhost:28001", "authStatus" : { "authRequired" : true, "replSetGetStatus" : false, "isMaster" : true }, "_useWriteCommands" : true }, "_db" : { "_mongo" : { "slaveOk" : false, "host" : "localhost:28001", "authStatus" : { "authRequired" : true, "replSetGetStatus" : false, "isMaster" : true }, "_useWriteCommands" : true }, "_name" : "mdsp" }, "_shortName" : "a.name", "_fullName" : "mdsp.a.name" }, "name" : "maketion Ltd" }
    { "_id" : 1, "userid" : 1, "name" : "tang" }
    >


以下資料檔案拷貝是基於參數 (--directoryperdb) 下完成的

1.關閉所有節點,

2.完成叢集配置後,把單機環境下的資料庫目錄,拷貝到各節點資料庫目錄下,並保護資料檔案的屬性。
cp -pR  db/mdsp  db1/
cp -pR  db/mdsp  db2/


3.重啟各節點,進入後檢查資料庫是否和原單節點一致。


4.如果 MongoDB 伺服器啟動時使用了 --auth 或 --keyFile 參數,你就必須在進行任何操作前進行認證。 你可以在串連時進行認證。方法是在連結字串中指定使用者名稱密碼,
或者在 MongoClient::__construct() 建構函式中指定 "username" 和 "password"。




上面是一段官方說明。這個以前不知道加了 keyFile 必須使用使用者/密碼登入。搞了很久。

mongo localhost:28011 -u root -p root 登入,看到沒有提示錯誤了。
以下是沒有使用使用者/密碼登入的錯誤資訊:

    ------------------------------遇到的問題描述------------------------
    伺服器沒有添加 --auth 啟動,
    mongo 登入時,也會出沒有許可權的提示,這可能和上面的授權有關係。聯絡到上面的話題,大概這命令就是這個功能吧。

    下面是遇到的錯誤提示。希望對大家有啟發


    在叢集環境下,啟動參加中也沒加AUTH。但登入時,說沒有許可權。 錯誤如下:
    [mongo@localhost bin]$ ./mongo -port 28011/admin
    MongoDB shell version: 2.5.5
    2014-06-05T10:53:18.292+0000 Error: Invalid port number "28011/admin" in connection string "127.0.0.1:28011/admin/test" at src/mongo/shell/mongo.js:135
    exception: connect failed
    [mongo@localhost bin]$ ./mongo localhost:28011/admin
    MongoDB shell version: 2.5.5
    connecting to: localhost:28011/admin
    Error while trying to show server startup warnings: not authorized on admin to execute command { getLog: "startupWarnings" }
    rs1:SECONDARY> exit
    bye
    [mongo@localhost bin]$ ./mongo localhost:28012/admin
    MongoDB shell version: 2.5.5
    connecting to: localhost:28012/admin
    Error while trying to show server startup warnings: not authorized on admin to execute command { getLog: "startupWarnings" }
    rs1:PRIMARY> use admin
    switched to db admin
    rs1:PRIMARY> show collections;
    2014-06-05T10:54:43.063+0000 error: {
                    "$err" : "not authorized for query on admin.system.namespaces",
                    "code" : 13
    } at src/mongo/shell/query.js:131
    rs1:PRIMARY>


    看到日誌中 有個 user:"__system",key:"xxx" 這是預設的還是什麼。
    2014-06-05T10:57:22.688+0000 [conn14] end connection 127.0.0.1:34299 (3 connections now open)
    2014-06-05T10:57:22.689+0000 [initandlisten] connection accepted from 127.0.0.1:34301 #15 (4 connections now open)
    2014-06-05T10:57:22.689+0000 [conn15]  authenticate db: local { authenticate: 1, nonce: "xxx", user: "__system", key: "xxx" }
    2014-06-05T10:57:52.696+0000 [conn15] end connection 127.0.0.1:34301 (3 connections now open)
    2014-06-05T10:57:52.696+0000 [initandlisten] connection accepted from 127.0.0.1:34303 #16 (4 connections now open)
    2014-06-05T10:57:52.698+0000 [conn16]  authenticate db: local { authenticate: 1, nonce: "xxx", user: "__system", key: "xxx" }
    2014-06-05T10:58:22.704+0000 [conn16] end connection 127.0.0.1:34303 (3 connections now open)
    2014-06-05T10:58:22.705+0000 [initandlisten] connection accepted from 127.0.0.1:34305 #17 (4 connections now open)
    2014-06-05T10:58:22.706+0000 [conn17]  authenticate db: local { authenticate: 1, nonce: "xxx", user: "__system", key: "xxx" }
    2014-06-05T10:58:27.666+0000 [clientcursormon] mem (MB) res:69 virt:9643
    2014-06-05T10:58:27.666+0000 [clientcursormon]  mapped (incl journal view):8924

---------------- end  -------------------------------

5.php 串連叢集伺服器樣本: ,有點象oracle TNS,把多個伺服器位址為列表,讓用戶端進行訪問處理。

<?php
// Using multiple servers as the seed list (prefered)
$m = new MongoClient("mongodb://rs1.example.com:27017,rs2.example.com:27017/?replicaSet=myReplSetName"));

// Using one server as the seed list
$m = new MongoClient("mongodb://rs1.example.com:27017", array("replicaSet" => "myReplSetName"));

// Using multiple servers as the seed list
$m = new MongoClient("mongodb://rs1.example.com:27017,rs2.example.com:27017", array("replicaSet" => "myReplSetName"));
?>


還可以指定讀取最佳化策略:Read Preferences
 You can specify tag sets with the following read preference modes:
    MongoClient::RP_PRIMARY_PREFERRED
    MongoClient::RP_SECONDARY
    MongoClient::RP_SECONDARY_PREFERRED
    MongoClient::RP_NEAREST

// Prefer the nearest server in the "east" data center also used for reporting,
// but fall back to a server in the "west" data center
$uri  = 'mongodb://rs1.example.com,rs2.example.com/';
$uri .= '?readPreference=nearest';
$uri .= '&readPreferenceTags=dc:east,use:reporting';
$uri .= '&readPreferenceTags=dc:west';
$m = new MongoClient($uri, array('replicaSet' => 'rs'));

更多參考如下:
http://www.php.net/manual/zh/mongo.connecting.rs.php

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.