亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 1474 | 回復(fù): 0
打印 上一主題 下一主題

[MongoDB] MongoDB 創(chuàng)建大量集合測試問題 [復(fù)制鏈接]

求職 : Linux運維
論壇徽章:
203
拜羊年徽章
日期:2015-03-03 16:15:432015年辭舊歲徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:57:092015小元宵徽章
日期:2015-03-06 15:58:182015年亞洲杯之約旦
日期:2015-04-05 20:08:292015年亞洲杯之澳大利亞
日期:2015-04-09 09:25:552015年亞洲杯之約旦
日期:2015-04-10 17:34:102015年亞洲杯之巴勒斯坦
日期:2015-04-10 17:35:342015年亞洲杯之日本
日期:2015-04-16 16:28:552015年亞洲杯紀(jì)念徽章
日期:2015-04-27 23:29:17操作系統(tǒng)版塊每日發(fā)帖之星
日期:2015-06-06 22:20:00操作系統(tǒng)版塊每日發(fā)帖之星
日期:2015-06-09 22:20:00
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2016-08-03 22:38 |只看該作者 |倒序瀏覽
問題背景

對使用 wiredtiger 引擎的 mongod 進行如下測試,不斷的『創(chuàng)建集合、創(chuàng)建索引,插入一條記錄』,然后統(tǒng)計這3個動作的耗時。

var db = db.getSiblingDB("testdb";
for (var i = 0; i < 100000; i++) {
    var start = (new Date()).getTime();
    var collName = "test" + i;
    var doc = {name: "name" +i, seq: i};
    db.createCollection(collName);        // 創(chuàng)建集合
    db[collName].createIndex({name: 1});  // 創(chuàng)建索引
    db[collName].insert(doc);             // 插入一條記錄
    var end = (new Date()).getTime();     // 統(tǒng)計耗時
    print("cost: " + (end - start));
}
隨著集合數(shù)越來越多,測試過程中發(fā)現(xiàn)2個問題

偶爾會出現(xiàn)耗時很長的請求(1s、2s、3s..不斷上升),統(tǒng)計了下頻率,大約1分鐘左右出現(xiàn)一次。
平均耗時不斷增加,從最開始平均10ms 不到,一直到20ms、30ms、40ms…
測試問題1

因為耗時很長的請求頻率大概1分鐘一次,跟 wiredtiger 默認(rèn)的60scheckpoint 很接近,懷疑問題跟 checkpoint 有關(guān),從運行慢日志看,耗時長是因為 createIndex 的原因。

通過當(dāng)時的 pstack 發(fā)現(xiàn),創(chuàng)建索引的線程正在等鎖,只有 checkpoint 線程在干活

Thread 4 (Thread 0x7f80c3c72700 (LWP 70891)):
#0  0x00007f80c2ddc054 in __lll_lock_wait () from /lib64/libpthread.so.0
#1  0x00007f80c2dd7388 in _L_lock_854 () from /lib64/libpthread.so.0
#2  0x00007f80c2dd7257 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3  0x00000000019f3f95 in __wt_curfile_open ()
#4  0x0000000001a580a5 in __session_open_cursor_int ()
#5  0x0000000001a09e13 in __wt_curtable_open ()
#6  0x0000000001a57f29 in __session_open_cursor_int ()
#7  0x0000000001a584b9 in __session_open_cursor ()
#8  0x000000000108cfe9 in mongo::WiredTigerIndex::BulkBuilder:penBulkCursor(mongo::WiredTigerIndex*) ()
#9  0x000000000108841e in mongo::WiredTigerIndexStandard::getBulkBuilder(mongo::OperationContext*, bool) ()
#10 0x0000000000cb09e9 in mongo::IndexAccessMethod::commitBulk(mongo::OperationContext*, std::unique_ptr<mongo::IndexAccessMethod::BulkBuilder, std::default_delete >, bool, bool, std::set<mongo::RecordId, std::less, std::allocator >*) ()
#11 0x0000000000b07410 in mongo::MultiIndexBlock::doneInserting(std::set<mongo::RecordId, std::less, std::allocator >*) ()
#12 0x0000000000b0797d in mongo::MultiIndexBlock::insertAllDocumentsInCollection(std::set<mongo::RecordId, std::less, std::allocator >*) ()


Thread 68 (Thread 0x7f80b9336700 (LWP 37085)):
#0  0x00000000019db9e0 in __config_next ()
#1  0x00000000019dc106 in __config_getraw.isra.0 ()
#2  0x00000000019dc5a6 in __wt_config_getones ()
#3  0x0000000001a2437d in __wt_meta_ckptlist_get ()
#4  0x0000000001a65218 in __checkpoint_worker.isra.10 ()
#5  0x0000000001a64888 in __checkpoint_apply ()
#6  0x0000000001a6657a in __txn_checkpoint ()
#7  0x0000000001a66e17 in __wt_txn_checkpoint ()
#8  0x0000000001a57854 in __session_checkpoint ()
#9  0x00000000019e4f8f in __ckpt_server ()
#10 0x00007f80c2dd5851 in start_thread () from /lib64/libpthread.so.0
#11 0x0000003403ee767d in clone () from /lib64/libc.so.6
為什么建索引會跟 checkpoint 有沖突?分析索引代碼發(fā)現(xiàn),前臺建索引時,mongod 會使用 wiredtiger 的 bulk cursor,而openBulkCursor是要競爭 checkpoint 鎖的(個人理解是避免在 bulk insert 過程中出現(xiàn) checkpoint),所以 createIndex 會阻塞等待 checkpoint 完成。

// src/cursor/cur_file.c:__wt_curfile_open
/* Bulk handles require exclusive access. */
    if (bulk)
        LF_SET(WT_BTREE_BULK | WT_DHANDLE_EXCLUSIVE);

    /* Get the handle and lock it while the cursor is using it. */
    if (WT_PREFIX_MATCH(uri, "file:") {
        /*
         * If we are opening exclusive, get the handle while holding
         * the checkpoint lock.  This prevents a bulk cursor open
         * failing with EBUSY due to a database-wide checkpoint.
         */
        if (LF_ISSET(WT_DHANDLE_EXCLUSIVE))
            WT_WITH_CHECKPOINT_LOCK(session, ret,
                ret = __wt_session_get_btree_ckpt(
                session, uri, cfg, flags));
另外從目前的實現(xiàn)看,后臺建索引時并不是 bulk cursor,而是使用普通的 cursor 逐條插入,故不會去競爭 checkpoint 的鎖,上述測試代碼在createIndex 時加上{background: true}選項時問題解決。

建議用戶在建立索引時,盡量選擇后臺建索引的方式,可能性能上不如前臺方式,但后臺建索引對業(yè)務(wù)的影響是最小的(前臺建索引還會獲取 db 的寫鎖,導(dǎo)致 db 上的讀寫都被阻塞),最好的方式是 DDL 和 DML 分離,在業(yè)務(wù)代碼中不要出現(xiàn)建索引、建集合的邏輯,預(yù)先創(chuàng)建好,業(yè)務(wù)只做CRUD 操作。

測試問題2

這個問題主要跟文件系統(tǒng)機制相關(guān),testdb 下創(chuàng)建了數(shù)萬個集合,對應(yīng)到 wiredtiger 的實現(xiàn),會出現(xiàn)一個目錄下數(shù)萬個文件的情況(集合的每個索引也要對應(yīng)一個文件),而從ext4文件系統(tǒng)層面上,在目錄里創(chuàng)建文件,先要遍歷整個目錄下所有的文件項,文件越多效率越低。

上述問題通常的解決方法是『將扁平化的目錄層次化』,對應(yīng)到 mongodb,就是將數(shù)萬個集合分散到多個 DB 里,具體方法如下。

配置 storage.directoryPerDB 選項為 true
業(yè)務(wù)上將集合分散到多個 DB 里(如100個,平均每個目錄下就只有幾百個文件)
總結(jié)

MongoDB 使用 wiredtiger 引擎時,大量集合的場景(通常業(yè)務(wù)設(shè)計上是有問題的),可能會遇到很多未知的問題,畢竟這不屬于常見的應(yīng)用場景,官方在這方面的測試支持也會相對弱些,比如上述提到的2個問題,還有之前分享的一個集合太多無法同步的問題,建議大家使用 MongoDB 時,合理設(shè)計數(shù)據(jù)模型,避免踩不必要的坑。
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP