우리는 6 노드 Red Hat 4.4.7/Linux 2.6.32 네트워크를 가지고 있으며, 각 노드는 Hibernate 3.3.2.GA를 사용하여 중앙 Oracle 데이터베이스에 레코드를 생성하는 Java 애플리케이션을 실행합니다.중복 된 UUID를 생성하는 최대 절전 모드
Hibernate에서 중복 된 UUID를 생성하는 문제가 발생했습니다. 다음과 같은 문제
Java 클래스가 정의 :
@Entity
@Table(name = "X_Y")
@GenericGenerator(name = "x-y-uuid", strategy = "uuid")
public class XY implements ... {
@Id
@Column(name = "X_Y_ID")
@GeneratedValue(generator = "x-y-uuid")
private String id;
...
}
우리는 잠시 동안 성공적으로 사용하고이 정의를 사용하여, 우리는 중복 X_Y_ID 키의 문제로 달렸다. X_Y_ID에 대한 고유 제한 조건을 사용 불가능으로 설정하고 프로세스를 재개합니다. 그 사이에, 우리는 Hibernate 코드뿐만 아니라 우리 코드에서 발생할 수있는 오류를 찾아 내기 시작했다. Hibernate의 UUIDHexGenerator
을 보면 UUID의 처음 8 문자는 기기의 IP 주소를 기반으로하며, 두 번째 8 문자는 JVM 시작 시간을 기반으로합니다.
X_Y_ID에 대한 사용 불가능한 고유 제한 조건을 사용한 프로세스가 완료된 후 결과 UUID를 분석했습니다. 사실 59 개의 중복 된 X_Y_ID 값이 있음을 발견했습니다. 우리 놀랍게도 , 쿼리 :
select SUBSTR(X_Y_ID,1,8), COUNT(*)
from X_Y
group by SUBSTR(X_Y_ID,1,8)
는 6 개 시스템이 동일한 처음 8 개 문자가있는 것으로 나타났다. 쿼리 :
select SUBSTR(X_Y_ID,9,8), COUNT(*)
from X_Y
group by SUBSTR(X_Y_ID,9,8)
는 당신이 볼 수 있듯이 행의 마지막 가진 약 두 배 수에 5 개 행이
"49d99de6" 2148309
"49d99e3c" 2044966
"49d99def" 2228095
"49d99df2" 2091068
"49d99dee" 4110661
했다. 이것은 놀랍지 않습니다. (모두 그것은 서로 다른 두 머신의 JVM이 서로 256ms 이내에 시작되었음을 의미합니다).
조금 더 조사해 보았을 때 처음 8 자에 대해 생성 된 값인 ff808081
은 IP 주소 127.0.0.1 인 localhost에 해당합니다. 이러한 시스템 중 하나에서 ifconfig
실행
(예를 들어) 제공합니다
eth0 Link encap:Ethernet HWaddr 00:50:56:81:2C:20
inet addr:10.191.8.50 Bcast:10.191.63.255 Mask:255.255.192.0
inet6 addr: fe80::250:56ff:fe81:2c20/64 Scope:Link
...
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
...
내 질문
은 다음과 같습니다- 가 어떻게이 최대 절전 모드에서 볼 수있는 IP 주소가 127.0.0.1 수 있음 10.191.8.50을 말하지 않습니까?
- 배포 된 시스템에서이를 방지하려면 어떻게해야합니까?
이것은 분명히 Hibernate의 버그이며, 그 편이 고정되어 있어야합니다. 그러나'grep $ HOSTNAME/etc/hosts' 그리고'127.0.0.1 yourhostname' 항목이 있는지 확인하십시오. –
@JasonC Hibernate가 보편적이거나 고유하지 않은 UUID를 생성하는 버그가 아닌 이유는 무엇입니까? 그들이 [RFC] (http://www.ietf.org/rfc/rfc4122.txt)를 따라 가면서 자신의 것을 뒤쫓아왔다면, 이것은 일어나지 않았을 것입니다. –
@thatotherguy 예, 사실,'UUIDHexGenerator'를 조금 더 자세히 들여다 보았습니다. 나는 그것이 어땠는지 알지 못했습니다 ... 저는 이것을 반영하기 위해 약간 아래에서 제 대답을 다시 고쳐야 할 것입니다. –