在分布式高并發的情況下,分布式主鍵生成政策可參考mongodb的objectid實作。
ObjectId是一種輕量的,不同的機器不同的程序都能用全局唯一的同種方法生成它,而不是采用傳統的自增的主鍵政策,因為在多台伺服器上同步自動增加主鍵既費力又費時。ObjectId是一個24位的字元串,它是由一組十六進制的字元構成,每個位元組兩位的十六進制數字,總共用了12位元組的存儲空間。MongoDB的這種設計,展現着空間換時間的思想。官網中對ObjectId的規範,如圖所示。

圖官網對ObjectId的規範
1) Time
時間戳。将剛才生成的objectid的前4位進行提取“4e7020cb”,然後按照十六進制轉為十進制,變為“1315971275”,這個數字就是一個時間戳。通過時間戳的轉換,就成了易看清的時間格式,如圖3所示。
2) Machine
機器。接下來的三個位元組就是“7cac81”,這三個位元組是所在主機的唯一辨別符,一般是機器主機名的散列值,這樣就確定了不同主機生成不同的機器hash值,確定在分布式中不造成沖突,這也就是在同一台機器生成的objectId中間的字元串都是一模一樣的原因。
3) PID
程序ID。上面的Machine是為了確定在不同機器産生的objectId不沖突,而pid就是為了在同一台機器不同的mongodb程序産生了objectId不沖突,接下來的“af71”兩位就是産生objectId的程序辨別符。
4) INC
自增計數器。前面的九個位元組是保證了一秒内不同機器不同程序生成objectId不沖突,這後面的三個位元組“36236b”是一個自動增加的計數器,用來確定在同一秒内産生的objectId也不會發現沖突,允許256的3次方等于16777216條記錄的唯一性。
總的來看,objectId的前4個位元組時間戳,記錄了文檔建立的時間;接下來3個位元組代表了所在主機的唯一辨別符,确定了不同主機間産生不同的objectId;後2個位元組的程序id,決定了在同一台機器下,不同mongodb程序産生不同的objectId;最後通過3個位元組的自增計數器,確定同一秒内産生objectId的唯一性。ObjectId的這個主鍵生成政策,很好地解決了在分布式環境下高并發情況主鍵唯一性問題,值得學習借鑒。