MongoDB的十個使用要點
1.mongodb 表名和欄位名統一用小寫字母
mongodb 是預設區分大小寫的,為了避免以前在 mysql 下遇到的大小寫敏感導致程式訪問頻頻出錯,
建立規範,mongodb 的表名和欄位名都用小寫字母命名。
2.儘可能的縮短欄位名的長度
mongodb 的 schema free 導致了每筆資料都要儲存它的 key 以及屬性,這導致了這些資料的大量冗餘。
開發人員也許考慮到,從易讀性出發設計的 key 名,基本都是按照字面意思去設計的,這導致 key 很長,對應的資料儲存佔用了很大的空間。
所以,在你的程式裡維護一套字典即可,儘可能降低 key 的長度。
譬如:
static final String CONTENT = "content";
static final String CONTENT_TYPE = "ctype";
static final String CONTENT_LENGTH = "clen";
3.記住,mongodb 的查詢每次只能用到一個索引
對於較複雜的表結構,可能會導致你頻頻使用聯合索引。
但記住:
1)mongodb 單表最大索引數為 64 。
2)索引越多,插入或修改記錄就會導致 mongodb 越慢。寫鎖會阻塞讀請求,寫得越慢,阻塞讀請求越多、阻塞時間越長。
所以,索引越加越多的時候,你可能需要審視一下表結構設計的合理性。
4.客戶端連線數大小的設定
mongodb-java-driver 的連線池,目前從觀察到的情況是應用一開啟便根據 connectionsPerHost 變數的設定,建立全部連線,然後提供給程式使用,並且一旦其中某個連線到資料庫的訪問失敗,
則會清空整個連線池到這臺資料庫的連線,並重新建立連線。
而 mongodb 對中斷連線的垃圾清理工作則是懶惰的被動清理方式,如果驅動程式端配置的連線數過大,一旦發生重連,則會導致 mongo 伺服器端堆積大量的垃圾連線以及對應資料,導致主機資源耗盡。
建議: mongodb 驅動的連線池大小的設定一般應該控制 100 左右。
( 參考閱讀:PHP-FPM模式下可怕的 MongoDB-PHP-Driver 連線池無節制連線問題)
5.例項分離
mongodb 對資料庫的訪問全部加鎖。
如是查詢請求則設定共享鎖。
資料修改請求則設定全域性排他鎖,且是例項級別的排他鎖。
寫鎖會阻塞讀請求,如果長時間持有寫鎖,會阻塞整個例項的讀請求。
建議:
1)不同應用不應該共用同一個例項,防止互相阻塞!
2)如伺服器資源不足,共用同一個例項,要保證讀寫特性相同,如都是讀多寫少,防止一臺寫多應用阻塞讀請求。
(評語:舊版本的MongoDB (pre 2.0)擁有一個全域性的寫入鎖,這個問題在2.0版本中的得到了顯著的改善,並且在當前2.2版本中得到了進一步的加強。MongoDB 2.2使用資料庫級別的鎖在這個問題上邁進了
一大步。所以用 MongoDB 2.2的人可以忽略此條目。)
6.需要重點關注的 mongodb 效能指標
關注主要效能指標:
1)Faults:顯示 mongodb 每秒頁面故障的數量,這個是 mongodb 對映到虛擬地址空間,而不是實體記憶體。這個值如果飆高的話,可能意味著機器沒有足夠的記憶體來儲存資料和索引。
2)Flushes:每秒做了多少次 fsync,顯示多少次資料被重新整理進了磁碟。
3)locked:寫鎖。
4)idx miss:索引未命中比例。
5)qr | qw:讀寫鎖的請求佇列長度。
6)conn: 當前已經建立的連線數。
7.嚴重的空間碎片問題
mongodb 如果資料修改很頻繁,會出現比較嚴重的空間碎片問題,表現在磁碟檔案擴張與實際資料量不相符,記憶體不夠用,索引命中率低,查詢效率降低。
碎片整理,目前我們採用的版本沒有太有效的方法。
可以用 db.repaireDatabase() 來整理資料庫,這個過程非常的慢。
如果是 master/slave 模式,則相當於執行一次主從切換,然後從新建立從庫。
如果是 replSet 架構,可以停掉資料庫,然後刪除資料目錄,從新從複製組中全同步資料,這個時候要考慮 oplog 的尺寸。
一個大體的步驟:
1)先呼叫rs.freeze(1200),將每個不想讓它成為 primary 的機器讓它在 1200 秒內無法成為 primary(這步也可以不做);
2)將 primary stepDown,不出意外新的 primary 會起來;
3)將原 primary kill 掉;
4)刪掉所有 data 資料(呼叫 repair 很慢,真不如干掉重新來);
5)再重啟動原 primary 的程式;
6)以此迴圈完成整個複製組的全部重建。
8.連線池 WriterConcern 模式選擇
有些應用配置了 WriterConcern.FSYNC_SAFE 模式;這種配置意味著客戶端在插入資料或更新資料的時候,要求 mongodb 必須將所更新的資料寫入磁碟並返回更新成功的資訊給程式。
如果碰上應用程式訪問壓力大,mongodb 就會反應遲鈍,並可能會假死。
針對此情況,需要評估資料的一致性需求,做出合適調整。
我們一般建議關閉此選項。
(評語:劉奎波的業務中心最佳化時就關閉了這個 WriterConcern.FSYNC_SAFE 模式)
9.開發時注意的細節
1)更新某條資料的時候,先查出來再更新會減小鎖的時間;
2)只有真正需要的欄位才select出來;
3)只有返回很少結果的查詢才用索引,否則會載入太多資料,比沒有用索引還慢!
4)屬性比較多的時候,建立分層的關係能夠提高查詢效率,否則每個記錄都要過一遍才能找到要的屬性。(評語:貌似說的是以 Array 形式儲存的 subdocument)
5)skip+limit 翻頁,越往後面越慢。比較靠譜的做法是,先找出上次的id,翻頁的時候不用 skip:
last_row_id = ObjectId('....');
db.activity_stream->find({_id:{$lt: last_row_id },user_id:20 } ).sort( {_id:-1} ).limit(10);
10.關於硬體資源的選擇
虛擬機器可以很好的隔離資源,並可動態的擴充套件。
我們建議 mongodb 的部署採用虛擬機器的方式,每個虛擬機器部署一個例項,使各節點分散在不同的物理機上,根據應用的前期預測,平衡虛擬機器的之間的i/o。
mongodb 是預設區分大小寫的,為了避免以前在 mysql 下遇到的大小寫敏感導致程式訪問頻頻出錯,
建立規範,mongodb 的表名和欄位名都用小寫字母命名。
2.儘可能的縮短欄位名的長度
mongodb 的 schema free 導致了每筆資料都要儲存它的 key 以及屬性,這導致了這些資料的大量冗餘。
開發人員也許考慮到,從易讀性出發設計的 key 名,基本都是按照字面意思去設計的,這導致 key 很長,對應的資料儲存佔用了很大的空間。
所以,在你的程式裡維護一套字典即可,儘可能降低 key 的長度。
譬如:
static final String CONTENT = "content";
static final String CONTENT_TYPE = "ctype";
static final String CONTENT_LENGTH = "clen";
3.記住,mongodb 的查詢每次只能用到一個索引
對於較複雜的表結構,可能會導致你頻頻使用聯合索引。
但記住:
1)mongodb 單表最大索引數為 64 。
2)索引越多,插入或修改記錄就會導致 mongodb 越慢。寫鎖會阻塞讀請求,寫得越慢,阻塞讀請求越多、阻塞時間越長。
所以,索引越加越多的時候,你可能需要審視一下表結構設計的合理性。
4.客戶端連線數大小的設定
mongodb-java-driver 的連線池,目前從觀察到的情況是應用一開啟便根據 connectionsPerHost 變數的設定,建立全部連線,然後提供給程式使用,並且一旦其中某個連線到資料庫的訪問失敗,
則會清空整個連線池到這臺資料庫的連線,並重新建立連線。
而 mongodb 對中斷連線的垃圾清理工作則是懶惰的被動清理方式,如果驅動程式端配置的連線數過大,一旦發生重連,則會導致 mongo 伺服器端堆積大量的垃圾連線以及對應資料,導致主機資源耗盡。
建議: mongodb 驅動的連線池大小的設定一般應該控制 100 左右。
( 參考閱讀:PHP-FPM模式下可怕的 MongoDB-PHP-Driver 連線池無節制連線問題)
5.例項分離
mongodb 對資料庫的訪問全部加鎖。
如是查詢請求則設定共享鎖。
資料修改請求則設定全域性排他鎖,且是例項級別的排他鎖。
寫鎖會阻塞讀請求,如果長時間持有寫鎖,會阻塞整個例項的讀請求。
建議:
1)不同應用不應該共用同一個例項,防止互相阻塞!
2)如伺服器資源不足,共用同一個例項,要保證讀寫特性相同,如都是讀多寫少,防止一臺寫多應用阻塞讀請求。
(評語:舊版本的MongoDB (pre 2.0)擁有一個全域性的寫入鎖,這個問題在2.0版本中的得到了顯著的改善,並且在當前2.2版本中得到了進一步的加強。MongoDB 2.2使用資料庫級別的鎖在這個問題上邁進了
一大步。所以用 MongoDB 2.2的人可以忽略此條目。)
6.需要重點關注的 mongodb 效能指標
關注主要效能指標:
1)Faults:顯示 mongodb 每秒頁面故障的數量,這個是 mongodb 對映到虛擬地址空間,而不是實體記憶體。這個值如果飆高的話,可能意味著機器沒有足夠的記憶體來儲存資料和索引。
2)Flushes:每秒做了多少次 fsync,顯示多少次資料被重新整理進了磁碟。
3)locked:寫鎖。
4)idx miss:索引未命中比例。
5)qr | qw:讀寫鎖的請求佇列長度。
6)conn: 當前已經建立的連線數。
7.嚴重的空間碎片問題
mongodb 如果資料修改很頻繁,會出現比較嚴重的空間碎片問題,表現在磁碟檔案擴張與實際資料量不相符,記憶體不夠用,索引命中率低,查詢效率降低。
碎片整理,目前我們採用的版本沒有太有效的方法。
可以用 db.repaireDatabase() 來整理資料庫,這個過程非常的慢。
如果是 master/slave 模式,則相當於執行一次主從切換,然後從新建立從庫。
如果是 replSet 架構,可以停掉資料庫,然後刪除資料目錄,從新從複製組中全同步資料,這個時候要考慮 oplog 的尺寸。
一個大體的步驟:
1)先呼叫rs.freeze(1200),將每個不想讓它成為 primary 的機器讓它在 1200 秒內無法成為 primary(這步也可以不做);
2)將 primary stepDown,不出意外新的 primary 會起來;
3)將原 primary kill 掉;
4)刪掉所有 data 資料(呼叫 repair 很慢,真不如干掉重新來);
5)再重啟動原 primary 的程式;
6)以此迴圈完成整個複製組的全部重建。
8.連線池 WriterConcern 模式選擇
有些應用配置了 WriterConcern.FSYNC_SAFE 模式;這種配置意味著客戶端在插入資料或更新資料的時候,要求 mongodb 必須將所更新的資料寫入磁碟並返回更新成功的資訊給程式。
如果碰上應用程式訪問壓力大,mongodb 就會反應遲鈍,並可能會假死。
針對此情況,需要評估資料的一致性需求,做出合適調整。
我們一般建議關閉此選項。
(評語:劉奎波的業務中心最佳化時就關閉了這個 WriterConcern.FSYNC_SAFE 模式)
9.開發時注意的細節
1)更新某條資料的時候,先查出來再更新會減小鎖的時間;
2)只有真正需要的欄位才select出來;
3)只有返回很少結果的查詢才用索引,否則會載入太多資料,比沒有用索引還慢!
4)屬性比較多的時候,建立分層的關係能夠提高查詢效率,否則每個記錄都要過一遍才能找到要的屬性。(評語:貌似說的是以 Array 形式儲存的 subdocument)
5)skip+limit 翻頁,越往後面越慢。比較靠譜的做法是,先找出上次的id,翻頁的時候不用 skip:
last_row_id = ObjectId('....');
db.activity_stream->find({_id:{$lt: last_row_id },user_id:20 } ).sort( {_id:-1} ).limit(10);
10.關於硬體資源的選擇
虛擬機器可以很好的隔離資源,並可動態的擴充套件。
我們建議 mongodb 的部署採用虛擬機器的方式,每個虛擬機器部署一個例項,使各節點分散在不同的物理機上,根據應用的前期預測,平衡虛擬機器的之間的i/o。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15498/viewspace-2121237/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 資料的設計命名的十個要點
- MongoDB知識要點MongoDB
- Java程式設計師微服務架構你必須要掌握的十個要點Java程式設計師微服務架構
- 建立一個成功的App前要考慮的5個要點APP
- Oracle效能調整的十大要點.docOracle
- AI測試與傳統測試不同,需要考慮十個要點AI
- 提升Web使用者體驗的71個設計要點Web
- 網頁首圖抓住使用者注意力的8個要點網頁
- 專案進度管理的三個要點
- Golang中defer的三個實戰要點Golang
- 盤點十個超炫的jQuery外掛jQuery
- 使用GitHub的十個最佳實踐Github
- 十個正確使用 Redis 的技巧Redis
- MongoDB的使用MongoDB
- 設計log函式庫的幾個要點函式
- 秒殺系統設計的5個要點
- 保護大資料安全的10個要點大資料
- CRM系統管理客戶的四個要點
- 成為Java高手的26個學習要點Java
- 成為Java高手的25個學習要點Java
- Linux新手要了解的十個知識點Linux
- 十個有爭議的程式設計觀點程式設計
- 成功運作一個開源專案的 15 個要點
- 19個MySQL效能優化要點解析MySql優化
- 可以提高php程式設計效率的20個要點PHP程式設計
- 最佳實踐採購團隊的8個要點
- 成功接專案需要注意的幾個要點
- 使用PHP驅動的MongoDB的單點查詢效能測試PHPMongoDB
- 優秀程式設計師都在注意的十個點程式設計師
- Dockerfile之CMD與ENTRYPOINT使用要點Docker
- 網站使用者體驗要點網站
- 我要點名一款十字線上 PVP 遊戲 - 1951遊戲
- mongoDB知識點MongoDB
- 程式設計師使用Node的十個技巧程式設計師
- 44個路由器知識要點(轉)路由器
- 53個要點提高PHP程式設計效率PHP程式設計
- 檔案管理,你必須要知道的三個要點
- 把“事兒”辦成的4個要點 | 享受工作系列