天天看點

阿裡雲DRDS 的sequence序列深入了解1 Sequence簡介2 sequence的原理了解3、END

1 Sequence簡介

DRDS sequence全稱:全局唯一數字序列,顧名思義,其作用是生成全局唯一和有序遞增的數字序列。常用于主鍵列、唯一索引列等值的生成。

Sequence分類,總共分為兩大類:

顯式sequence:通過sequence文法進行建立與維護,可以單獨使用。

隐式sequence:DRDS表主鍵定義 AUTO_INCREMENT後,用于自動填充主鍵,由 DRDS 自動維護

每類sequence針對不同的使用場景還分為四種類型,分别為Group Sequence,Group Sequence(單元化),Time-based Sequence,Simple Sequence。

詳情參考阿裡雲官網

本文重點介紹group隐式sequence。為什麼?

1、sequence原理性的東西,在官網上基本沒有展現,我們隻知其然而不知其是以然

2、當然是因為做DRDS資料遷移踩的關于隐式sequence的坑太多了,經常跟阿裡研發取經,加上環境測試了解到一些東西。

2 sequence的原理了解

1、sequence值是如何配置設定的?

阿裡雲DRDS 的sequence序列深入了解1 Sequence簡介2 sequence的原理了解3、END

如圖所示:DRDS在配置設定sequence的時候,會根據自身的節點數來劃分多個sequence段,預設每個段的長度為10萬。注意這裡是根據DRDS的規格節點數來劃分的sequence端,而不是根據RDS的數量,與RDS無關。

通過show sequences;指令,可以檢視目前sequence的value。

阿裡雲DRDS 的sequence序列深入了解1 Sequence簡介2 sequence的原理了解3、END

這裡的value值通常是表示已經配置設定的最大sequence段的起始值,即200000

2、sequence的起始值

有沒有發現上圖中,sequence段的起始值我是從100001開始取值的。預設情況下,sequence的起始值并不是按照1來開始遞增的,而是按照100001開始的。這就涉及到内部的一些算法:

(value - value % (innerStep unit_count)) + innerStep unit_count + nodeIndex * innerStep

實驗證明如下:

建立一張表,并且插入一條測試資料:

阿裡雲DRDS 的sequence序列深入了解1 Sequence簡介2 sequence的原理了解3、END
阿裡雲DRDS 的sequence序列深入了解1 Sequence簡介2 sequence的原理了解3、END

可以看到主鍵的id是從100001開始取值的。

3、sequence的緩存

這裡在節點上配置設定的sequence段,我們可以稱之為sequence的緩存,正常情況下,節點上的緩存用完才會重新配置設定sequence段。

阿裡雲DRDS 的sequence序列深入了解1 Sequence簡介2 sequence的原理了解3、END

緩存實驗測試如下:

阿裡雲DRDS 的sequence序列深入了解1 Sequence簡介2 sequence的原理了解3、END
阿裡雲DRDS 的sequence序列深入了解1 Sequence簡介2 sequence的原理了解3、END
阿裡雲DRDS 的sequence序列深入了解1 Sequence簡介2 sequence的原理了解3、END

truncate表清理了資料之後,重新插入資料還是會用到之前的緩存,從100002開始。

由于這種緩存的存在,尤其是DRDS在資料遷移的某些場景時,會産生很大的影響。

某客戶案例:

DRDS進行平台的資料遷移,由于沒有直接遷移DRDS to DRDS的工具,經過多次測試與衡量決定采用底層RDS to RDS方式的資料遷移。在第二次進行應用測試大批量報錯主鍵沖突。原因就是第一次測試完,truncate清理資料後,緩存還是存在的。第二次導入資料後則還是會用緩存的值,這時候測試插入資料就會出現主鍵沖突。

這裡出現sequence沖突的根本原因是,sequence本來是DRDS層面維護的,但是采用非标的方式遷移底層的RDS資料,雖然資料沒有問題,但sequence就沒有人來維護了。這樣就很容易出現很多問題。是以不到迫不得已盡量不要走非标方案。

解決方法:清理sequence緩存。

常用的清理緩存的方法:

1、alter sequence start with AUTO__XXXX;使用指令擡高sequence,指令是表級别的。

2、重新開機drds,目的是重新開機節點。

3、表删除重建立表

4、緩存的值是如何計算出來

我們已經知道,初始化的時候,sequence的值會按照算法定義起始值。那alter sequence start with AUTO__XXXX指令是如何更新sequence的value 以及 緩存的呢?

同理,alter sequence調整後,也會重新初始化sequence,先用算法更新起始值

(value - value % (innerStep unit_count)) + innerStep unit_count + unit_index * innerStep

然後再用下面的公式計算緩存區間:所有節點先後用公式計算

value + (inner_step * unit_count)

簡單的說:一般而言,執行指令alter後,首先會根據算法,将調整的sequence“合法化”,就是取整數,然後加一段區間更新到緩存,是以緩存會更新到一個更大的值。是以你會發現,在執行alter指令後,之後的主鍵值并不是按照修改的值遞增的,主鍵值肯定比調整的value要大。

測試驗證如下:

阿裡雲DRDS 的sequence序列深入了解1 Sequence簡介2 sequence的原理了解3、END

上圖可以看到,show sequence顯示的值為200000,與緩存中已配置設定的sequence段的最大值比對。

阿裡雲DRDS 的sequence序列深入了解1 Sequence簡介2 sequence的原理了解3、END

上圖中,随意調大了sequence的value,show sequence顯示為了432432,(這個隻是暫時顯示,後面還是會更新為最大sequence段的起始值)

阿裡雲DRDS 的sequence序列深入了解1 Sequence簡介2 sequence的原理了解3、END

上圖中,又插入了一條資料,發現show sequence的值已經改了。用指令查詢一下緩存,果然緩存已經更新了,并且是比alter設定的value值要大。

這裡還會發現,圖中第一次show sequence時,不是代表最大的sequence段的起始值。這是因為sequence值用到的時候才會更新這個value。

那為什麼執行檢視緩存的指令inspect後就恢複了呢?

猜測這個指令會強制重新整理value與緩存保持一緻。

那麼此時再插入資料主鍵會是從432432開始嗎?

阿裡雲DRDS 的sequence序列深入了解1 Sequence簡介2 sequence的原理了解3、END

當然不是了,如果你還覺得是,那就是之前我啰嗦的不夠透徹。

這裡就是按照緩存中的值來取sequence了。

3、END

繼續閱讀