사용 중에 자주 발생하는 성능 관련 질문에 대해 다음 세 가지 모범 사례를 제시합니다.
ID 생성 요구 사항이 5W/s를 초과하지 않는 경우 구성 매개변수를 수정할 필요가 없습니다.
❄ 5W 조각/초를 초과하고 50W 조각/초 미만인 경우 다음과 같이 수정하는 것이 좋습니다: SeqBitLength=10
❄ 50W 비트/초를 초과하고 500W 비트/초에 가까우면 다음과 같이 수정하는 것이 좋습니다: SeqBitLength=12
요약하면 SeqBitLength를 늘리면 성능이 향상되지만 생성되는 ID가 길어집니다.
❄ 더 짧고 빠른 ID를 생성하는 최적화된 눈송이 알고리즘(눈송이 드리프트)입니다.
❄ k8s(WorkerId 자동 등록) 등 컨테이너 환경의 자동 확장을 지원하고, 독립형 또는 분산 환경에서 디지털 고유 ID를 생성할 수 있습니다.
C#/Java/Go/C/Rust/Python/Node.js/PHP(C 확장)/SQL/ 및 기타 언어를 기본적으로 지원하고 멀티 스레드 안전 동적 라이브러리 호출(FFI)을 제공합니다.
모든 눈송이 알고리즘(숫자 세그먼트 모드 또는 클래식 모드, 크고 작은 제조업체)과 호환되므로 향후 업그레이드하거나 전환할 수 있습니다.
❄ 이것은 컴퓨터 역사상 가장 포괄적인 Snowflake ID 생성 도구입니다. 【2022년 8월 현재】
? 설계자로서 특히 여러 데이터베이스가 있는 분산 시스템에서 데이터베이스의 고유 기본 키 문제를 해결하고 싶습니다.
? 데이터 테이블의 기본 키가 최소한의 저장 공간을 사용하고, 더 빠르게 색인을 생성하고, 선택, 삽입 및 업데이트가 더 빠르게 이루어지기를 원합니다.
? 데이터베이스와 테이블을 분할(데이터베이스와 테이블 병합)할 때 기본 키 값을 직접 사용할 수 있으며 업무 시점을 반영할 수 있다는 점을 고려해야 합니다.
? 이러한 기본키 값이 너무 길어서 프론트엔드 js Number 타입의 최대값을 초과한다면 Long 타입을 String 타입으로 변환해야 하는데 조금 답답함을 느낄 것입니다.
? Guid는 자동 증가 기능이 있지만 공간을 많이 차지하고 인덱싱 속도가 느립니다.
? 애플리케이션 인스턴스가 50개가 넘을 수 있으며 각 동시 요청은 10W/s에 도달할 수 있습니다.
? 컨테이너 환경에 애플리케이션을 배포하기 위해 수평 복제 및 자동 확장을 지원합니다.
? 지속적인 기본 키 ID를 얻기 위해 Redis의 자동 증가 작업에 의존하고 싶지 않습니다. 연속 ID는 비즈니스 데이터 보안 위험을 초래하기 때문입니다.
? 시스템이 100년 이상 작동하기를 원합니다.
생성된 ID가 너무 깁니다.
즉각적인 동시성의 양은 충분하지 않습니다.
시간 다이얼백 문제를 해결할 수 없습니다.
선주문 ID의 사후 추가 생성은 지원되지 않습니다.
외부 스토리지 시스템에 의존할 수 있습니다.
✔ 시간이 지남에 따라 단조롭게 증가하고(반드시 연속적이지는 않음) 길이가 더 짧으며 50년 동안 js Number 유형의 최대값을 초과하지 않는 정수입니다. (기본 구성)
✔ 기존 눈송이 알고리즘보다 2~5배 빠른 속도로 0.1초에 50만개 생성이 가능합니다. (8세대 저전압 i7 기준)
✔ 시간 콜백 처리를 지원합니다. 예를 들어 서버 시간이 1초 뒤로 설정되면 이 알고리즘은 중요한 시간에 대한 고유 ID를 생성하도록 자동으로 조정할 수 있습니다.
✔새 ID의 수동 삽입을 지원합니다. 비즈니스가 기록 시간에 새 ID를 생성해야 하는 경우 이 알고리즘의 예약된 비트는 초당 5,000개의 ID를 생성할 수 있습니다.
✔ 외부 캐시나 데이터베이스에 의존하지 않습니다. (k8s 환경에서 WorkerId를 자동으로 등록하는 동적 라이브러리는 redis에 의존합니다)
✔기본 기능, 즉시 사용 가능, 구성 파일, 데이터베이스 연결 등이 필요하지 않습니다.
(파라미터: 10비트 자동 증가 시퀀스, 1000 드리프트 최대값)
지속적인 요청 | 5K | 5W | 50W |
---|---|---|---|
전통적인 눈송이 알고리즘 | 0.0045초 | 0.053초 | 0.556초 |
스노우 드리프트 알고리즘 | 0.0015초 | 0.012초 | 0.113초 |
? 최고의 성능: 500W/s~3000W/s. (모든 테스트 데이터는 8세대 저전압 i7 기준으로 계산되었습니다.)
? 시스템 시간이 다시 조정되면 알고리즘은 과거 시계열의 예약된 시퀀스 번호를 사용하여 새 ID를 생성합니다.
? 콜백에 의해 생성된 ID 번호는 기본적으로 먼저 배치되며 나중에 조정될 수도 있습니다.
? 시간이 이 알고리즘의 사전 설정된 기준으로 다시 설정되도록 허용합니다(매개변수는 조정 가능).
? 이 알고리즘에 의해 생성된 ID는 정수입니다(최대 8바이트의 공간을 차지함). 다음은 기본 구성을 기반으로 생성된 ID입니다.
129053495681099 (运行1年,长度:15)
387750301904971 (运行3年,长度:15)
646093214093387 (运行5年,长度:15)
1292658282840139 (运行10年,长度:16)
9007199254740992 (运行70年,达到 js Number 最大值,长度:16)
165399880288699493 (运行1000年,等同普通雪花算法运行1年,长度:18)
? 이 알고리즘으로 생성되는 ID 값은 js Number 최대값의 1%~10%로 일반 눈송이 알고리즘 값의 1/1000이지만 생성 속도는 일반 눈송이 알고리즘보다 빠릅니다.
? js Number 유형의 최대값: 9007199254740992. 이 알고리즘은 동시성 성능(5W+/0.01s) 및 최대 64개의 WorkerId(6비트)를 유지하면서 js Number Max 값에 도달하는 데 70년이 걸릴 수 있습니다.
? 每增加 1位 WorkerIdBitLength 或 SeqBitLength,生成的ID数字值将会乘以2(基础长度可参考前一节“ID示例”),反之则除以2。
얼마나 오래 사용할 수 있는지에 대한 설명은 생성된 ID 번호가 long(signed 64bit, 8byte)의 최대값을 초과하여 커질 수 있는 경우를 의미합니다.
• 기본 구성에서는 71000개의 고유 ID를 사용할 수 있습니다.
? 1024개 워커노드 지원시 ID는 4480년간 중복없이 사용 가능합니다.
? 4096개 워커노드 지원시 ID는 1120년간 중복없이 사용 가능합니다.
WorkerIdBitLength 는 기계 코드 비트 길이에 따라 WorkerId의 최대값을 결정하며 기본값은 6 이며 값 범위는 [1, 19]입니다. 실제로 일부 언어에서는 unsigned ushort(uint16) 유형을 사용하여 수신합니다. 이 매개변수이므로 최대값은 16입니다. signed short(int16)를 사용하는 경우 최대값은 15입니다.
❄ WorkerId , 기계 코드, 가장 중요한 매개변수 , 기본값 없음, 전역적으로 고유 해야 함(또는 동일한 DataCenterId 내에서 고유해야 함), 프로그래밍 방식으로 설정 해야 함, 기본 조건(WorkerIdBitLength가 기본값을 사용함), 최대값은 63 이론적 최대값은 2^WorkerIdBitLength -1입니다(다른 구현 언어는 65535 또는 32767로 제한될 수 있으며 원칙은 WorkerIdBitLength 규칙과 동일합니다). 다른 시스템이나 다른 애플리케이션 인스턴스에서 동일할 수 없습니다 . 애플리케이션을 통해 이 값을 구성하거나 외부 서비스를 호출하여 값을 얻을 수 있습니다. WorkerId의 자동 등록 요구에 대한 응답으로 이 알고리즘은 기본 구현을 제공합니다. 즉, Redis를 통해 WorkerId의 동적 라이브러리를 자동으로 등록합니다. 자세한 내용은 "ToolsAutoRegisterWorkerId"를 참조하세요.
특별 참고 사항 : 서버가 여러 개의 독립 서비스를 배포하는 경우 각 서비스에 대해 서로 다른 WorkerId를 지정해야 합니다.
❄ SeqBitLength , 시퀀스 비트 길이, 기본값 6 , 값 범위 [3, 21](4 이상 권장)은 밀리초당 생성되는 ID 수를 결정합니다. 초당 요청 수가 5W를 초과하지 않으면 기본값인 6을 그대로 유지하고, 5W를 초과하고 50W를 초과하지 않으면 10 이상의 값을 할당하는 것이 좋습니다. 규칙 요구 사항: WorkerIdBitLength + SeqBitLength는 22를 초과하지 않습니다.
❄ MinSeqNumber , 최소 시퀀스 번호, 기본값 5, 값 범위 [5, MaxSeqNumber], 밀리초당 처음 5개의 시퀀스 번호는 숫자 0-4에 해당하며, 그 중 1-4는 시간 다이얼백에 해당하는 예약 비트입니다. , 0은 수동 새 값을 위해 예약된 비트입니다.
❄ MaxSeqNumber , 최대 시퀀스 번호, 설정 범위는 [MinSeqNumber, 2^SeqBitLength-1], 기본값은 0, 실제 최대 시퀀스 번호는 0이 아닌 경우 최대값(2^SeqBitLength-1)입니다. , 이는 실제 최대 시퀀스 번호이며, 여러 시스템이 세그먼트에서 ID를 생성하기 위해 WorkerId를 공유하지 않는 한 일반적으로 설정할 필요가 없습니다(이 경우 최소 시퀀스 번호가 올바르게 설정되어야 함).
❄ BaseTime , 기본 시간(기준점 시간, 원래 시간, 에포크 시간이라고도 함)은 기본값(2020)을 가지며 밀리초 타임스탬프(정수, .NET은 DatetTime 유형)이며 해당 기능은 다음과 같습니다. ID 생성 시 시스템 시간과 기준 시간의 차이(밀리초)가 ID 생성을 위한 타임스탬프로 사용됩니다. 기본 시간은 일반적으로 설정할 필요가 없으며, 기본값이 너무 오래되었다고 생각되면 재설정할 수 있습니다. 하지만 앞으로는 이 값을 변경하지 않는 것이 가장 좋습니다.
두 번째 버전에서는 매개변수를 추가할 계획입니다.
❄ DataCenterId , 데이터 센터 ID(컴퓨터실 ID, 기본값 0)는 전역적으로 고유한지 확인하세요.
DataCenterIdBitLength , 데이터 센터 ID 길이(기본값 0).
❄ TimestampType , 타임스탬프 유형(0밀리초, 1초), 기본값은 0입니다.
1️⃣ 싱글톤 모드로 호출합니다. 이 알고리즘은 단일 스레드를 사용하여 ID를 생성하며 여러 당사자의 호출은 상호 배타적입니다. 동일한 애플리케이션 인스턴스 내에서 호출자는 멀티스레딩(또는 병렬)을 사용하여 이 알고리즘을 호출하지만 ID 출력 속도는 증가하지 않습니다.
2️⃣ 고유한 WorkerId를 지정합니다. WorkerId의 전역 고유성은 외부 시스템에 의해 보장되어야 하며 이 알고리즘의 입력 매개변수에 할당되어야 합니다.
3️⃣ 단일 머신에 여러 인스턴스를 배포할 때 서로 다른 WorkerId를 사용하세요. 모든 구현이 프로세스 간 동시 고유성을 지원하는 것은 아닙니다. 동일한 호스트에 여러 애플리케이션 인스턴스를 배포할 때 안전을 위해 각 WorkerId가 고유한지 확인하세요.
4️⃣ 예외처리. 알고리즘은 모든 예외를 발생시키며, 외부 시스템은 예외를 포착하고 이를 잘 처리하여 더 큰 시스템 충돌이 발생하지 않도록 해야 합니다.
5️⃣ 이 알고리즘을 통합하고 사용하는 데 도움이 되는 IdGeneratorOptions의 정의를 주의 깊게 이해하세요.
6️⃣ 스노우 드리프트 알고리즘을 사용하세요. 코드에 기존 눈송이 알고리즘의 정의가 포함되어 있고 진입점에서 (방법=2)를 지정하여 기존 알고리즘을 활성화할 수 있지만 여전히 눈송이 드리프트 알고리즘(방법=1, 기본값)을 사용하는 것이 좋습니다. , 결국 신축성이 더 좋고 성능도 더 좋습니다.
7️⃣ 핵심 알고리즘을 수정하지 마세요. 본 알고리즘은 내부 매개변수가 많고 로직이 복잡하므로, 핵심 로직을 숙지하지 않은 경우, 수많은 꼼꼼하고 과학적인 테스트를 통해 검증되지 않은 이상 핵심 코드를 수정하여 프로덕션 환경에서 사용하지 마십시오.
8️⃣ 애플리케이션 도메인 내의 구성 정책은 동일합니다. 시스템이 일정 기간 동안 실행되었고 프로젝트가 WorkerId를 프로그래밍 방식으로 지정하는 것에서 WorkerId를 자동으로 등록하는 것으로 전환해야 하는 경우 동일한 애플리케이션 도메인에서 사용 중인 모든 인스턴스가 일관된 구성 전략을 채택하는지 확인하십시오. 이는 WorkerId에만 적용되는 것이 아닙니다. 이지만 다른 구성 매개변수도 포함됩니다.
9️⃣ 서버 시간을 잘 관리하세요. Snowflake 알고리즘은 시스템 시간에 의존합니다. 운영 체제 시간을 대량으로 수동으로 조정하지 마십시오. 조정해야 하는 경우 서비스가 다시 시작될 때의 시스템 시간이 마지막으로 종료된 시간보다 큰지 확인하십시오. (참고: 세계적 수준 또는 네트워크 수준의 시간 동기화 또는 콜백으로 인한 시스템 시간의 작은 변화는 이 알고리즘에 영향을 미치지 않습니다.)
구성 변경은 시스템이 일정 기간 실행된 후 작동 매개변수(IdGeneratorOptions 개체 속성)를 조정하는 것을 의미합니다.
? 1. 첫 번째 원칙은 BaseTime은 더 오래된 것(현재보다 더 오래됨)일 수 있으므로 생성된 ID 값이 과거 최대 값보다 커서 시간이 중복되지 않고 중복 ID가 생성되지 않는다는 것입니다. [ 시스템 실행 후에는 BaseTime을 조정하는 것을 권장하지 않습니다 .]
2. 언제든지 WorkerIdBitLength 또는 SeqBitLength를 늘리는 것이 허용되지만 "감소" 작업은 나중에 생성되는 ID가 이전 구성과 동일해질 수 있으므로 주의해서 사용해야 합니다. [시스템 실행 후 xxxBitLength 값이 증가하도록 허용]
3. WorkerIdBitLength 또는 SeqBitLength 중 하나를 줄여야 하는 경우 조건이 충족되어야 합니다. 두 개의 새 xxxBitLength의 합은 이전 값의 합보다 커야 합니다. [실행 후 BitLength 값을 좁히는 것은 권장되지 않습니다 .]
? 4. 위의 세 가지 규칙은 이 알고리즘에서 논리적으로 제어되지 않습니다. 사용자는 새 구성이 요구 사항을 충족하는지 확인한 후 구성을 변경해야 합니다.
? 고유 ID 생성기는 WorkerId를 사용합니다. 비즈니스 서비스에 수평적 및 무차별 복제(자동 확장)가 필요한 경우 고유 ID를 생성하기 전에 전역적으로 고유한 WorkerId를 자동으로 등록하는 기능이 필요합니다.
? 이 알고리즘은 k8s와 같은 컨테이너 환경에서 Redis를 통해 WorkerId를 자동으로 등록할 수 있는 오픈 소스 동적 라이브러리(Go 언어로 구현)를 제공합니다.
? Redis를 통해 WorkerId를 등록하는 것이 유일한 방법은 아닙니다. 중앙 집중식 구성 서비스를 개발할 수도 있습니다. 각 엔드포인트 서비스가 시작되면 중앙 서비스를 통해 고유한 WorkerId를 얻습니다.
물론 서비스가 자동으로 확장될 필요가 없다면 WorkerId를 자동으로 등록할 필요는 없지만 전역적으로 고유한 값을 설정해야 합니다.
? 각 엔드포인트 서비스(단일 또는 일괄)에 사용 가능한 ID를 생성하는 중앙 집중식 ID 생성 서비스 개발과 같은 다양한 방법이 있습니다.
이미지 링크: https://github.com/yitter/IdGenerator/blob/master/Tools/AutoRegisterWorkerId/regprocess.jpg
소스코드 경로:/Go/source/regworkerid/reghelper.go
다운로드 링크: https://github.com/yitter/IdGenerator/releases/download/v1.3.3/workeridgo_lib_v1.3.3.zip
// 注册一个 WorkerId,会先注销所有本机已注册的记录
// address: Redis连接地址,单机模式示例:127.0.0.1:6379,哨兵/集群模式示例:127.0.0.1:26380,127.0.0.1:26381,127.0.0.1:26382
// password: Redis连接密码
// db: Redis指定存储库,示例:1
// sentinelMasterName: Redis 哨兵模式下的服务名称,示例:mymaster,非哨兵模式传入空字符串即可
// minWorkerId: WorkerId 最小值,示例:30
// maxWorkerId: WorkerId 最大值,示例:63
// lifeTimeSeconds: WorkerId缓存时长(秒,3的倍数),推荐值15
extern GoInt32 RegisterOne(char* server, char* password, GoInt32 db, char* sentinelMasterName, GoInt32 minWorkerId, GoInt32 maxWorkerId, GoInt32 lifeTimeSeconds);
// 注销本机已注册的 WorkerId
extern void UnRegister();
언어 | 깃허브 |
---|---|
?기음# | 예시 보기 |
?자바 | 예시 보기 |
?가다 | 예시 보기 |
녹 | 예시 보기 |
?파이썬 | 예시 보기 |
?기음 | 예시 보기 |
? C(PHP 확장) | 예시 보기 |
? 델파이(파스칼) | 예시 보기 |
? | 예시 보기 |
?타입스크립트 | 예시 보기 |
? | 예시 보기 |
?디 | 예시 보기 |
오픈소스 주소: https://github.com/yitter/IdGenerator
QQ 그룹: 646049993