我試圖建立一個需要非常高的寫入吞吐量和合理的讀取吞吐量的數據庫。我有一套分佈式系統,將「事件」數據添加到數據庫中。MongoDb複合索引優化
目前,事件記錄的ID是Guid。我一直在閱讀的指南不傾向於創建很好的索引,因爲它們的隨機分佈意味着最近的數據將分散在磁盤中,這可能導致分頁問題。
所以這裏是我想要驗證的第一個假設: 我假設我不想選擇創建一個正確平衡樹的_id,例如類似自動編號的東西。這將是有益的,因爲最近的兩個事件基本上在磁盤上彼此相鄰。這是一個正確的假設嗎?
假設(1)是正確的,那麼我試圖找出產生這樣一個id的最佳方法。我知道Mongo本身支持ObjectId,這對於可以將數據綁定到Mongo的應用程序很方便,但我的應用程序不是這樣的。由於有多個系統產生數據,模擬「自動編號」字段有點問題,因爲mongo不支持服務器端的自動編號,所以生產者必須分配id,如果他們不願意不知道其他系統在做什麼。
爲了解決這個問題,我正在考慮做的是使_id字段成爲{localId,producerId}上的複合鍵,其中本地id是生產者可以生成的自動編號,因爲producerId將使其唯一。 ProducerId是我可以在生產者之間進行談判的事情,以便他們能夠提出獨特的ID。
所以這裏是我的下一個問題: 如果我的目標是從所有生產者獲取最新的數據,那麼{localId,producerId}應該是首選的關鍵順序,因爲localId將是正確的,並且producerId將是一個小羣,我寧願2個最近的事件保持本地對方。如果我倒順序,那麼我如何樹最終將看推理會像下面這樣:
root
/ | \
p0 p1 p2
/ | \
e0..n e0..n e0..n
其中p#是製造端ID,以及e#是一個事件。這好像會將我的索引分割成p#數據簇,而新事件不一定會彼此相鄰。我對首選訂單的假設應該(請驗證)看起來像這樣:
root
/ | \
e0 e1 e2
/ | \
p0..n p0..n p0..n
這似乎使最近的事件彼此靠近。 (我知道Mongo使用B樹作爲索引,但我只是試圖在這裏簡化視覺)。
唯一需要注意{LOCALID,producerId}我可以看到的是,由用戶常用的查詢將列出了由生產者,其{producerId,LOCALID}實際上會處理好很多最近的事件。爲了使這個查詢與{localId,producerId}一起工作,我想我還需要將producerId作爲字段添加到文檔中,並對其進行索引。
爲了明確我在這裏的問題的真實性,我想知道我是否正確思考這個問題,或者是否有明顯更好的方法來解決這個問題。
感謝
如果您打算開發一個項目,請考慮Apache Cassandra。對於繁重的寫作來說,它非常驚人 –
該應用程序已經相當成熟,我們已經對Mongo有所承諾。我只需要經歷一個優化階段,因爲我們由於磁盤抖動而不能保持高速運轉。我會看看卡桑德拉,謝謝。 – Mranz
說實話,我目前面臨類似的問題。即使我的應用程序已經非常成熟,我覺得在某些時候,mongo可能不如cassandra所能做的那麼好。雖然mongo 2.2很酷 –