在分布式系統中,有一些場景需要使用全域性唯一 id ,可以和業務場景有關,比如支付流水號,也可以和業務場景無關,比如分庫分表後需要有乙個全域性唯一 id,或者用作事務版本號、分布式鏈路追蹤等等,好的全域性唯一 id 需要具備這些特點:
那麼分布式場景下有哪些生成唯一 id 的方案呢?
先說最容易理解的方案,利用資料庫的自增長序列生成:資料庫生成唯一主鍵,並通過服務提供給其他系統;如果是小型系統,資料總量和併發量都不是很大的情況下,這種方案足夠支撐。
如果每次生成乙個 id 可能會對資料庫有壓力,可以考慮一次性生成 n 個 id 放入快取中,如果快取中的 id 被取光,再通過資料庫生成下一批 id 。
利用 redis / mongodb / zookeeper 生成:redis 利用 incr 和 increby ;mongodb 的 objectid;zk 通過 znode 資料版本;都可以生成全域性的唯一標識碼。
我們用 mongodb 的 objectid 來舉例:
mongodb 的 objectid 共佔 12 個位元組,其中:
不管是老版本還是新版本,mongodb 的 objectid 至少都可以保證集群內的唯一,我們可以搭建乙個全域性唯一 id 生成的服務,利用 mongodb 生成 objectid 並對外提供服務(mongodb 的各語言驅動都實現了 objectid 的生成演算法)。
這個是分布式架構中,生成唯一標識碼最常用的演算法。為了保證 uuid 的唯一性,生成因素包括了mac位址、時間戳、名字空間(namespace)、隨機或偽隨機數、時序等元素;uuid 有多個版本,每個版本的演算法不同,應用範圍也不同:
如果希望 id 可以本地生成,但是又不要和 uuid 那樣無序,可以考慮使用 snowflake 演算法(twitter開源)。
snowflake 演算法生成 id 是乙個 64 bit 的整數,包括:
在j**a中,snowflake 演算法生成的 id 正好可以用 long 來進行儲存。
image
面試官不講武德,問我如何實現分布式快取?
剛才有個朋友問我,小樓老師,發生腎麼事了,我說怎麼回事,給我發了幾張截圖,我一看!嗷!原來是昨天,他面試又掛了。我啪的一下就把面試題要過來了,很快啊。我這一看,不得了,我說你一直用框架練死勁,底層原理不紮實,遇到面試不好用。他不服氣,非要讓我試試,我說可以,把面試題發在下面 1 介紹下為什麼要使用快...
單機快取 面試官不講武德,問我如何實現分布式快取?
剛才有個朋友問我,小樓老師,發生腎麼事了,我說怎麼回事,給我發了幾張截圖,我一看!嗷!原來是昨天,他面試又掛了。我啪的一下就把面試題要過來了,很快啊。我這一看,不得了,我說你一直用框架練死勁,底層原理不紮實,遇到面試不好用。他不服氣,非要讓我試試,我說可以,把面試題發在下面 1 介紹下為什麼要使用快...
redis分布式鎖,面試官請隨便問,我都會
實現要點 互斥性,同一時刻,智慧型有乙個客戶端持有鎖。防止死鎖發生,如果持有鎖的客戶端崩潰沒有主動釋放鎖,也要保證鎖可以正常釋放及其他客戶端可以正常加鎖。加鎖和釋放鎖必須是同乙個客戶端。容錯性,只有redis還有節點存活,就可以進行正常的加鎖解鎖操作。正確的redis分布式鎖實現 錯誤加鎖方式 錯誤...