分區索引是為瞭解決大寬表的儲存和高並發訪問問題而設計的一種新特性。建立搜尋索引時可以指定資料分區策略,服務端自動將資料進行拆分並儲存,查詢資料時系統自動進行分區裁剪。本文介紹資料分區的策略和使用方法。
前提條件
已開通Lindorm執行個體的搜尋索引服務,具體操作請參見開通搜尋索引。
已通過Lindorm-cli串連Lindorm寬表引擎,具體操作請參見通過Lindorm-cli串連並使用寬表引擎。
使用情境
業務資料具有時間屬性,例如車連網資料、訂單詳情、訊息日誌等。
業務資料有明顯的聚類特性,例如商家資料表以商家ID為聚類,查詢條件中包括商家ID。IoT裝置資料表以裝置ID為聚類,查詢條件中包括裝置ID。
資料分區策略
準備工作
使用分區索引前需要建立測試表,語句如下:
CREATE TABLE IF NOT EXISTS search_table (user_id bigint, storeId varchar, goodsId varchar, goodsPrice smallint, orderTime bigint, info varchar, constraint primary key (user_id asc));
HASH分區
HASH分區將資料進行散列儲存,從而避免出現資料的熱點問題。在資料寫入量較大的情境中可以很好地實現資料均衡。搜尋索引預設按照Lindorm寬表的主鍵進行HASH分區,同時也支援自訂分區鍵。
HASH分區的文法樣本如下:
建立搜尋索引,預設按照Lindorm寬表的主鍵進行HASH分區,預設設定的分區數量為搜尋節點數乘以2。
CREATE INDEX IF NOT EXISTS idx USING SEARCH ON search_table (storeId, goodsId, goodsPrice);
建立搜尋索引,按照Lindorm寬表的storeId列進行HASH分區(即一級HASH分區),分區數量為64。
CREATE INDEX IF NOT EXISTS idx USING SEARCH ON search_table (storeId, goodsId, goodsPrice) partition by hash(storeId) partitions 64;
重要業務查詢時,如果多數情況下會攜帶某個列作為過濾條件,可將該列設定為自訂分區鍵。
對於適用自訂分區鍵的情境,可根據實際業務情況將分區數量partitions設定大一些。如果不確定具體數值,可先設定64作為初始測試值。
對Lindorm寬表的某一列進行HASH分區(即一級HASH分區)時,如果自訂的分區鍵(也就是Lindorm寬表的某一列)存在熱點問題,如一個storeId列下最多可能匹配到10%以上的資料,那麼可能導致大量資料寫入同一個分區中,影響查詢和寫入效能。建議使用多級HASH分區(進階用法),對Lindorm寬表的多個列組合進行HASH分區(即二級HASH分區或者三級HASH分區)。
- 自訂分區鍵的值有以下限制:
- 分區索引值不可更改。
- 分區索引值不可為空。
時間範圍分區
對於一些時間序列的資料,可以按照時間範圍分區,例如按照周或者月進行分區,同一時間範圍內的資料將會聚集儲存,並且可以自動淘汰舊分區的資料。
按照時間範圍分區的文法樣本如下:
建立索引,按照業務的時間列orderTime分區,從30天前開始,每7天自動分區,預設保留90天的分區資料。
CREATE INDEX idx USING SEARCH ON search_table (storeId, goodsId, goodsPrice, orderTime) partition by range time(orderTime) partitions 4 with (indexState=ACTIVE, RANGE_TIME_PARTITION_START='30', RANGE_TIME_PARTITION_INTERVAL='7', RANGE_TIME_PARTITION_TTL='90');
建立索引,按照業務的時間列orderTime分區,從半年前開始,每1個月自動分區,預設保留半年的分區資料,分區欄位單位設定為秒。
CREATE INDEX idx USING SEARCH ON search_table (storeId, goodsId, goodsPrice, orderTime) partition by range time(orderTime) partitions 4 with (indexState=ACTIVE, RANGE_TIME_PARTITION_START='180', RANGE_TIME_PARTITION_INTERVAL='30', RANGE_TIME_PARTITION_TTL='180', RANGE_TIME_PARTITION_FIELD_TIMEUNIT='s');
按照時間範圍分區的參數說明如下表:
參數 | 是否必選 | 說明 |
RANGE_TIME_PARTITION_START | 是 | 表示建立索引操作前多少天開始建立分區。適用於有歷史資料的情境,如果歷史資料的時間戳記比開始分區的時間還要小,則會報錯。 |
RANGE_TIME_PARTITION_INTERVAL | 是 | 表示間隔多少天建立新分區,例如 |
RANGE_TIME_PARTITION_TTL | 否 | 表示保留多少天的分區資料,例如 |
RANGE_TIME_PARTITION_FIELD_TIMEUNIT | 否 | 表示業務指定的時間分區欄位單位,預設單位為毫秒(ms)。
|
多級HASH分區(進階用法)
按照Lindorm寬表的storeId列和goodsId列組合進行二級HASH分區,加鹽因子(salt_factor)為4,分區數量為64。
//相同storeId,不同goodsId的資料會被打散到4個分區中去
CREATE SEARCH INDEX idx ON search_table (storeId, goodsId, goodsPrice) partition by hash(storeId(salt_factor=4),goodsId) partitions 64;
- 加鹽因子(
salt_factor
)是進一步散列相同storeId列值的資料,通常設定為一個較小的數值,並且數值與分區數量是兩倍的數量關係。如果分區數量為16,當salt_factor大於4時,則無法散列資料。加鹽因子的其他值表示如下:salt_factor=1
:表示相同storeId列的資料,不同goodsId列的資料會被散列到分區總數量的一半中。salt_factor=2
:表示相同storeId列的資料,不同goodsId列的資料會被散列到分區總數量的1/4中。salt_factor=3
:表示相同storeId列的資料,不同goodsId列的資料會被散列到分區總數量的1/8中。
- 多級HASH分區(二級HASH分區或者三級HASH分區)除了可以散列資料,在查詢資料情境中也大大提高了查詢效率。例如在上述二級HASH分區中,查詢資料時同時輸入storeId列和goodsId列的過濾資訊會確定在一個分區中進行資料檢索,減少資料的掃描範圍從而提高查詢效率。
- 使用二級HASH分區時,一級分區鍵(Lindorm搜尋表的第一列即storeId列)必須設定加鹽因子。使用三級HASH分區時,一級分區鍵和二級分區鍵都必須設定加鹽因子。
- 自訂分區鍵的值有以下限制:
- 分區索引值不可更改。
- 分區索引值不可為空。