雪花算法分布式Id以及其產生的前端精度損失解決方法


一. 分布式 id

特點:

1. 全局唯一性:全局沒有重復的id標識。
2. 遞增性:保證生成的 id 在業務中是遞增的。
3. 高可用:確保在任何時候都能生成正確可用的id。
4. 高並發:在高並發環境下表現良好。

分布式id常見解決方案

1. UUID
java 中自帶的算法,其能生成一串占 36 bit 的字符串,可以保證唯一性但無法實現有序遞增,且業務可讀性差。
2. 雪花算法
具體介紹寫在下面。
3. Leaf
由美團開源的分布式id生成算法,能保證唯一性,遞增性,但需要依賴關系數據庫、Zookeeper 等中間件。可以參考:Leaf算法

二. 雪花算法

雪花算法是 Twitter 開發的一種分布式 id 生成算法,即 SnowFlake 算法,取意於自然界不存在兩片完全一樣的雪花,雪花算法生成的 id 也如雪花一樣是獨一無二的。

組成

雪花算法生成的 id 是一個 64 bit(位)的 long 型的數字(二進制的),下面給出結構圖:
image

該生成的 id 主要由 4 部分構成:
1. 首位無效占位符:占用 1 bit ,其值始終為 0,沒有意義。
2. 時間戳:占用 41 bit ,用來記錄時間戳,為毫米級,即 2 的 41 次方大概為 69 年。
3. 機器編碼:占用 10 bit ,其中高位 5 bit 是數據中心 ID,低位 5 bit 是工作節點 ID,最多可以容納 1024 個節點。
4. 序列號:占用 12 bit ,用來記錄同毫秒內產生的不同 id 。每個節點每毫秒從 0 開始不斷累加,最多可以累加到 4095 ,一共可以產生 4096 個 id 。
SnowFlake算法在同一毫秒內最多可以生成 1024 X 4096 = 4194304 個全局唯一id。

三. 雪花算法導致前端精度丟失解決方法

原因:

前端 js 的 number 類型有最大值,即 2 的 53 次方,為9007199254740992,這是一個 16 位的十進制整數即前端精度為 16 位,后端采用雪花算法得到的 id 是 long 型(64 bit)的即精度為 19 位。這時候,前后端傳值就會出現精度丟失。

解決方法:

1.把數據庫 id 改為 String 類型,相當的麻煩,且性能會下降,此種方法不能使用。
2.采用注解方法,將@JsonSerialize(using = ToStringSerializer.class)加到需要的 id 字段上。例子如下:

public class ArticleVo {
    //防止后端Long類型轉為前端JSON數據精度丟失
    @JsonSerialize(using = ToStringSerializer.class)
    private Long id;

    private String title;

    private String summary;
}

3.可以采用這個博主的全局配置類方法:點擊這里查看


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM