MySQL/Gigaspaces/NetApp을 통한 분산 잠금 서비스 [폐쇄
-
21-08-2019 - |
문제
부인 성명: 나는 이미 물었다 이 질문, 그러나 배포 요구 사항이 없습니다. 나는 3 개의 upvotes를 얻은 답변을 얻었고, 배치 요구 사항을 포함시키기 위해 질문을 편집했을 때 답변은 관련이 없었다. 내가 다시 제출하는 이유는 의미있는 대답이 없더라도 원래 질문이 '답변'을 고려하기 때문입니다. 나는 열었다 uservoice 제출 이 문제에 대해. 내가 다시 게시 한 이유는 StackoverFlow가 원래 질문에 대한 답변을 고려하기 때문에 '답이없는 질문'탭에 표시되지 않습니다.
어떤 분산 잠금 서비스를 사용 하시겠습니까?
요구 사항은 다음과 같습니다.
- 다른 프로세스/기계에서 볼 수있는 상호 제외 (잠금)
- 잠금 ... 릴리스 시맨틱
- 특정 시간 초과 후 자동 잠금 해제 - 잠금 홀더가 죽으면 x 초 후에 자동으로 해제됩니다.
- Java 구현
- 쉬운 배포 - NetApp, MySQL 또는 Gigaspaces를 넘어서 복잡한 배포가 필요하지 않아야합니다. 그 제품 (특히 gigaspaces- 테라코타가 배제 된 이유)과 잘 어울립니다.
- 갖고 반갑습니다 : .NET 구현
- 무료 인 경우 : 교착 상태 감지 / 완화
"데이터베이스를 통해 수행 할 수 있습니다"또는 "Javaspaces를 통해 수행 할 수 있습니다"와 같은 답변에 관심이 없습니다. 관련 답변에는 준비된 기본적으로 입증 된 입증 된 구현 만 포함되어야합니다.
해결책
다음은 기준 3에서 의미하는 바에 따라 기준을 충족하는 Gigaspaces 기반 답변의 개요입니다. 저는 Java가 아닌 .NET의 gigaspaces와 함께 일합니다.
잠금 장치와 Datamember Bool 속성을 잠금 해제하는 SpaceId+Spacerouting 속성으로 잠금 클래스를 만듭니다.
sealed public class IdLockTrans
{
[SpaceID]
[SpaceRouting]
public string ID
{
get;
set;
}
[DataMember]
public bool Unlocked
{
get;
set;
}
public IdLockTrans(Id id)
{
ID = id.ID;
}
public IdLockTrans()
{
}
}
특정 시간 초과 후 Gigaspaces의 임대 시간을 잠금 릴리스에 사용합니다. 이렇게하면 gigaspaces가 시간 초과 기간 동안 유휴 상태 인 후 공간에서 idlocktrans 객체를 자동으로 제거하게됩니다. ID에 대한 IDLockTrans가 없으면 ID가 잠금 해제되었음을 의미합니다.
사물함 수업은이 클래스 멤버를 정의하고 초기화합니다.
private readonly ISpaceProxy _proxy;
private readonly long _leaseTime;
public override bool Lock(Id id, long timeout)
{
bool locked;
IdLockTrans lockTransTemplate = new IdLockTrans(id);
// Assume that this is a new id.
try
{
_proxy.Write(lockTransTemplate, null, _leaseTime, 0, UpdateModifiers.WriteOnly);
locked = true;
}
catch (EntryAlreadyInSpaceException)
{
using (ITransaction tx = _proxy.CreateLocalTransaction())
{
try
{
lockTransTemplate.Unlocked = true;
IdLockTrans lockTrans = _proxy.Take(lockTransTemplate, tx, timeout);
locked = (lockTrans != null);
if (lockTrans != null)
{
lockTrans.Unlocked = false;
_proxy.Write(lockTrans, tx, _leaseTime, 0, UpdateModifiers.WriteOnly);
}
tx.Commit();
}
catch
{
tx.Abort();
throw;
}
}
}
return locked;
}
public override void Unlock(Id lockedId)
{
IdLockTrans lockTrans = new IdLockTrans(lockedId);
lockTrans.Unlocked = true;
try
{
_proxy.Update(lockTrans, null, _leaseTime, 0, UpdateModifiers.UpdateOnly);
}
catch (EntryNotInSpaceException)
{
throw new Exception("IdLockTrans for " + lockTrans.ID
+ " not found on Unlock. Lock time exceeded lease time.");
}
}
다른 팁
.NET 구현은 Java API와 함께 제공되는 Box Lock/Unlock API의 기존과 매우 가깝습니다. 보다:http://www.gigaspaces.com/docs/javadoc8.0/org/openspaces/core/defaultgigamap.html
이 Java 클래스의 소스 코드를 제품과 함께 제공 한 GS-Openspaces-Src.zip 파일의 일부로 찾을 수 있습니다. gigaspaces .net api와 동일하게 사용하는 것은 StraightFWD 여야합니다.
아직도보고있는 경우, 아파치 사육사:
Zookeeper는 구성 정보를 유지하고 명명, 분산 동기화 제공 및 그룹 서비스 제공을위한 중앙 집중식 서비스입니다. 이러한 모든 종류의 서비스는 분산 애플리케이션에 의해 어떤 형태 나 다른 형태로 사용됩니다.
사육사 문서는 예를 제공합니다 잠금 서비스를 구축하는 방법 Zookeeper 위에.
MySQL을 사용하여 고유 한 키를 잠그는 것은 매우 간단합니다.
가정 1 :
트랜잭션을 사용하고 격리 수준이 커밋됩니다.
가정 2 : 고유 한 키로 처리 스레드를 잠그고 거래가 커밋 될 때 해제합니다.
그런 다음이 SQL을 배포 잠금으로 사용할 수 있습니다.
Duplicate Key 업데이트 키 = 키에 분산_Lock (키) 값 (#{key})에 삽입;