MongoDB文件全域性唯一ID的設計思路
MongoDB中資料的基本單元稱為文件(Document)。文件是MongoDB的核心概念,多個鍵極其關聯的值有序的放置在一起便是文件。
Advertisement在一個特定集合內部,需要唯一的標識文件。因此MongoDB中儲存的文件都由一個”_id”鍵,用於完成此功能。這個鍵的值可以是任意型別的,預設試ObjectId物件。ObjectId物件的生成思路是本文的主題,也是很多分散式系統可以借鑑的思路。
為了考慮分散式,“_id”要求不同的機器都能用全域性唯一的同種方法方便的生成它。因此不能使用自增主鍵(需要多臺伺服器進行同步,既費時又費力),因此選用了生成ObjectId物件的方法。
ObjectId使用12位元組的儲存空間,其生成方式如下:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
時間戳 | 機器ID | PID | 計數器 |
前四個位元組時間戳是從標準紀元開始的時間戳,單位為秒,有如下特性:
- 時間戳與後邊5個位元組一塊,保證秒級別的唯一性;
- 保證插入順序大致按時間排序;
- 隱含了文件建立時間;
機器ID是伺服器主機標識,通常是機器主機名的雜湊值。
同一臺機器上可以執行多個mongod例項,因此也需要加入程序識別符號PID。
前9個位元組保證了同一秒鐘不同機器不同程序產生的ObjectId的唯一性。後三個位元組是一個自動增加的計數器(一個mongod程序需要一個全域性 的計數器),保證同一秒的ObjectId是唯一的。同一秒鐘最多允許每個程序擁有(256^3 = 16777216)個不同的ObjectId。
總結一下:時間戳保證秒級唯一,機器ID保證設計時考慮分散式,避免時鐘同步,PID保證同一臺伺服器執行多個mongod例項時的唯一性,最後的計數器保證同一秒內的唯一性(選用幾個位元組既要考慮儲存的經濟性,也要考慮併發效能的上限)。
“_id”既可以在伺服器端生成也可以在客戶端生成,在客戶端生成可以降低伺服器端的壓力。
原文出處:http://www.cnblogs.com/liuhao/archive/2011/12/01/2270649.html