18、分佈式全局id實踐(1/4)

1、利用mongodb的id
MongoDB的ObjectId和snowflake算法類似。它設計成輕量型的,不同的機器都能用全局唯一的同種方法方便地生成它。MongoDB 從一開始就設計用來作爲分佈式數據庫,處理多個節點是一個核心要求。使其在分片環境中要容易生成得多。

前4 個字節是從標準紀元開始的時間戳,單位爲秒。時間戳,與隨後的5 個字節組合起來,提供了秒級別的唯一性。由於時間戳在前,這意味着ObjectId 大致會按照插入的順序排列。這對於某些方面很有用,如將其作爲索引提高效率。這4 個字節也隱含了文檔創建的時間。絕大多數客戶端類庫都會公開一個方法從ObjectId 獲取這個信息。
接下來的3 字節是所在主機的唯一標識符。通常是機器主機名的散列值。這樣就可以確保不同主機生成不同的ObjectId,不產生衝突。
爲了確保在同一臺機器上併發的多個進程產生的ObjectId 是唯一的,接下來的兩字節來自產生ObjectId 的進程標識符(PID)。
前9 字節保證了同一秒鐘不同機器不同進程產生的ObjectId 是唯一的。後3 字節就是一個自動增加的計數器,確保相同進程同一秒產生的ObjectId 也是不一樣的。同一秒鐘最多允許每個進程擁有2563(16 777 216)個不同的ObjectId。

  //自增長id
    private static int getSequence2(Long time) {

        // 連接到MongoDB
        Mongo mongo = new Mongo("localhost", 27017);
        // 打開數據庫 testDB
        DB db = mongo.getDB("test_1");
        DBCollection table = db.getCollection("sequence");

        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        DBObject query = new BasicDBObject();
        query.put("coll_name", "0");
        DBObject newDocument =new BasicDBObject();
        newDocument.put("$inc", new BasicDBObject().append("cnt", 1));
        DBObject ret = table.findAndModify(query, newDocument);
        if (ret == null){
            return 0;
        }else{
            return (Integer)ret.get("cnt") + 1;
        }


    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章