mongo小結和使用示例


mongo小結(>=2.2)

1、存儲模式:面向集合存儲,模式自由; GridFS大文件存儲(16M)

2、容災類型:主從復制(Replication)、Replica Set(自動選取主節點)、Sharding + Replica Set。

說明:mongo的Replication采用日志+批量更新方式,效率比直接更新高,Replication更新期間,從節點讀性能受影響(鎖機制導致)。

3、支持CRUD 和 Fast In-Place Updates(文檔內更新)。

說明:Fast In-Place Updates支持快速更新文檔自身內容,對於不影響文檔大小的更新,效率比覆蓋更新整個文檔效率高。為了支持改變文檔大小的文檔內更新,mongo內部采用padding,即采用比文檔略大的空間存儲文檔,當更新導致文檔大小改變時,如改變大小不超過padding大小,就地更新,無須另外存儲。padding比例由mongo自身決定。

4、讀寫鎖,寫鎖優先

說明:mongo的鎖機制對於解釋mongo運行效率很重要。常見需要寫鎖的操作:insert、update、remove、eval(執行命令或腳本)、createIndex(創建索引需鎖定整個collection,數據大時,相當耗時)、replication、TTL的定期刪除。

5、存儲機制:mmap file + 內存索引。完全由OS處理緩存。磁盤空間預分配(默認2G)。

說明:mongo將內存管理和緩存都交給OS。內存優先讓給索引使用。當索引大於內存大小時,將影響各種操作。當"工作集"(熱門數據)+索引 大於 內存時,查詢性能受影響。

6、集合類型:普通集合、TTL Collection(淘汰過期數據)、 Capped Collection(定長集合,FIFO)

7、同步:拷貝集合數據+日志同步

8、相對豐富的運維工具和shell客戶端

使用示例

// this header should be first to ensure that it includes cleanly in any context
#include "mongo/client/dbclient.h"

#include <iostream>
#include <vector>
#include <string>

#ifndef verify
#  define verify(x) MONGO_verify(x)
#endif

using namespace std;
using namespace mongo;

int connect_mongo(DBClientConnection* conn, const string& ip, const string& port)
{ 
    try{
        if( conn->getServerAddress().empty() ){   // not init
            string errmsg;
            if( ! conn->connect( ip  + ":" + port , errmsg ) ){
                printf("FAIL connect mongo, %s", errmsg.c_str());
                return -1;
            }
        }

        if (conn->isFailed()) {
            string errmsg;
            if ( ! conn->connect( ip  + ":" + port , errmsg ) ) {
                printf("FAIL connect mongo, %s", errmsg.c_str());
                return -1;
            }
        }
    }
    catch( DBException& e ) {
        printf("MONGO Exception(connect): %s", e.what());
        return -1;
    }
    catch ( std::exception& e ) {  
        printf("MONGO Exception(connect): %s", e.what());
        return -1;
    }
    catch( ... ){
        printf("MONGO Exception(connect): NULL");
        return -1;
    }

    return 0;
}

int set_mongo(DBClientConnection* conn, const string& dbname, const string& id, const string& value)
{
    try{
        mongo::BSONObjBuilder b;
        long long curtime = time(NULL);
        Date_t date( (curtime - curtime % (3600*24) + ( random() % 6 + 2) * 3600) * 1000 ); // limit ttl deleting time to 2:00-8:00. 

        b.append( "_id", id );
        b.append( "value", value);
        b.append( "ts", date);

        //cout<< b.obj() << endl;
        conn->update( dbname , BSONObjBuilder().append( "_id" , id ).obj(), b.obj(), true );
    }
    catch( DBException& e ) {
        printf("MONGO Exception(set): %s", e.what());
        return -1;
    }
    catch ( std::exception& e ) {  
        printf("MONGO Exception(set): %s", e.what());
        return -1;
    }
    catch( ... ){
        printf("MONGO Exception(set): NULL");
        return -1;
    }

    return 0;
}

int get_mongo(DBClientConnection* conn, const string& dbname, const string& id, string& value)
{
    try{
        BSONObj obj = conn->findOne( dbname, BSONObjBuilder().append( "_id" , id ).obj()); 
        if( !obj.isEmpty() ){
            value = obj.getStringField("value");
        }
    }
    catch( DBException& e ) {
        printf("MONGO Exception(get): %s", e.what());
        return -1;
    }
    catch ( std::exception& e ) {  
        printf("MONGO Exception(get): %s", e.what());
        return -1;
    }
    catch( ... ){
        printf("MONGO Exception(get): NULL");
        return -1;
    }

    return 0;
}

int mget_mongo(DBClientConnection* conn, const string& dbname, const vector<string>& ids, vector<string>& values)
{
    try{
        mongo::BSONObjBuilder b;
        b.append( "$in",  ids);

        auto_ptr<DBClientCursor> cursor = conn->query( dbname, BSON( "_id" << b.obj() ));
        while ( cursor->get() && cursor->more() ) {
            BSONObj obj = cursor->next();

            if( !obj.isEmpty() ){
                values.push_back(obj.getStringField("value"));
            }
        }
    }
    catch( DBException& e ) {
        printf("MONGO Exception(get): %s", e.what());
        return -1;
    }
    catch ( std::exception& e ) {  
        printf("MONGO Exception(get): %s", e.what());
        return -1;
    }
    catch( ... ){
        printf("MONGO Exception(get): NULL");
        return -1;
    }

    return 0;
}

int del_mongo(DBClientConnection* conn, const string& dbname, const string& id)
{
    try{
        conn->remove( dbname, BSONObjBuilder().append( "_id" , id ).obj()); 
    }
    catch( DBException& e ) {
        printf("MONGO Exception(del): %s", e.what());
        return -1;
    }
    catch ( std::exception& e ) {  
        printf("MONGO Exception(del): %s", e.what());
        return -1;
    }
    catch( ... ){
        printf("MONGO Exception(del): NULL");
        return -1;
    }

    return 0;
}

void Print(DBClientConnection& conn, const string& dbname)
{
    auto_ptr<DBClientCursor> cursor = conn.query( dbname , BSONObj() );
    int count = 0;
    while ( cursor->more() ) {
        count++;
        BSONObj obj = cursor->next();
        std::cout<< obj << std::endl;
    }
}

int main( int argc, const char **argv ) 
{
    const char *port = "27000";
    string host( "127.0.0.1" );
    if ( argc < 3 ) {
        std::cout << argv[0] << " dbname host [port]" << endl;
        return EXIT_FAILURE;
    }

    const char* dbname = argv[1];

    if( argc >= 3){
        host = string(argv[2]);
    }
    if( argc >= 4){
        port = argv[3];
    }

    {
        DBClientConnection conn( false , 0 , 2 );
        if( connect_mongo(&conn, host, port) != 0)
        {
            exit(-1);
        }

        string id = "test123";
        string value = "test456";
        del_mongo(&conn, dbname, id);
        set_mongo(&conn, dbname, id, value);

        string ret_val;
        get_mongo(&conn, dbname, id, ret_val);
        if( value != ret_val){
            cout<<"TEST FAIL: " << value << " : " << ret_val <<endl;
        }
    }

    cout << "test finished!" << endl;
    return EXIT_SUCCESS;
}

參考

官方文檔: http://docs.mongodb.org/master/MongoDB-Manual-master.pdf

MongoDB 2.2 的 Time To Live (TTL) 集合: http://www.oschina.net/translate/mongodb-time-to-live-ttl-collections 

C++客戶端代碼的示例


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM