트랜잭션이 많은 분산 응용 프로그램의 개발과 함께 분산 캐싱 솔루션은 성능 확장성을 달성하기 위해 매우 바람직해졌습니다. NCache 를 제공하므로 인메모리 분산 데이터 저장소로 좋은 선택입니다. 선형 확장성 과 고 가용성.
지금까지는 훌륭했지만 이러한 공유 환경에서 데이터 무결성을 보장하는 방법은 큰 문제입니다. 둘 이상의 클라이언트가 애플리케이션에서 동일한 데이터에 동시에 액세스하고 변경할 수 있으므로 결과적으로 데이터가 일관되지 않을 수 있습니다. 데이터 무결성 위반이 발생하면 캐시에 있는 데이터는 사실상 쓸모가 없게 됩니다.
이 블로그 게시물에서는 이 문제가 어떻게 발생하고 어떻게 NCache 그것으로 당신을 구합니다 분산 잠금 기능.
NCache 세부 정보 NCache 잠금 Ncache 기술 문서
잠금이 없는 데이터 무결성 문제
데이터 무결성 문제를 자세히 이해하기 위해 판매자가 제품을 업로드하는 동안 고객이 해당 제품을 보고 구매하는 온라인 전자 상거래 상점의 예를 고려합니다.
고객이 특정 제품을 보고 싶어하고 해당 제품의 판매자가 가격을 업데이트하려고 한다고 가정합니다. 이제 고객이 더 높은 가격에 제품을 보고 있고 판매자가 사용자가 아직 볼 수 없는 할인을 추가하면 사용자는 더 높은 가격에 제품을 구매하게 됩니다.
시나리오는 그림 1에 나와 있습니다.
- 클라이언트 1은 캐시에서 제품의 세부 정보를 읽습니다.
- 클라이언트 2도 제품 데이터를 읽습니다. 맞습니다.
- 클라이언트 1은 이제 캐시에서 제품 세부 정보를 업데이트합니다.
- 클라이언트 2는 캐시의 제품 세부 정보도 업데이트합니다.
- 클라이언트 1의 업데이트가 손실됩니다.
방법을 보자. NCache 이 문제를 해결합니다.
NCache 분산 잠금
NCache 데이터를 잠글 수 있도록 하여 비즈니스 요구 사항에 따라 데이터를 보호하는 유연한 방법을 제공합니다. 한 사용자가 데이터 청크를 제어하고 업데이트합니다. 한편, 다른 사용자는 해당 데이터를 조작할 수 없습니다.
애플리케이션 시나리오에 따라 다음 중 하나를 선택할 수 있습니다. NCache 잠금 메커니즘:
- 비관적 잠금 (트랜잭션 또는 배타적 잠금): 다른 사용자가 액세스할 수 없도록 항목을 독점적으로 잠급니다.
- 낙관적 잠금 (항목 버전 관리를 통한 잠금): 다른 사용자가 항목에 액세스할 수 있도록 하는 항목 버전 관리를 사용합니다.
민감한 데이터에 대한 비관적 잠금
당신은 비관적 잠금 전략 애플리케이션에서 업데이트가 필요한 데이터가 민감한 경우. LockHandle을 사용하여 데이터에 대한 명시적 잠금을 획득할 수 있습니다. 완료되면 잠금이 해제됩니다.
이제 우리는 어떻게 NCache 비관적 잠금은 이 예에서 데이터 일관성 문제를 해결합니다. 한편 업데이트를 위해 제품에 대한 독점 잠금을 획득할 수 있으며 다른 사용자는 해당 제품에 액세스할 수 없습니다. 이것은 그림 2에 나와 있습니다.
- 클라이언트 1은 제품에 대한 잠금을 획득하고 제품 세부 정보를 추가하고 업데이트하기 시작합니다.
- 클라이언트 2는 제품 세부 정보를 읽을 수 있는 액세스가 거부되었으며 잠금이 해제될 때까지 기다려야 합니다.
- 잠금이 해제되면 클라이언트 2는 제품에 대한 일반 작업을 계속할 수 있습니다.
중요한 것은, NCache 잠금이 있는 것과 없는 것의 두 가지 API 세트를 지원합니다. 사용자가 비관적 잠금을 사용하려면 강력한 데이터 일관성이 요구되는 애플리케이션의 모든 곳에서 잠금 매개변수가 있는 API를 사용해야 합니다. 당신이 그것을 할 수있는 방법을 보자 NCache 잠금 기능. 다음 코드 세그먼트에서 먼저 새 LockHandle이 생성된 다음 잠금을 획득할 기간을 지정하도록 시간 범위가 설정됩니다. 이 LockHandle은 잠금을 식별하는 잠금 ID로 작동합니다. 그런 다음 키 및 LockHandle이 있는 Get 메서드를 사용하여 잠금을 획득합니다.
이제 비즈니스 운영을 수행하고 수동으로 잠금을 해제하거나 기간이 끝날 때까지 기다릴 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// Pre-condition: Cache is already connected // Create a new lock handle to fetch an Item using locking LockHandle lockHandle = new LockHandle(); // Timespan for which lock is to be taken TimeSpan timeSpan = TimeSpan.FromSeconds(5); // Get item from the cache and lock it var result = cache.Get(key, true, timeSpan, ref lockHandle); // Verify if the item is locked successfully if (result != null) { // Item has been successfully locked } else { // Key does not exist // Item is already locked with a different LockHandle } //Unlock item in cache manually cache.Unlock(key, lockHandle); |
여기서 잠금 매개변수가 있는 Get API는 잠금 획득을 기다리지 않고 즉시 반환됩니다. 처음에 실패할 경우에 대비하여 항목에 대한 잠금을 획득하려면 명시적으로 재시도해야 합니다.
LockHandle을 키와 연결하는 Lock 메서드를 사용하여 잠금을 획득할 수도 있습니다. NCache 다양한 방법을 제공합니다 명시적 잠금 획득/해제 유연한 잠금이 가능합니다. 구현하려는 경우 NCache 잠금, 사용 NCache 항목 잠금을 위한 샘플 애플리케이션 GitHub의 도움이 될 것입니다.
데이터 가용성을 위한 낙관적 잠금
비관적 잠금은 훌륭하지만 애플리케이션에 응답 시간이 중요한 경우 최적의 접근 방식이 아닐 수 있습니다. 여기에서 낙관적 잠금이 유용합니다.
NCache 낙관적 잠금 사용 캐시 항목 버전 관리 명시적 잠금의 경우에 발생하는 스레드 기아를 극복하기 위해. 따라서 해당 항목이 업데이트될 때마다 증분되는 캐시된 항목 버전에서 작업할 수 있습니다. NCache 항목 버전을 추적하므로 데이터 일관성에 대해 걱정할 필요가 없습니다.
그림 3은 완료 방법을 보여줍니다.
- 클라이언트 1은 제품에 대한 세부 정보를 추가하고 CacheItemVersion은 v1으로 설정됩니다.
- 클라이언트 2는 CacheItemVersion v1을 사용하여 업데이트된 제품 세부 정보를 읽습니다.
- 클라이언트 1은 CacheItemVersion이 증가하고 v2가 되는 세부 정보를 다시 변경합니다.
- 이제 클라이언트 2가 이전 CacheItemVersion v1을 사용하여 세부 정보를 업데이트하려고 하면 CacheItemVersion으로 작업이 실패합니다.
- 클라이언트 2는 최신 CacheItemVersion을 가져옵니다.
- 클라이언트 2는 CacheItemVersion을 사용하여 제품 세부 정보를 업데이트합니다. 이제 작업이 성공적으로 수행되고 CacheItemVersion이 자동으로 1씩 증가합니다.
이렇게 하면 모든 사용자가 항상 CacheItemVersion을 업데이트했으며 사용자가 스토어의 제품에 대한 액세스를 거부당하지 않도록 합니다.
다음 코드는 수행 방법을 보여줍니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
// Specify the key of the cacheItem string key = "Product:1001"; // Initialize the cacheItemVersion CacheItemVersion version = null; // Get the cacheItem previously added in the cache with the version CacheItem cacheItem = cache.GetCacheItem(key, ref version); // If result is not null if (cacheItem != null) { // CacheItem is retrieved successfully with the version var prod = cacheItem.GetValue(); prod.Discount = 0.5; // Create a new cacheItem with updated value var updateItem = new CacheItem(prod); //Set the itemversion. This version is used to compare the // item version of the cached item updateItem.Version = version; //Insert call will fail with LockingException, if cache contains a newer version of the cache item. //In case of LockingException, we can fetch the latest cache item from cache and update it cache.Insert(key, updateItem); // If it matches, the insert is successful, otherwise it fails } |
왜 사용 하는가? NCache 잠금
안전하고 일관된 데이터는 오늘날의 비즈니스에 매우 중요하며 다중 사용자 트랜잭션과 같은 단순한 일이 데이터 무결성을 손상시킨다면 안타까운 일이 될 것입니다.
NCache 고도로 분산된 환경에서 최고의 유연성으로 데이터의 무결성과 일관성을 보장합니다. 애플리케이션 시나리오에 따라 다음에서 제공하는 다양한 방식으로 다양한 잠금 메커니즘을 채택할 수 있습니다. NCache. 결국 데이터 불일치 없이 동시성을 갖게 됩니다!
당신이 가진 놀라운 정보를 다른 사람에게 줄 수 있습니다. 알려주셔서 감사합니다. 우리 자산의 보안을 보장하는 그러한 정보를 계속 공유하십시오.