컴퓨터 지식 네트워크 - 컴퓨터 백과사전 - 데이터베이스 클러스터에서 id 의 고유성을 보장하는 방법, 초당 20 만 개의 동시 이벤트가 있다고 가정합니다.

데이터베이스 클러스터에서 id 의 고유성을 보장하는 방법, 초당 20 만 개의 동시 이벤트가 있다고 가정합니다.

눈송이 알고리즘의 도구 클래스를 사용하면 1 초 내에 260,000 개의 고유 값을 생성할 수 있습니다. 데이터베이스의 기본 키는 스스로 늘릴 수 없으므로 수동으로 설정해야 합니다.

소포? 실체

수입? Java.lang.management.management factory;

수입? Java.net.inetaddress;

수입? Java.net.network interface;

/* *

*? & LTP> 이름: idworker.java

*? & LTP> 설명: 분산 자체 성장 ID

*? & ltpre & gt

*? 트위터? 눈송이 자바 구현 시나리오

*? & lt/pre & gt;;

*? 핵심 코드는 해당 ID 작업자 클래스에 대해 구현되며 원리 구조는 다음과 같습니다. 저는 0 을 사용하여 비트를 나타내고,-를 사용하여 각 부분의 기능을 구분합니다.

*? 1||0-0000000000? 0000000000? 0000000000? 0000000000? 0? -응? 00000? -00000 이요? -000000000000

*? 위 문자열에서 첫 번째 비트는 사용되지 않고 (실제로 long 의 기호 비트로도 사용 가능), 다음 4 1 비트는 밀리초 시간입니다.

*? 그런 다음 5 비트 데이터 센터 식별 비트, 5 비트 시스템 ID (식별자가 아니지만 실제로는 스레드 ID) 가 있습니다.

*? 그러면 현재 밀리초의 12 비트 수를 합치면 64 비트에 불과하며 긴 유형이다.

*? 이렇게 하면 전체 시스템이 시간순으로 정렬되고 전체 분산 시스템에서 ID 충돌 (데이터 센터와 시스템 ID 구분) 이 발생하지 않는다는 장점이 있습니다.

*? 매우 효율적입니다. 테스트를 거쳐 눈송이는 초당 약 26 만 개의 ID 를 생성하여 요구 사항을 완벽하게 충족합니다.

*? & LTP>

*? 64 비트 ID? (42 (밀리초) +5 (기계 ID)+5 (서비스 코드)+12 (반복 누적))

*

*? @ 저자? 폴 림

*/

공공? 반? Id 작업자? {

//? 시간 시작 마크 포인트는 일반적으로 시스템의 가장 늦은 시간을 기준으로 합니다 (일단 확인되면 변경할 수 없음).

개인? 결승전? 정전기? 용? Twepoch? =? 128834974657l;

//? 기계 식별 번호

개인? 결승전? 정전기? 용? 워릭비츠? =? 5L

//? 데이터 센터 식별 번호

개인? 결승전? 정전기? 용? 데이터 센터 id 비트? =? 5L

//? 최대 시스템 ID

개인? 결승전? 정전기? 용? MaxWorkerId? =? -1L? -응? (-1L? & lt& lt? 작업자 id 비트);

//? 최대 데이터 센터 ID

개인? 결승전? 정전기? 용? MaxDatacenterId? =? -1L? -응? (-1L? & lt& lt? Datacenteridbits);

//? 밀리초 단위의 자체 증가

개인? 결승전? 정전기? 용? SequenceBits? =? 12l;

//? 기계 ID 가 왼쪽으로 12 비트 이동합니다.

개인? 결승전? 정전기? 용? WorkerIdShift? =? SequenceBits

//? 데이터 센터 ID 왼쪽 17 비트.

개인? 결승전? 정전기? 용? 데이터 센터 IdShift? =? SequenceBits? +? 위키백과: 위키백과

//? 시간 밀리초가 왼쪽으로 22 비트 이동합니다.

개인? 결승전? 정전기? 용? TimestampLeftShift? =? SequenceBits? +? 워릭비츠? +? DatacenterIdBits

개인? 결승전? 정전기? 용? SequenceMask? =? -1L? -응? (-1L? & lt& lt? SequenceBits

/*? 마지막 프로덕션 id 타임스탬프? */

개인? 정전기? 용? Last 타임스탬프? =? -1l;

//? 0, 동시 제어

개인? 용? 시퀀스? =? 0l;

개인? 결승전? 용? 작업자 id

//? 데이터 id 섹션

개인? 결승전? 용? DatacenterId

공공? IdWorker(){

This.datacenterId? =? Getdata centerid (maxdata centerid);

This.workerId? =? Getmaxworkerid (데이터 센터, maxworkerid);

}

/* *

*? @param? 근로자 Id

* 작업자 ID

*? @param? 데이터 센터 Id

* 일련 번호

*/

공공? Id 작업자 (길이? 작업자 id,? 용? DatacenterId)? {

만약? (작업자 id? & gt? MaxWorkerId? | |? 작업자 id? & lt? 0)? {

던져? 새 것? Illegalargumentexception (string.format ("작업자? Id? 안 돼요? 그래요? 더 위대한가? 비교? %d? 아니면? 적게? 비교? 0 ",? MaxWorkerId)););

}

만약? (데이터 센터 Id? & gt? MaxDatacenterId? | |? 데이터 센터 Id? & lt? 0)? {

던져? 새 것? Illegalargumentexception (string.format ("데이터 센터? Id? 안 돼요? 그래요? 더 위대한가? 비교? %d? 아니면? 적게? 비교? 0 ",? MaxDatacenterId)););

}

This.workerId? =? 작업자 id

This.datacenterId? =? DatacenterId

}

/* *

*? 다음 ID 가져오기

*

*? @ 반환

*/

공공? 동기화? 용? NextId ()? {

용? 타임 스탬프? =? Timegen ();

만약? (타임 스탬프? & lt? LastTimestamp)? {

던져? 새 것? Runtimeexception (string.format ("clock? 감동? 뒤로. 거부? 어디 가? 생성? Id? 뭐 때문에? %d? 밀리초',? Last 타임스탬프? -응? 타임 스탬프));

}

만약? (lastTimestamp? = =? 타임 스탬프)? {

//? 현재 밀리 초 이내에+1

시퀀스? =? (시퀀스? +? 1)? & amp? SequenceMask

만약? (시퀀스? = =? 0)? {

//? 현재 밀리초 수가 꽉 차면 다음 초를 기다립니다.

타임 스탬프? =? Tilnextmillis (last timestamp);

}

}? 그렇지 않으면요? {

시퀀스? =? 0l;

}

Last 타임스탬프? =? 타임스탬프

//? ID 오프셋 조합은 최종 ID 를 생성하고 해당 ID 를 반환합니다.

용? NextId? =? ((타임 스탬프? -응? Twepoch)? & lt& lt? TimestampLeftShift)

|? (데이터 센터 Id? & lt& lt? 데이터 센터 IdShift)

|? (작업자 id? & lt& lt? WorkerIdShift)? |? 시퀀스;

반환? NextId

}

개인? 용? TilNextMillis (최종? 용? LastTimestamp)? {

용? 타임 스탬프? =? This.timegen ();

언제? (타임 스탬프? & lt=? LastTimestamp)? {

타임 스탬프? =? This.timegen ();

}

반환? 타임스탬프

}

개인? 용? TimeGen ()? {

반환? System.currenttimemillis ();

}

/* *

*? & LTP>

*? 알았어? MaxWorkerId

*? & lt/p & gt;;

*/

보호받고 있습니까? 정전기? 용? GetMaxWorkerId(long? 데이터 센터 Id,? 용? MaxWorkerId)? {

StringBuffer? Mpid? =? 새 것? Stringbuffer ();

Mpid.append (데이터 센터);

문자열? 이름? =? Managementfactory.getruntimemxbean () 을 참조하십시오. Getname ();

만약? (! Name.isEmpty ()? {

/*

*? 알았어? JvmPid

*/

Mpid.append (name.split ("@" [0]);

}

/*

*? 마이크. +? PID? 무슨 일이야? 하쉬코드? /kloc 가져오기-0/6 낮음

*/

반환? (mpid.toString (). HashCode ()? & amp? 0xffff)? %? (maxWorkerId? +? 1);

}

/* *

*? & LTP>

*? 데이터 id 섹션

*? & lt/p & gt;;

*/

보호받고 있습니까? 정전기? 용? GetDatacenterId(long? MaxDatacenterId)? {

용? Id? =? 0l;

해봐? {

인터넷 주소? Ip? =? Inetaddress.getlocalhost ();

네트워크 인터페이스? 인터넷? =? Networkinterface.getbyinetaddress (IP);

만약? (인터넷? = =? Null)? {

Id? =? 1l;

}? 그렇지 않으면요? {

Byte[]? 마이크. =? Network.gethardwareaddress ();

Id? =? ((0x000000FF? & amp? "용"? Mac[mac.length? -응? 1])

|? (0x0000FF00? & amp? ((길이)? Mac[mac.length? -응? 2])? & lt& lt? 8))? & gt& gt? 6;

Id? =? Id? %? (maxDatacenterId? +? 1);

}

}? 받아요? (예외? E)? {

System.out.println ("? GetDatacenterId:? " -응? +? E. getmessage ());

}

반환? Id;

}

공공? 정전기? 무효화? 메인 (string []? Args)? {

//Twitter 26 만 개의 고유 id

Id 작업자? Id 작업자? =? 새 것? Id 작업자 (0,0);

뭐 때문에? (int? 나? =? 0; -응? 나? & lt2600? 을 눌러 섹션을 인쇄할 수도 있습니다 -응? I++)? {

System.out.println (idworker.nextid ());

}

}

}

上篇: 왕지건이 핸드폰을 만드는 것을 어떻게 생각합니까? 下篇: 핸드폰에서 어떻게 당직을 서는가?
관련 내용