分佈式ID生成方案選型!詳細解析雪花算法Snowflake

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"分佈式唯一ID","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"RocketMQ","attrs":{}},{"type":"text","text":"時,需要使用到分佈式唯一","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"ID","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"消息可能會發生重複,所以要在消費端做冪等性,爲了達到業務的冪等性,生產者必須要有一個唯一","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"ID,","attrs":{}},{"type":"text","text":" 需要滿足以下條件:","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"同一業務場景要全局唯一","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"該ID必須是在消息的發送方進行生成發送到MQ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"消費端根據該ID進行判斷是否重複,確保冪等性","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在哪裏產生以及消費端進行判斷做冪等性與該ID無關,此ID需要保證的特性:","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"局部甚至全局唯一","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"趨勢遞增","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"Snowflake算法","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Snowflake是Twitter開源的分佈式ID生成算法, 結果是一個","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Long","attrs":{}},{"type":"text","text":"型的ID,核心思想是:","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"1","attrs":{}},{"type":"text","text":"位作爲符號位,確定爲","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"0,","attrs":{}},{"type":"text","text":" 表示","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"正","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"41","attrs":{}},{"type":"text","text":"位作爲","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"毫秒數","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"10","attrs":{}},{"type":"text","text":"位作爲機器的ID ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":":","attrs":{}},{"type":"text","text":" 高","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"5","attrs":{}},{"type":"text","text":"位是","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"數據中心ID,","attrs":{}},{"type":"text","text":" 低","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"5","attrs":{}},{"type":"text","text":"位是","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"機器ID","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"12","attrs":{}},{"type":"text","text":"位作爲","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"毫秒內的序列號,","attrs":{}},{"type":"text","text":" 意味着每個節點每秒可以產生","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"4096(2^12^)","attrs":{}},{"type":"text","text":" 個ID","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/5c/5ce7e7e0bf0ab2563ffd1fe083b3e2e9.jpeg","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"該算法通過二進制的操作進行實現,單機每秒內理論上最多可以生成","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"1000*(2^12),","attrs":{}},{"type":"text","text":" 即","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"409.6","attrs":{}},{"type":"text","text":"萬個ID","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"SnowflakeIdWorker","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Snowflake算法Java實現SnowflakeIdWorker:","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"/**\n * Twitter_Snowflake
\n * SnowFlake的結構如下(每部分用-分開):
\n * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000
\n * 1位標識,由於long基本類型在Java中是帶符號的,最高位是符號位,正數是0,負數是1,所以id一般是正數,最高位是0
\n * 41位時間截(毫秒級),注意,41位時間截不是存儲當前時間的時間截,而是存儲時間截的差值(當前時間截 - 開始時間截)\n * 得到的值),這裏的的開始時間截,一般是我們的id生成器開始使用的時間,由我們程序來指定的(如下下面程序IdWorker類的startTime屬性)。41位的時間截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69
\n * 10位的數據機器位,可以部署在1024個節點,包括5位datacenterId和5位workerId
\n * 12位序列,毫秒內的計數,12位的計數順序號支持每個節點每毫秒(同一機器,同一時間截)產生4096個ID序號
\n * 加起來剛好64位,爲一個Long型。
\n * SnowFlake的優點是,整體上按照時間自增排序,並且整個分佈式系統內不會產生ID碰撞(由數據中心ID和機器ID作區分),並且效率較高,經測試,SnowFlake每秒能夠產生26萬ID左右。\n */\npublic class SnowflakeIdWorker {\n\n // ==============================Fields===========================================\n /** 開始時間截 (2015-01-01) */\n private final long twepoch = 1420041600000L;\n\n /** 機器id所佔的位數 */\n private final long workerIdBits = 5L;\n\n /** 數據標識id所佔的位數 */\n private final long datacenterIdBits = 5L;\n\n /** 支持的最大機器id,結果是31 (這個移位算法可以很快的計算出幾位二進制數所能表示的最大十進制數) */\n private final long maxWorkerId = -1L ^ (-1L << workerIdBits);\n\n /** 支持的最大數據標識id,結果是31 */\n private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);\n\n /** 序列在id中佔的位數 */\n private final long sequenceBits = 12L;\n\n /** 機器ID向左移12位 */\n private final long workerIdShift = sequenceBits;\n\n /** 數據標識id向左移17位(12+5) */\n private final long datacenterIdShift = sequenceBits + workerIdBits;\n\n /** 時間截向左移22位(5+5+12) */\n private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;\n\n /** 生成序列的掩碼,這裏爲4095 (0b111111111111=0xfff=4095) */\n private final long sequenceMask = -1L ^ (-1L << sequenceBits);\n\n /** 工作機器ID(0~31) */\n private long workerId;\n\n /** 數據中心ID(0~31) */\n private long datacenterId;\n\n /** 毫秒內序列(0~4095) */\n private long sequence = 0L;\n\n /** 上次生成ID的時間截 */\n private long lastTimestamp = -1L;\n\n //==============================Constructors=====================================\n /**\n * 構造函數\n * @param workerId 工作ID (0~31)\n * @param datacenterId 數據中心ID (0~31)\n */\n public SnowflakeIdWorker(long workerId, long datacenterId) {\n if (workerId > maxWorkerId || workerId < 0) {\n throw new IllegalArgumentException(String.format(\"worker Id can't be greater than %d or less than 0\", maxWorkerId));\n }\n if (datacenterId > maxDatacenterId || datacenterId < 0) {\n throw new IllegalArgumentException(String.format(\"datacenter Id can't be greater than %d or less than 0\", maxDatacenterId));\n }\n this.workerId = workerId;\n this.datacenterId = datacenterId;\n }\n\n // ==============================Methods==========================================\n /**\n * 獲得下一個ID (該方法是線程安全的)\n * @return SnowflakeId\n */\n public synchronized long nextId() {\n long timestamp = timeGen();\n\n //如果當前時間小於上一次ID生成的時間戳,說明系統時鐘回退過這個時候應當拋出異常\n if (timestamp < lastTimestamp) {\n throw new RuntimeException(\n String.format(\"Clock moved backwards. Refusing to generate id for %d milliseconds\", lastTimestamp - timestamp));\n }\n\n //如果是同一時間生成的,則進行毫秒內序列\n if (lastTimestamp == timestamp) {\n sequence = (sequence + 1) & sequenceMask;\n //毫秒內序列溢出\n if (sequence == 0) {\n //阻塞到下一個毫秒,獲得新的時間戳\n timestamp = tilNextMillis(lastTimestamp);\n }\n }\n //時間戳改變,毫秒內序列重置\n else {\n sequence = 0L;\n }\n\n //上次生成ID的時間截\n lastTimestamp = timestamp;\n\n //移位並通過或運算拼到一起組成64位的ID\n return ((timestamp - twepoch) << timestampLeftShift) //\n | (datacenterId << datacenterIdShift) //\n | (workerId << workerIdShift) //\n | sequence;\n }\n\n /**\n * 阻塞到下一個毫秒,直到獲得新的時間戳\n * @param lastTimestamp 上次生成ID的時間截\n * @return 當前時間戳\n */\n protected long tilNextMillis(long lastTimestamp) {\n long timestamp = timeGen();\n while (timestamp <= lastTimestamp) {\n timestamp = timeGen();\n }\n return timestamp;\n }\n\n /**\n * 返回以毫秒爲單位的當前時間\n * @return 當前時間(毫秒)\n */\n protected long timeGen() {\n return System.currentTimeMillis();\n }\n\n //==============================Test=============================================\n /** 測試 */\n public static void main(String[] args) {\n SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0, 0);\n for (int i = 0; i < 1000; i++) {\n long id = idWorker.nextId();\n System.out.println(Long.toBinaryString(id));\n System.out.println(id);\n }\n }\n}\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"優點:","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"生成速度快","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"實現簡單,沒有多餘的依賴","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以根據實際情況調整各個位段,方便靈活","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"缺點:","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"只能趨勢遞增","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"依賴機器時間. 如果發生回撥可能會造成生成的ID重複","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"SnowFlake算法時間回撥問題:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"時間回撥產生原因:","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由於業務需要,機器需要同步時間服務器","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"時間回撥問題解決辦法:","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當回撥時間小於15ms,可以等待時間追上來以後再繼續生成","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當回撥時間大於15ms時可以通過更換workId來產生之前都沒有產生過的Id來解決回撥問題","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"步驟:","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先將workId的位數進行調整至15位","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":"none"},"content":[{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/04/041fb1b4b60329a672907fe69b5d69e2.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":false,"pastePass":false}}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"然後將","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"SnowflakeIdWorker","attrs":{}},{"type":"text","text":"實現調整位段","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"1","attrs":{}},{"type":"text","text":"位作爲","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"符號位,","attrs":{}},{"type":"text","text":" 即生成的分佈式I唯一d爲正數","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"38","attrs":{}},{"type":"text","text":"位作爲","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"時間戳,","attrs":{}},{"type":"text","text":" 表示當前時間相對於初始時間的增量值,單位爲毫秒","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"15","attrs":{}},{"type":"text","text":"位作爲","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"機器ID,","attrs":{}},{"type":"text","text":" 最多可支持3.28萬個節點","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"10","attrs":{}},{"type":"text","text":"位作爲","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"毫秒內的序列號,","attrs":{}},{"type":"text","text":" 理論上可以生成2^10^個序列號","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因爲服務的無狀態關係,正常情況下","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"workId","attrs":{}},{"type":"text","text":"不會配置在具體配置文件中,這裏可以選擇集中式的","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Redis","attrs":{}},{"type":"text","text":"作爲中央存儲:","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"將workId調整位數後得到的多餘的3萬多個workId放置到一個基於Redis的隊列中,用來集中管理workId","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"每次當節點啓動的時候,先查看本地是否有workId,如果有那麼就作爲workId.如果沒有,就在隊列中取出一個當workId來使用,並從隊列中刪除","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"當發現時間回撥太多的時候,就再去隊列中去一個來當新的workId使用,將剛剛那個使用回撥的情況的workId存到隊列裏. 因爲隊列每次都是從頭取出,從尾部插入,這樣可以避免剛剛A機器使用的workId又被B機器獲取的可能性","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果使用redis又會遇到新的小問題: redis一致性如何保證?redis掛了怎麼辦?怎麼同步?","attrs":{}}]}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"從基礎組件的使用角度來說,對於","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"SnowflakeIdWorker","attrs":{}},{"type":"text","text":"算法當遇到時間回撥問題,只需要拋出異常即可,這樣可以保證算法實現的簡單性","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"也可以參考","attrs":{}},{"type":"link","attrs":{"href":"https://github.com/baidu/uid-generator","title":"","type":null},"content":[{"type":"text","text":"uid-generator","attrs":{}}]},{"type":"text","text":" 方法: 每次取一批","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"workId,","attrs":{}},{"type":"text","text":" 集中之後批取,這樣可以解決各個節點訪問集中機器的性能問題.","attrs":{}}]}]}],"attrs":{}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章