SpringCloud(第二十章 SpringCloud之雪花算法)

题目:集群高并发情况下如何保证分布式唯一全局id生成?

一、问题

1 问题
1.1 为什么需要分布式全局唯一id以及分布式id的业务需求

1、在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识
2、如在美团点评的金融、支付、餐饮、酒店;猫眼电影等产品的系统中数据日渐增长,对数据分库分表后需要有一个唯一id来标识一条数据或消息;
3、特别一点的如订单、骑手、优惠券也都需要有唯一id做标识;
4、此时一个能够生成全局唯一id的系统是非常必要的。

1.2 id生成规则部分硬性要求

1.全局唯一:不能出现重复的id号,既然是唯一标识,这是最基本的要求;
2.趋势递增:在MySQL的InnoDB引擎中使用的是聚集索引,由于多数RDBBMS使用Btree的数据结构来存储索引数据,在主键的选择上面我们应该尽量使用有序的主键保证写入性能
3.单调递增:保证下一个ID一定大于上一个ID,例如事务版本号、IM增量消息、排序等特殊需求
4.信息安全:如果ID是连续的,恶意用户的扒取工作就非常容易做了,直接按照顺序下载指定URL即可;如果是订单号就更危险了,竞对可以直接知道我们一天的单量。所以在一些应用场景下,需要ID无规则不规则,让竞争对手不好猜。
5.含时间戳:这样就能够在开发中快速了解这个分布式id的生成时间

1.3 ID号生成系统的可用性要求

1、高可用:发一个获取分布式ID的请求,服务器就要保证99.999%的情况下给我创建一个唯一分布式ID;
2、低延迟:发一个获取分布式ID的请求,服务器就要快,极速;
3、高QPS:假如并发一口气10万个创建分布式ID请求同时杀过来,服务器要顶得住且一下子成功创建10万个分布式ID;

二、一般通用方案

1、UUID
1.1 是什么
在这里插入图片描述
(如果只是考虑唯一性,OK)
1.2 But
在这里插入图片描述

2、数据库自增主键
2.1 单机
在这里插入图片描述

2.2 集群分布式
在这里插入图片描述

3、基于Redis生成全局id策略
3.1 因为redis是单线的天生保证原子性,可以使用原子操作INCR和INCRBY来实现
3.2 集群分布式
在这里插入图片描述

三种方案优缺点:
uuid:只有唯一性,趋势递增
mysql:唯一性,递增
redis:虽然五个算法思想满足,但是维护麻烦,如果整个系统不需要redis技术,但是为了生成id而使用redis来搭建,有点不划算(维护哨兵模式。。。)

三、snowflake(雪花算法)

Twitter的分布式自增ID算法snowflake

1、概述

在这里插入图片描述
在这里插入图片描述

2、结构

这里是引用
在这里插入图片描述
在这里插入图片描述

3、源码

github上有,是Scale语言写的,现在有人参考写出了java版本

4、工程落地经验
4.1 糊涂工具包

https://github.com/looly/hutool/

4.2 springboot整合雪花算法
4.2.1 pom
在这里插入图片描述

4.2.2 核心代码IdGeneratorSnowflake

@Slf4j
@Component
public class IdGeneratorSnowflake{
   private long workerId = 0;
   private long datacenterId = 1;
   private Snowflake snowflake = IdUtil.createSnowflake(workerId,datacenterId);

   @PostConstruct
   public void init(){
      try{
        workerId = NetUtil.ipv4Tolong(NetUtil.getLocalhostStr());
        log.info(“当前机器的workerId:{}”,workerId);
      }catch(Exception e){
        e.printStackTrace();
        log.warn(“当前机器的worker获取失败”,e);
        workerId = NetUtil.getLocalhostStr().hastCode();
      } 
   }
   
   public synchronized long snowflakeId(){
     return snowflake.nextId();
   }

   public synchronized long snowflakeId(long workerId,long datacenterId){
      Snowflake snowflake = IdUtil.createSnowflake(workerId,datacenterId);
      return snowflake.nextId();
   }
  
   public static void main(String[] args){
      System.out.println(new IdGeneratorSnowflake().snowflakeId());
   }
}

5、优缺点
在这里插入图片描述

四、其它补充

ps:如果实在考虑到雪花算法的时钟回拨问题,业内有以下两种解决方案。

1、百度开源的分布式唯一Id生成器UidGenerator
2、Leaf – 美团点评分布式ID生成系统

ps:尚硅谷SpringCloud学习笔记

SpringCloud(第一章 零基础理论入门)
SpringCloud(第二章 从2.2.x和H版开始说起)
SpringCloud(第三章 关于Cloud各种组件的停更/升级/替换)
SpringCloud(第四章 服务架构编码构建)
SpringCloud(第五章 Eureka服务注册与发现)
SpringCloud(第六章 Zookeeper服务注册与发现)
SpringCloud(第七章 Consul服务注册与发现)
SpringCloud(第八章 Ribbon负载均衡服务调用)
SpringCloud(第九章 OpenFeign服务接口调用)
SpringCloud(第十章 Hystrix断路器)
SpringCloud(第十一章 Gateway新一代网关)
SpringCloud(第十二章 SpringCloud Config 分布式配置中心)
SpringCloud(第十三章 SpringCloud Bus 消息总线)
SpringCloud(第十四章 SpringCloud Stream 消息驱动)
SpringCloud(第十五章 SpringCloud Sleuth 分布式请求链路跟踪)
SpringCloud(第十六章 SpringCloud Alibaba 入门简介)
SpringCloud(第十七章 SpringCloud Alibaba Nacos服务注册和配置中心)
SpringCloud(第十八章 SpringCloud Alibaba Sentinel实现熔断与限流)
SpringCloud(第十九章 SpringCloud Alibaba Seata处理分布式事务)
SpringCloud(第二十章 SpringCloud之雪花算法)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值