>  기사  >  데이터 베이스  >  Redis 잠금의 간단한 응용 프로그램 소개

Redis 잠금의 간단한 응용 프로그램 소개

尚
앞으로
2019-11-30 15:10:502185검색

Redis 잠금의 간단한 응용 프로그램 소개

사실 다중 스레드로 데이터를 수정하는 것은 적절하지 않습니다. 결국 Redis 서버는 단일 스레드이며 모든 명령이 직렬로 실행됩니다. 그러나 클라이언트가 동시에 명령을 보내는 경우 배열 문제가 발생합니다. 직렬 명령 등의 네트워크 시간 차이로 인해 데이터 불일치가 발생합니다. 이 글은 숫자의 덧셈과 뺄셈에 관한 글이지만, lock 상황을 설명하기 위해 원자 명령 incr은 의도적으로 사용하지 않았습니다. (권장: redis 비디오 튜토리얼)

먼저 간단한 RedisHelper, 값 설정, 값 가져오기 및 동시 잠금 설정을 추가하면 후속 작업에서 내가 무엇을 했는지 정확히 알 수 있습니다.

public class RedisHelper
    {
        public RedisClient client = new RedisClient("127.0.0.1", 6379);
        public void Set<T>(string key, T val)
        {
            client.Set(key, val);
        }
        public T Get<T>(string key)
        {
            var result = client.Get<T>(key);
            return result;
        }
        public IDisposable Acquire(string key)
        {
           return  client.AcquireLock(key);
        }
    }

아래 동시 코드를 보세요. 두 개의 새로운 스레드만 추가했습니다. 두 스레드가 동시에 동일한 키에 액세스하려고 하며 각각 50,000번 액세스합니다. 동시 조건에서는 데이터의 정확성을 보장하기가 어렵습니다. 출력 결과를 비교하십시오.

static void Main(string[] args)
        {
            RedisHelper rds = new RedisHelper();
            rds.Set<int>("mykey1", 0);
            Thread myThread1 = new Thread(AddVal);
            Thread myThread2 = new Thread(AddVal);
            myThread1.Start();
            myThread2.Start();
            Console.WriteLine("等待两个线程结束");
            Console.ReadKey();
        }

        public static void AddVal()
        {
            RedisHelper rds = new RedisHelper();
            for (int i = 0; i < 50000; i++)
            {
                
                    int result = rds.Get<int>("mykey1");
                    rds.Set<int>("mykey1", result + 1);
                
            }
            Console.WriteLine("线程结束,输出" + rds.Get<int>("mykey1"));
        }

Redis 잠금의 간단한 응용 프로그램 소개

예, 단일 스레드로 두 개의 50000을 실행하면 100000이 출력됩니다. 이제 두 개의 동시 스레드가 동시에 실행되고 있기 때문에 데이터 결과가 우리가 원하는 것과 다른 경우가 많습니다. 따라서 이 문제를 해결하는 방법은 Redis가 이미 준비되어 있습니다!

내 RedisHelper의 메소드 중 하나가 공개 IDisposable Acquire(문자열 키)임을 알 수 있습니다. 또한 IDisposable을 반환하는 것을 볼 수 있는데, 이는 리소스를 수동으로 해제해야 함을 증명합니다.

메서드 내부의 AcquireLock이 핵심입니다. 이는 Redis에서 잠금을 요청하는 것과 같습니다. 잠긴 리소스는 단일 스레드에서만 액세스할 수 있으며 동시에 두 스레드에서 가져오거나 설정할 수 없습니다. 물론 여기서의 교대는 귀하에게 한 번, 나에게 한 번이라는 뜻이 아닙니다. 아래 코드를 참조하세요.

static void Main(string[] args)
        {
            RedisHelper rds = new RedisHelper();
            rds.Set<int>("mykey1", 0);
            Thread myThread1 = new Thread(AddVal);
            Thread myThread2 = new Thread(AddVal);
            myThread1.Start();
            myThread2.Start();
            Console.WriteLine("等待两个线程结束");
            Console.ReadKey();
        }

        public static void AddVal()
        {
            RedisHelper rds = new RedisHelper();
            for (int i = 0; i < 50000; i++)
            {
                using (rds.Acquire("lock"))
                {
                    int result = rds.Get<int>("mykey1");
                    rds.Set<int>("mykey1", result + 1);
                }
            }
            Console.WriteLine("线程结束,输出" + rds.Get<int>("mykey1"));
        }

잠금을 획득하기 위해 Acquire 메서드를 호출하는 데 using을 사용한 것을 볼 수 있습니다.

Redis 잠금의 간단한 응용 프로그램 소개

최종 출력 결과는 100000이며, 이는 우리가 원하는 올바른 결과입니다. 이전 8W+는 두 스레드 중 하나가 먼저 실행을 종료했기 때문입니다.

또한 정식 사용 과정에서는 사용 후 부여받은 잠금을 삭제하고,expiration을 사용하여 만료 시간을 추가하는 것을 권장합니다.

프로그램 실행 중 예기치 않은 종료를 방지하기 위해 잠금은 항상 존재하며 잠긴 데이터는 나중에 업데이트되거나 획득되지 않을 수 있습니다.

만료를 설정하지 않도록 시도할 수도 있습니다. 프로그램이 막 실행되기 시작하면 콘솔을 닫고 프로그램을 다시 실행하여 redis-cli 작업 콘솔에서 잠근 값을 얻으면 결코 얻을 수 없습니다. .

이 Redis 인스턴스에 연결된 모든 머신은 지정된 이름을 동시에 획득하는 하나의 잠금만 가질 수 있습니다.

다음은 StackExchange.Redis를 작성하는 방법입니다.

var info = "name-"+Environment.MachineName;
            //如果5秒不释放锁 自动释放。避免死锁
            if (db.LockTake("name", info, TimeSpan.FromSeconds(5)))
            {
                try
                {
                   
                }
                catch (Exception ex)
                {
                    
                }
                finally
                {
                   
                    db.LockRelease("name", token);
                }
            }

더 많은 Redis 지식을 보려면 redis에 주목하세요. 데이터베이스 튜토리얼 칼럼.

위 내용은 Redis 잠금의 간단한 응용 프로그램 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 cnblogs.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제