雪花算法的由来
分布式ID生成规则
全局唯一
趋势递增
单调递增
信息安全
含时间戳
为啥递增?
现在mysql默认地存储引擎是InnoDB,索引是有序递增的。插入有序递增的id,索引直接在最后就维护了,如插入不是有序递增的,那么新的索引可能插入到头或中间位置,可能会导致页的分裂,维护索引耗费时间。
分布式ID生成系统的可用性要求
高可用
低延迟
高QPS
id生成
一般方案
UUID
满足了唯一性,但满足不了有序
的要求,所以插入数据库的性能差。
数据可自增主键
单机
集群
Redis
snowflake
Twitter的分布式自增id算法snowflake
概述
结构
整合springboot
直接引用hutool或者githab下雪花源码。
hutool
package com.wh.config;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.net.NetUtil;
import cn.hutool.core.util.IdUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
* @author wanghao
* @date 2021/7/18 20:15
*/
@Component
@Slf4j
public class IdGeneratorSnowflake {
private long workerId = 0;
private long datacenterId = 0;
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.info("当前机器的workerId获取失败", e);
workerId = NetUtil.getLocalhostStr().hashCode();
}
}
public synchronized long snowflakeId(){
return snowflake.nextId();
}
public synchronized long snowflakeId(long workerId,long datacenterId){
snowflake = IdUtil.createSnowflake(workerId, datacenterId);
return snowflake.nextId();
}
}