第三节:分库分表下订单ID的生成的几种方案

一. 背景

 主流架构一般分库分表都会涉及,追求性能的同时,带来各种痛点。

   比如订单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 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章