簡單的ID生成器設計

2021-10-09 05:06:55 字數 2310 閱讀 7316

在工作中,我們經常需要用到id生成器。比如當當前系統與別的系統有一些資料需要同步時,為了實現冪等性,往往會為每一次同步請求設定乙個全域性統一的id。可見id生成器在許多專案中都有至關重要的多用。

id生成器有許多的實現方式。

1. 比如用著名的uuid,這種方法可以簡單的獲取到全域性唯一的id。但是因為獲得的id是字串,在一些需要純資料的場合,處理起來效率沒有這麼高。

2.使用資料庫的自增id,但是需要資料落庫之後才能拿到。

本篇文章分享一種簡單的id生成器,可以支援多台例項使用。另外也支援自定定義每日或者每月重置。

為了提高id生成器的訪問速度,可以將當前的id值存在記憶體中。而為了防止多個例項出現相同的id,我們需要分配不同的id段到不同的例項上,這樣保證每個例項用的id數字段都是不同的,也就不會出現重複的情況。同時將最新分配的資料段記錄到資料庫中,實現持久化。並且使用唯一鍵和樂觀鎖防止併發。分配id段的步長可以自定義,如果設定為1,則每次分配的id段都是1,能保證生成的id是連續的,但是也導致每次生成id都要去更新資料庫。

總結上面的設計思路後,假設當前業務編號(type)為1,id生成器的分配id段的步長為100,每日自動重置為0,當前日期為20200815,可以得到:

1. 呼叫id生成器生成函式時,首先到記憶體中尋找有沒有已經分配的id段,如果沒有,則到資料庫中搜尋是否有type=1 and time=20200815的記錄,如果沒有,建立一條記錄(idvalue=100, type = 1,time=20200815),並且把0-100的資料段存到記憶體中使用。如果存在則更新idvalue=idvalue+步長。(使用樂觀鎖防止併發)

2.如果記憶體中存在已經分配的id,則取id,並且更新記憶體中id的最新值。如果id值超出了分配的id段。則到資料庫中搜出type=1 and time=20200815 的idvalue,並且把(idvalue - idvalue+步長)放入記憶體中,並且更新資料庫idvalue=idvalue+步長。

3.如果需要月結,年節等,只需要控制time欄位就能實現。

其中部分邏輯等待讀者自己去實現。(臨時寫的,如果發現問題可以交流)

class id_creator(objects):

id_value_dict = {}

step = 100 # step可以寫成乙個外部的字典,這樣可以簡單的更新步長

def create_id(time, idtype):

key = _create_key(time, idtype) # 生成key的邏輯自己實現即可

segment = id_value_dict.get(key)

# 這裡segment是乙個類

if segment is none or segment.value > sement.max_v:

segment = self._create_new_segment(time, idtype)

id_value = segment.value

segment.value = segment.value + 1

return id_value

def _create_new_segment(time, type):

#從資料庫中獲取記錄,自行實現

database_record = get_data_from_sql(time, idtype)

# 這裡使用樂觀鎖,一直迴圈到更新或者建立成功

while true:

# 如果沒有資料庫記錄,則直接建立記錄

if database_recode is none:

try:

_create_database_record(time, idtype, step)

max_value = step

except:

continue

# 如果有,更新記錄

else:

max_value = database_recode.id_value + step

try:

_update_database_record(time, idtype, max_value)

except:

continue

if max_value > 0:

break

# 建立新的segment

segment = segment(value=max_value - step + 1, max_v=max_value)

key = _create_key(time, idtype)

id_value_dict[key] = segment

return segment

id生成器演算法設計

摘要 原理說明 1.每個資料庫儲存初始值 2.業務獲取值後修改資料庫的初始值 現初始值 源初始值 資料庫個數 步長 原子操作 3.業務拿到初始值後,獲取的資料集合是 開始值 開始值 步長 設定步長 in 原理說明 1.每個資料庫儲存初始值 2.業務獲取值後修改資料庫的初始值 現初始值 源初始值 資料...

ID 生成器 雪花演算法

我們的業務需求中通常有需要一些唯一的id,來記錄我們某個資料的標識 看圖理解 詳細的看 注釋 public class snowflakeidworker if datacenterid maxdatacenterid datacenterid 0 this.workerid workerid th...

分布式ID生成器

一 需求緣起 幾乎所有的業務系統,都有生成乙個唯一記錄標識的需求,例如 這個記錄標識往往就是資料庫中的主鍵,資料庫上會建立聚集索引 cluster index 即在物理儲存上以這個字段排序。這個記錄標識上的查詢,往往又有分頁或者排序的業務需求,例如 所以往往要有乙個time欄位,並且在time欄位上...