分布式自增id生成算法SnowFlake
程序员文章站
2022-05-03 19:14:08
...
分布式id生成算法的有很多种,Twitter的SnowFlake就是其中经典的一种。
概述
SnowFlake算法生成id的结果是一个64bit大小的整数,它的结构如下图:
-
1位,不用。二进制中最高位为1的都是负数,但是我们生成的id一般都使用整数,所以这个最高位固定是0
41位,用来记录时间戳(毫秒)。 -
41位可以表示241−1个数字,如果只用来表示正整数(计算机中正数包含0),可以表示的数值范围是:0 至 241−1,减1是因为可表示的数值范围是从0开始算的,而不是1。
也就是说41位可以表示241−1个毫秒的值,转化成单位年则是(241−1)/(1000∗60∗60∗24∗365)=69年 - 10位,用来记录工作机器id。可以部署在210=1024个节点,包括5位datacenterId和5位workerId
5位(bit)可以表示的最大正整数是25−1=31,即可以用0、1、2、3、….31这32个数字,来表示不同的datecenterId或workerId - 12位,***,用来记录同毫秒内产生的不同id。12位(bit)可以表示的最大正整数是212−1=4095,即可以用0、1、2、3、….4094这4095个数字,来表示同一机器同一时间截(毫秒)内产生的4095个ID序号
由于在Java中64bit的整数是long类型,所以在Java中SnowFlake算法生成的id就是long来存储的。
SnowFlake可以保证:
1、所有生成的id按时间趋势递增
2、整个分布式系统内不会产生重复id(因为有datacenterId和workerId来做区分)
java实现如下(单例模式、线程安全):
package com.project.company.web;
import com.project.company.entity.Company;
import com.project.company.service.ICompanyService;
import com.project.company.util.IdGenter;
import com.project.company.util.Response;
import com.project.company.util.Result;
import org.apache.catalina.ssi.ResponseIncludeWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/company")
public class CompanyController {
@Autowired
private ICompanyService companyService;
@RequestMapping(value = "/list", method = RequestMethod.GET)
public Result getCompanys()
{
List<Company> list = companyService.findCompanyList();
return Response.success(list);
}
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public Result getCompanyById(@PathVariable("id") long id)
{
Company company = companyService.findCompanyById(id);
return Response.success(company);
}
@RequestMapping(value = "", method = RequestMethod.POST)
public Result postCompany(@RequestParam(value = "name", required = true) String name,
@RequestParam(value = "status", required = true) int status)
{
Company company = new Company();
company.setName(name);
company.setStatus(status);
int res = companyService.add(company);
if(res == 1)
{
return Response.success();
}
else
{
return Response.error(-1, "fail");
}
}
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public Result updateCompany(@PathVariable("id") long id,
@RequestParam(value = "name", required = true) String name,
@RequestParam(value = "status", required = true) int status)
{
Company company = new Company();
company.setName(name);
company.setStatus(status);
company.setId(id);
int res = companyService.update(company);
if(res == 1)
{
return Response.success();
}
else
{
return Response.error(-1, "fail");
}
}
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public Result deleteCompany(@PathVariable("id") long id)
{
int res = companyService.delete(id);
if(res == 1)
{
return Response.success();
}
else
{
return Response.error(-1, "fail");
}
}
@RequestMapping(value = "/idgenter", method = RequestMethod.GET)
public Result getId()
{
long id = IdGenter.getInstance().nextId();
return Response.success(id);
}
}
调用:
long id = IdGenter.getInstance().nextId();
本篇文章参考自《理解分布式id生成算法SnowFlake》,更详细信息请移步至该文章。
上一篇: 我跟表嫂是同学
下一篇: 眼睛的天堂之旅——日喀则的扎什伦布寺