分库分表之后分布式如何保证ID全局唯一性

Posted ccccccccccccccccccccccccccccc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分库分表之后分布式如何保证ID全局唯一性相关的知识,希望对你有一定的参考价值。

分库分表之后分布式如何保证ID全局唯一性

韩师学子--小倪 2018-07-21 23:35:38 8139 收藏 3
分类专栏: mysql
版权
                         分库分表之后分布式如何保证ID全局唯一性
分库分表:
跨库的问题
分布式事务问题
查询数据结果集合并
全局性唯一性ID保证
要求:
1.全局唯一性:不能出现重复的Id号(基本的要求)
2.信息安全:防止恶意用户规矩id的规则来获取数据
3.数据递增:保证我下一个ID一定大于上一个ID.
当前201709122030 下一个;201709122031
互斥关系:信息安全、数据递增规律
CREATE TABLE \'tl_id\' {
     \'id\' varchar(255) NOT NULL,
     PRIMARY KEY(\'id\')
}ENGINE=InnoDB DEFAULT CHARSET=utf8;

业界方案:
UUID:通过唯一识别码16个字节128位的长数字。
组成部分:当前日期和时间序列+全局的唯一性网卡mac地址
优点:代码实现简单、不占用宽带、数据迁移不受影响
缺点:无序、无法保证趋势递增(要求3)字符存储、传输、查询慢、不可读


Snowflake雪花算法
 国外的twitter分布式下ID生成算法
1bit+41bit+10bit+10+bit=62bit
高位随机+毫秒数+机器码(数据中心+机器id)+10的流水好
国内:
保证数据的唯一性就行了IDC机房
优点:代码实现简单、不占用宽带、数据迁移不受影响、低位趋势递增
缺点:强以来时钟(多台服务器时间一定要一样)、无序无法保证趋势递增(要求3)

mysql方案


奇数跟我们偶数 递增步长2
适合小型互联网公司、比如可以知道我们一定生成的ID数量   五万的订单量(预定义)
一年1千8百万
Mysql 一张表500万
如果公司每天订单量5万的数据 我们用mysql设置步长位100的话可以用27年,只能为100库,公司来到风投了,每天的订单量50万100万的时候
优点:代码实现方便、性能不错、数字排序、可读性很强
缺点:受限数据库、扩展麻烦、插入数据库才能拿到ID、单点故障的问题
主从同步的时候:电商下单->支付insert master db select数据 ,因为数据同步延迟导致差不到这个数据。加cache(不是最好的解决方式)数据要求比较严谨的话查master主库。
CREATE TABLE \'tl_num\' (
     \'id\' bigint(11) NOT NULL AUTO_INCREMENT,
     KEY(\'id\') USING BTREE
)ENGINE=InnoDB auto_increment= 1 DEFAULT CHARSET = utf8;

 


Redis:
缩减版本、有关业务代码没有包含到里头、redis方案
优点:不依赖数据、灵活方便、性能优于数据库的、没有单点故障(高可用)
缺点:需要占用网络资源、性能要比本地生成慢、需要增加插件


 

@Autowired
JedisPool jedisPool;
public String getOrderIDPrefix(Date date){
Calendar c =Calendar.getInstance();
c.setTime(date);
int year = c.get(Calendar.YEAR);
int day = c.get(Calendar.DAY_OF_YEAR); //从今天属于今年的第多少天?365 2位 3位 267 001
int hout = c.get(Calendar.HOUR_OF_DAY);
String dayFmt = String.format("%1$03d", day);
String hourFmt = String.format("%1$02d", hour);
return (year - 2000) + dayFmt + hourFmt;
}
public Long orderId(String prefix){
Jedis jedis = jedisPool.getResource();
String key = "tl_order_id" + prefix;
String orderId = null;
try {
Long index = jedis.incr(key); //00001
orderId = prefix + String>format("%1$05d", index);
}catch(Exception e){
System.out.println("生成订单号异常");

}finally {
if(null != jedis){
jedis.close();
}
}
return Long.valueOf(orderId);
}
 
————————————————
版权声明:本文为CSDN博主「韩师学子--小倪」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xiao__jia__jia/article/details/81150112

以上是关于分库分表之后分布式如何保证ID全局唯一性的主要内容,如果未能解决你的问题,请参考以下文章

成为架构师课程系列数据库性能优化:写入数据量增加时,如何实现分库分表?如何保证分库分表后 ID 的全局唯一性?

[精选]分库分表之后,id 主键如何处理?如何保持全局唯一

每日一题: 分库分表之后,id主键如何处理?

分布式中的分库分表之后,ID 主键如何处理?

雪花算法-保证数据库分库分表后id的全局唯一性

雪花算法(SnowFlake)