>데이터 베이스 >Redis >동시성 문제를 처리하기 위해 Redis 잠금을 사용하는 방법

동시성 문제를 처리하기 위해 Redis 잠금을 사용하는 방법

尚
앞으로
2020-05-07 09:09:546032검색

동시성 문제를 처리하기 위해 Redis 잠금을 사용하는 방법

Redis 잠금을 사용하여 동시성 문제를 처리하면 실행 중인 인스턴스가 중단되면 다른 인스턴스 중 하나가 실행되어 인스턴스가 하나만 실행되도록 할 수 있습니다.

import redis
r = redis.Redis(...)

last_heart = 0		# 记录上一次得到的锁心跳
free_lock_try = 6	# 锁无心跳的最大次数 

while not r.setnx('mylock', 1):
    now_heart = r.get('mylock')
    print(f"没获取到锁,now_heart={now_heart},last_heart={last_heart},free_lock_try={free_lock_try}")
    if now_heart == last_heart:
        free_lock_try = free_lock_try - 1
        if free_lock_try == 0:	# 锁已经1分钟没有心跳了
            old_heart = r.getset('mylock', 1)	# 将lock重置为1,并返回set之前的心跳值
            if old_heart < now_heart:
                time.sleep(10)
                continue
            else:
                break	# 成功获取到锁,退出循环
    else:
        free_lock_try = 6	# 锁有心跳,重置free_lock_try值
        last_heart = now_heart
    time.sleep(10)

def producer_exit():
    """程序正常退出时候自动清理锁"""
    r.delete(&#39;mylock&#39;)
import atexit
atexit.register(producer_exit)

# 业务代码
while True:
  r.incr(&#39;mylock&#39;)	# 让锁心跳加一
  ...

이 프로그램이 해결하는 동시성 잠금 문제를 살펴보겠습니다.

1. 높은 동시성에서는 여러 프로세스가 동시에 잠금을 얻을 수 없습니다. 여기서는 Redis.setnx가 사용됩니다. 잠금이 이미 존재하는 경우 다른 프로세스는 잠금을 재설정하고 잠금을 얻을 수 없습니다. 또한 여러 프로세스가 동시에 잠금이 있고 하트비트가 없음을 발견하면 redis.getset을 사용하여 하트비트를 1로 재설정합니다. 설정은 성공할 수 있지만 여러 프로세스에서 얻은 값은 다음 경우에만 다릅니다. 잠금이 실제로 획득되었습니다. 프로세스는 이전 프로세스의 하트비트를 반환하고 다른 프로세스는 1을 얻습니다.

2. 잠금이 있는 프로세스는 정상적으로 종료됩니다. atexit를 사용하여 잠금을 삭제하는 프로세스 종료 기능을 등록할 수 있습니다. 여기서는 이를 수행할 필요가 없지만 새 프로세스가 여러 번 기다려야 합니다. 3. 잠금이 설정된 프로세스가 예기치 않게 종료됩니다. 종료 후 하트비트는 더 이상 증가하지 않습니다. free_lock_try 수가 초과되면 다른 프로세스가 재설정되어 잠금을 획득합니다

4. 예기치 않게 이 문제는 잠금과 관련이 없습니다. 감독자를 사용하여 프로세스를 보호할 수 있습니다.

더 많은 Redis 지식을 알고 싶다면

redis 입문 튜토리얼

칼럼을 주목해 주세요.

위 내용은 동시성 문제를 처리하기 위해 Redis 잠금을 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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