W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
大家好,我是V 哥,在TiDB中使用自增主鍵時(shí),確實(shí)存在一些限制和潛在的熱點(diǎn)問題,今天的文章來聊一聊 TiDB中的自增主鍵要怎么做。
以下是一些使用限制和如何避免它們的方法:
@@tidb_allow_remove_auto_inc
來控制是否允許刪除自增屬性。AUTO_RANDOM
:TiDB提供了AUTO_RANDOM
屬性,可以在建表時(shí)替代AUTO_INCREMENT
使用,這樣TiDB會(huì)生成隨機(jī)分布的ID,從而避免寫入熱點(diǎn)問題 。SHARD_ROW_ID_BITS
:對于非聚簇索引主鍵或沒有主鍵的表,TiDB會(huì)使用一個(gè)隱式的自增RowID。通過設(shè)置SHARD_ROW_ID_BITS
,可以把RowID打散寫入多個(gè)不同的Region,緩解寫入熱點(diǎn)問題 。
在TiDB中,AUTO_RANDOM
是用于解決自增主鍵熱點(diǎn)問題的一種方法。以下是一個(gè)具體的業(yè)務(wù)場景案例和操作步驟:
業(yè)務(wù)場景:
假設(shè)你有一個(gè)高并發(fā)的在線服務(wù),需要為每個(gè)服務(wù)實(shí)例生成一個(gè)唯一的標(biāo)識符。如果使用傳統(tǒng)的AUTO_INCREMENT
自增主鍵,大量的寫入操作可能會(huì)導(dǎo)致寫入熱點(diǎn),因?yàn)樗械膶懭攵紩?huì)嘗試在最后一個(gè)Region上進(jìn)行,從而影響性能。
解決方案:
AUTO_RANDOM
:
在創(chuàng)建表時(shí),將主鍵列設(shè)置為AUTO_RANDOM
。例如,你可以執(zhí)行以下SQL語句來創(chuàng)建一個(gè)新表: CREATE TABLE service_instances (
id BIGINT PRIMARY KEY AUTO_RANDOM,
instance_name VARCHAR(255),
created_at TIMESTAMP
);
這樣,每當(dāng)插入新行而沒有指定id
值時(shí),TiDB會(huì)自動(dòng)生成一個(gè)隨機(jī)的id
值。
id
值,TiDB會(huì)自動(dòng)為每個(gè)實(shí)例生成一個(gè)唯一的id
: INSERT INTO service_instances (instance_name, created_at) VALUES ('ServiceInstanceName', NOW());
這將利用AUTO_RANDOM
屬性生成一個(gè)隨機(jī)的id
,從而避免寫入熱點(diǎn)。
id
,可以使用LAST_INSERT_ID()
函數(shù): SELECT LAST_INSERT_ID();
這將返回最近一次由TiDB隱式分配的AUTO_RANDOM
值。
咱們可以使用TiDB的監(jiān)控工具,如Grafana,監(jiān)控AUTO_RANDOM
字段的性能。注意觀察是否有任何寫入熱點(diǎn)的跡象,如某個(gè)TiKV節(jié)點(diǎn)的負(fù)載明顯高于其他節(jié)點(diǎn)。根據(jù)監(jiān)控結(jié)果調(diào)整策略。
需要注意的是:
AUTO_RANDOM
字段插入值,除非打開了@@allow_auto_random_explicit_insert
系統(tǒng)變量,并且你知道你在做什么。錯(cuò)誤的顯式賦值可能會(huì)導(dǎo)致值耗盡。AUTO_RANDOM
只能用于BIGINT
類型的主鍵列,并且不支持與AUTO_INCREMENT
同時(shí)使用。業(yè)務(wù)場景案例:
假設(shè)你運(yùn)營一個(gè)電商平臺,需要處理大量的訂單數(shù)據(jù)。每個(gè)訂單都需要一個(gè)唯一的訂單號,而且訂單數(shù)據(jù)寫入數(shù)據(jù)庫時(shí)必須均勻分布,以避免寫入熱點(diǎn)。如果使用自增主鍵,大量的寫入操作可能會(huì)集中在單個(gè)TiKV節(jié)點(diǎn)上,導(dǎo)致寫入熱點(diǎn)問題。
解決方案:
創(chuàng)建訂單表時(shí),不使用自增主鍵,而是使用SHARD_ROW_ID_BITS
來打散行ID,從而避免寫入熱點(diǎn)。
CREATE TABLE orders (
order_id INT PRIMARY KEY NONCLUSTERED,
product_id INT,
quantity INT,
created_at TIMESTAMP,
INDEX product_idx (product_id)
) SHARD_ROW_ID_BITS = 4 PRE_SPLIT_REGIONS=3;
這里SHARD_ROW_ID_BITS = 4
表示行ID會(huì)被打散到16個(gè)分片中,PRE_SPLIT_REGIONS=3
表示在表創(chuàng)建后會(huì)預(yù)先切分為8個(gè)Region。
order_id
,TiDB會(huì)自動(dòng)為每個(gè)訂單分配一個(gè)唯一的行ID。 INSERT INTO orders (product_id, quantity, created_at)
VALUES (101, 2, NOW());
同樣,我們使用Grafana,監(jiān)控orders
表的性能。注意觀察是否有任何寫入熱點(diǎn)的跡象,如某個(gè)TiKV節(jié)點(diǎn)的負(fù)載明顯高于其他節(jié)點(diǎn)。根據(jù)監(jiān)控結(jié)果調(diào)整SHARD_ROW_ID_BITS
的值。
需要注意的是:
SHARD_ROW_ID_BITS
值,以盡量解決熱點(diǎn)Region無法打散的問題。
問題來了,如何根據(jù)業(yè)務(wù)增長調(diào)整 'SHARD_ROW_ID_BITS' 的值以優(yōu)化數(shù)據(jù)庫性能?
在TiDB中,SHARD_ROW_ID_BITS
是一個(gè)表屬性,用于設(shè)置隱式_tidb_rowid
分片數(shù)量的bit位數(shù),以此來解決寫入熱點(diǎn)問題。這個(gè)屬性可以在創(chuàng)建表時(shí)指定,也可以用來修改現(xiàn)有表的行為。
調(diào)整SHARD_ROW_ID_BITS
值的步驟:
SHARD_ROW_ID_BITS
的值:SHARD_ROW_ID_BITS
值。例如,如果當(dāng)前設(shè)置為4(分成16個(gè)分片),但寫入壓力仍然很高,可以考慮增加該值。ALTER TABLE
語句來修改SHARD_ROW_ID_BITS
值: ALTER TABLE your_table_name SHARD_ROW_ID_BITS = new_value;
new_value
是你基于業(yè)務(wù)增長評估后決定的新值。PRE_SPLIT_REGIONS
選項(xiàng)在建表后預(yù)先切分出一定數(shù)量的Region: CREATE TABLE t (a int, b int) SHARD_ROW_ID_BITS = 4 PRE_SPLIT_REGIONS=3;
PRE_SPLIT_REGIONS=3
表示建完表后提前切分出8個(gè)Region。SHARD_ROW_ID_BITS
后,繼續(xù)使用Grafana監(jiān)控系統(tǒng)性能,特別注意寫入流量的分布情況。SHARD_ROW_ID_BITS
的值,或者考慮其他優(yōu)化措施。需要注意的是:
SHARD_ROW_ID_BITS
的值會(huì)增加Region的分裂數(shù)量,可能會(huì)對TiDB集群的性能和資源使用產(chǎn)生影響。SHARD_ROW_ID_BITS
值時(shí),需要確保PD調(diào)度器不會(huì)因?yàn)樾egion合并策略而將Region重新合并。
關(guān)于使用分布式ID生成器,比如雪花算法,還有使用UUID和使用Sequence序列,這里V 哥就不再介紹了,與 MySQL 一致。因此,在 TiDB 中提供了AUTO_RANDOM
和 SHARD_ROW_ID_BITS
來解決熱點(diǎn)問題,好用的很。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: