분산 식 유일한 ID 생 성 시리즈(4)-Redis 클 러 스 터 가 실현 하 는 분포 식 ID 는 분포 식 ID 로 적합 합 니까?
우선 항목 주소:
https://github.com/maqiankun/...
Redis 클 러 스 터 생 성 분포 식 ID 에 대해 서 는 redis 가 lua 스 크 립 트 를 사용 할 때의 EVAL,EVALSHA 명령 을 먼저 알 아야 합 니 다.
https://www.runoob.com/redis/...https://www.runoob.com/redis/...
Redis 가 분포 식 ID 를 실현 하 는 원 리 를 설명 하고 자바 언어 로 설명 합 니 다.
여기 분포 식 id 는 3 부분 으로 구성 되 어 있 습 니 다.밀리초 급 시간,redis 군집 의 몇 번 째 노드,모든 redis 노드 는 밀리초 마다 증가 하 는 시퀀스 값 입 니 다.
그 다음 에 window 는 64 비트 이 고 그 다음 에 정수 일 때 첫 번 째 는 0 이 어야 하기 때문에 가장 큰 수 치 는 63 비트 의 111111111111111111111111111111111111111111111111111111111111111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111 111
41 위의 바 이 너 리 11111111111111111111111111111111111111111111111111111 을 10 진법 으로 바 꾸 는 밀리초 가 2199023255551 이다.그 다음 에 우 리 는 2199023255551 을 시간 으로 바 꾸 면 2039-09-07 이다.즉,20 년 후에 12 위 를 redis 노드 로 할 수 있 기 때문에 최대 12 명의 111111111111,즉 최대 4095 개의 redis 노드 를 지원 할 수 있다.그 다음 에 10 비트 의 redis 각 노드 는 자체 적 으로 서열 값 을 증가 합 니 다.여 기 는 최대 10 비트 의 1111111111 입 니 다.즉,모든 redis 노드 는 밀리초 마다 1023 개의 중복 되 지 않 는 id 값 을 생 성 할 수 있 습 니 다.
그 다음 에 우 리 는 자바 코드 를 사용 하여 이 원 리 를 설명 한다.아래 의 1565165536640 L 은 밀리초 값 이다.그 다음 에 우리 의 redis 노드 는 53 으로 설정 한 다음 에 우 리 는 두 개의 서로 다른 증가 서열 값 을 설정 했다.각각 1 과 1023 이다.아래 의 결 과 는 1565165536640 L 이라는 밀리초 안에 53 번 redis 노드 는 두 개의 서로 다른 분포 식 id 값 을 생 성 했다.
package io.github.hengyunabc.redis;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test {
public static void main(String[] args) {
long buildId = buildId(1565165536640L, 53, 1);
System.out.println(" id :"+buildId);
long buildIdLast = buildId(1565165536640L, 53, 1023);
System.out.println(" id :"+buildIdLast);
}
public static long buildId(long miliSecond, long shardId, long seq) {
return (miliSecond << (12 + 10)) + (shardId << 10) + seq;
}
}
public class Test {
public static void main(String[] args) {
long buildId = buildId(1565165536640L, 53, 1);
System.out.println(" id :"+buildId);
long buildIdLast = buildId(1565165536640L, 53, 1023);
System.out.println(" id :"+buildIdLast);
}
public static long buildId(long miliSecond, long shardId, long seq) {
return (miliSecond << (12 + 10)) + (shardId << 10) + seq;
}
}
결 과 는 아래 와 같다.
id :6564780070991352833
id :6564780070991353855
그러면 누군가가 말 하 겠 습 니 다.이것 도 분포 식 id 의 설정 에 부합 되 지 않 습 니 다.가 독성 이 전혀 없습니다.여기 서 우 리 는 아래 의 방식 으로 이 분포 식 id 의 생 성 밀리초 시간 값 을 얻 을 수 있 습 니 다.
package io.github.hengyunabc.redis;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test {
public static void main(String[] args) {
long buildId = buildId(1565165536640L, 53, 1);
parseId(buildId);
long buildIdLast = buildId(1565165536640L, 53, 1023);
parseId(buildIdLast);
}
public static long buildId(long miliSecond, long shardId, long seq) {
return (miliSecond << (12 + 10)) + (shardId << 10) + seq;
}
public static void parseId(long id) {
long miliSecond = id >>> 22;
long shardId = (id & (0xFFF << 10)) >> 10;
System.err.println(" id-"+id+" :"+new SimpleDateFormat("yyyy-MM-dd").format(new Date(miliSecond)));
System.err.println(" id-"+id+" "+shardId+" redis ");
}
}
이러 면 되 잖 아,하하.
id-6564780070991352833 :2019-08-07
id-6564780070991352833 53 redis
id-6564780070991353855 :2019-08-07
id-6564780070991353855 53 redis
클 러 스 터 판 redis 의 분포 식 id 생 성 실현
이때 제 분포 식 redis 클 러 스 터 의 포트 는 각각 6380,6381 입 니 다.먼저 Evalsha 명령 안전 sha 1 검사 코드 를 생 성 합 니 다.생 성 과정 은 다음 과 같 습 니 다.먼저 6380 포트 에 대응 하 는 안전 sha 1 검사 코드 를 생 성 합 니 다.먼저 redis 의 bin 디 렉 터 리 에 들 어간 다음 에 다음 명령 을 실행 하여 lua 스 크 립 트 를 다운로드 하 십시오.
wget https://github.com/maqiankun/distributed-id-redis-generator/blob/master/redis-script-node1.lua
그리고 아래 명령 을 실행 하여 6380 포트 에 대응 하 는 안전 sha 1 검사 코드 를 생 성 합 니 다.이때 보 이 는 것 은 be6d4e21e9113bf8af47ce72f3da 18e 00580 d402 입 니 다.
./redis-cli -p 6380 script load "$(cat redis-script-node1.lua)"
먼저 6381 포트 에 대응 하 는 보안 sha 1 검사 코드 를 만 들 고 redis 의 bin 디 렉 터 리 에 먼저 들 어간 다음 명령 을 실행 하여 lua 스 크 립 트 를 다운로드 합 니 다.
wget https://github.com/maqiankun/distributed-id-redis-generator/blob/master/redis-script-node2.lua
그리고 아래 명령 을 실행 하여 6381 포트 에 대응 하 는 안전 sha 1 검사 코드 를 생 성 합 니 다.이때 97f 65601d0aaf 1a 0574 da 69b 1ff 3092969 c4310 e 를 보 았 습 니 다.
./redis-cli -p 6381 script load "$(cat redis-script-node2.lua)"
그리고 우 리 는 위의 sha 1 검사 코드 와 아래 코드 를 사용 하여 분포 식 id 를 생 성 합 니 다.
프로젝트 그림 은 다음 과 같 습 니 다 IdGenerator 류 의 코드 는 다음 과 같 습 니 다.
package io.github.hengyunabc.redis;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.tuple.Pair;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisConnectionException;
public class IdGenerator {
/**
* JedisPool, luaSha
*/
List> jedisPoolList;
int retryTimes;
int index = 0;
private IdGenerator(List> jedisPoolList,
int retryTimes) {
this.jedisPoolList = jedisPoolList;
this.retryTimes = retryTimes;
}
static public IdGeneratorBuilder builder() {
return new IdGeneratorBuilder();
}
static class IdGeneratorBuilder {
List> jedisPoolList = new ArrayList();
int retryTimes = 5;
public IdGeneratorBuilder addHost(String host, int port, String luaSha) {
jedisPoolList.add(Pair.of(new JedisPool(host, port), luaSha));
return this;
}
public IdGenerator build() {
return new IdGenerator(jedisPoolList, retryTimes);
}
}
public long next(String tab) {
for (int i = 0; i < retryTimes; ++i) {
Long id = innerNext(tab);
if (id != null) {
return id;
}
}
throw new RuntimeException("Can not generate id!");
}
Long innerNext(String tab) {
index++;
int i = index % jedisPoolList.size();
Pair pair = jedisPoolList.get(i);
JedisPool jedisPool = pair.getLeft();
String luaSha = pair.getRight();
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
List result = (List) jedis.evalsha(luaSha, 2, tab, ""
+ i);
long id = buildId(result.get(0), result.get(1), result.get(2),
result.get(3));
return id;
} catch (JedisConnectionException e) {
if (jedis != null) {
jedisPool.returnBrokenResource(jedis);
}
} finally {
if (jedis != null) {
jedisPool.returnResource(jedis);
}
}
return null;
}
public static long buildId(long second, long microSecond, long shardId,
long seq) {
long miliSecond = (second * 1000 + microSecond / 1000);
return (miliSecond << (12 + 10)) + (shardId << 10) + seq;
}
public static List parseId(long id) {
long miliSecond = id >>> 22;
long shardId = (id & (0xFFF << 10)) >> 10;
List re = new ArrayList(4);
re.add(miliSecond);
re.add(shardId);
return re;
}
}
Example 의 코드 는 다음 과 같 습 니 다.아래 while 순환 의 목적 은 여러 분포 식 id 를 인쇄 하기 위 한 것 입 니 다.아래 tab 변 수 는 evalsha 명령 의 매개 변수 입 니 다.자신의 수요 에 따라 정의 할 수 있 습 니 다.
package io.github.hengyunabc.redis;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
public class Example {
public static void main(String[] args) {
String tab = " evalsha , ";
IdGenerator idGenerator = IdGenerator.builder()
.addHost("47.91.248.236", 6380, "be6d4e21e9113bf8af47ce72f3da18e00580d402")
.addHost("47.91.248.236", 6381, "97f65601d0aaf1a0574da69b1ff3092969c4310e")
.build();
int hello = 0;
while (hello<3){
long id = idGenerator.next(tab);
System.out.println(" id :" + id);
List result = IdGenerator.parseId(id);
System.out.println(" id :" + new SimpleDateFormat("yyyy-MM-dd").format(new Date(result.get(0))) );
System.out.println("redis :" + result.get(1));
hello++;
}
}
}
이때 인쇄 결 과 는 다음 과 같다.
id :6564819854640022531
id :2019-08-07
redis :1
id :6564819855189475330
id :2019-08-07
redis :0
id :6564819855361442819
id :2019-08-07
redis :1
여기까지 redis 클 러 스 터 판 분포 식 id 는 끝 났 습 니 다.완벽 합 니 다.؏؏☝무성 하 다☝؏؏
Redis 클 러 스 터 가 실현 하 는 분포 식 id 는 분포 식 id 로 적합 합 니까?
저 는 Redis 클 러 스 터 가 분포 식 ID 를 실현 하 는 것 이 우리 가 개발 하 는 기본 적 인 사용 이 라 고 생각 합 니 다.그러나 저 는 다음 과 같은 두 가지 문제 가 있다 고 생각 합 니 다.
1:여기 서 우 리 는 지난 편의 데이터베이스 자체 증가 ID 체 제 를 비교 할 수 있 습 니 다.사실은 Redis 클 러 스 터 는 데이터 베이스 클 러 스 터 가 분포 식 ID 를 만 드 는 성능 문 제 를 해결 했다 고 할 수 있 지만 Redis 클 러 스 터 시스템 의 수준 확장 이 비교적 어렵 습 니 다.나중에 Redis 클 러 스 터 에 Redis 노드 를 추가 하려 면 데이터 베이스 클 러 스 터 의 노드 확장 만큼 번 거 로 울 것 입 니 다.
2:그리고 프로젝트 에 Redis 를 사용 하지 않 았 다 면 새로운 구성 요 소 를 도입 하 는 것 도 번 거 로 운 문제 입 니 다.
링크
다른 분포 식 ID 시리즈 단축 키:분포 식 ID 시리즈(1)-분포 식 ID 와 분포 식 ID 의 업무 수요 분포 식 ID 시리즈(2)-UUID 는 분포 식 ID 시리즈(3)-데이터베이스 자체 증가 ID 체제 가 분포 식 ID 로 적합 합 니까?분포 식 ID 시리즈(4)-Redis 클 러 스 터 가 실현 하 는 분포 식 ID 는 분포 식 ID 로 적합 합 니까?분포 식 IDID 시리즈(5)-트 위 터 의 눈 알고리즘 Snowflake 는 분포 식 ID 로 적합 합 니까?
키다리 인터넷 주소https://www.itqiankun.com/art...https://blog.csdn.net/hengyun...https://tech.meituan.com/2017...https://segmentfault.com/a/11...https://www.jianshu.com/p/9d7...
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.