一. 背景
主流架構一般分庫分表都會涉及,追求性能的同時,帶來各種痛點。
比如訂單id的生成,在分表的情況下,使用int自增,兩張分表都自增,直接會導致主鍵ID的重複,這是錯誤。
補充常見的分庫分表中間件:
1. DB層次的,針對DB做代理。
ShardingSphere-Proxy的架構圖
2. 代碼層次的
最常見的是 sharding-jdbc (他和 shardingsphere-proxy是同一產品下的東西,只是作用的層次不同),如下圖:
二者的區別詳見:https://shardingsphere.apache.org/document/legacy/3.x/document/cn/overview/
二. 方案剖析
1. 自增方案
方案1:起始點分段
比如設置分表2的起始點從10000開始
ALTER TABLE incorder_1 AUTO_INCREMENT=10000;
優缺點:
簡單容易,數據庫層面設置,代碼是不需要動的
邊界的切分人爲維護,操作複雜,觸發器自動維護可以實現但在高併發下不推薦
方案2:分段步長的自增
--查看
show session variables like 'auto_inc%';
show global variables like 'auto_inc%';
--設定自增步長
set session auto_increment_increment=2;
--設置起始值
set session auto_increment_offset=1;
--全局的
set global auto_increment_increment=2;
set global auto_increment_offset=1;
分析:
影響範圍不可控,要麼session每次設置,忘記會出亂子。要麼全局設置,影響全庫所有表
結論:不可取!!!
方案3:Sequence特性
-- 創建一個sequence:
create sequence sequence_name as int minvalue 1 maxvalue 1000000000 start with 1
increment by 1 no cache;
-- sequence的使用:
sequence_name.nextval
sequence_name.currval
-- 在表中使用sequence:
insert into incorder_0 values(sequence_name.nextval,userid);
2. 基於業務規則自定義生成
不用自增,自定義id,加上業務屬性,從業務細分角度對併發性降維。例如淘寶,在訂單號中加入用戶id。
加上用戶id後,併發性維度降低到單個用戶,每個用戶的下單速度變的可控。
時間戳+userid,業務角度,一個正常用戶不可能1毫秒內下兩個單子,即便有說明是刻意刷單,應該被前端限流。
3. 集中式分配
4. uuid和guid
5. 雪花算法
詳見下面
三. 雪花算法
!
- 作 者 : Yaopengfei(姚鵬飛)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 聲 明1 : 如有錯誤,歡迎討論,請勿謾罵^_^。
- 聲 明2 : 原創博客請在轉載時保留原文鏈接或在文章開頭加上本人博客地址,否則保留追究法律責任的權利。