Python 은 분포 식 잠 금 코드 를 사용 하여 예제 를 보 여 줍 니 다.
자 물 쇠 는 항상 스 레 드,프로 세 스 와 같은 단어 가 나타 나 고 완 일 봉 은 이런 명사 에 대해 간단 하고 이해 하기 쉬 운 해석 을 했다.
제 가 이해 하 는 것 은 스 레 드,프로 세 스 를 사용 하 는 것 은 병행 을 실현 하여 성능 을 향상 시 키 는 것 입 니 다(다 핵 CPU,여러 대의 서버 를 이용).그러나 이런 병행 은 스케줄 의 불확실 성 으로 인해 사고 가 발생 하기 쉽 습 니 다.(일부 공유 자원,관건 적 인 노드 에서)사고 가 나 지 않도록 자원 에 자 물 쇠 를 채 워 야 합 니 다.이 자원 을 조작 할 때 이런 병행 을 통제 하고 난 자 를 없 애 야 합 니 다.
많은 언어 들 이 스 레 드 등급 의 잠 금 실현 과 해당 하 는 도 구 를 제공 하지만 프로 세 스 에 있어 서 는 어 쩔 수 없습니다.한편,하나의 서비스 가 생산 환경 에 배치 되면 여러 개의 실례 를 배치 할 수 있다.이런 상황 에서 서로 다른 프로 세 스에 사용 되 는 자 물 쇠 를 자주 사용한다.분포 식 자 물 쇠 는 분포 식 시스템 에서 특정한 공유 자원 에 자 물 쇠 를 추가 하 는 부품 이다.
이제 Python 프로젝트 에서 간단 한 분포 식 상호 배척 자 물 쇠 를 어떻게 사용 하 는 지 보 여 주세요.
분산 자 물 쇠 를 사용 하지 않 으 면 어떻게 됩 니까?
분포 식 자 물 쇠 를 사용 하지 않 으 면 어떤 사고 가 발생 하 는 지 간단 한 인 스 턴 스 로 보 여 줍 니 다.
쇼핑 몰 시스템 이 스톱워치 활동 을 한다 고 가정 하면 redis 에 count:1 의 정 보 를 기록 하고 스톱워치 시간 이 되면 많은 요청 을 받 을 수 있 습 니 다.이때 각 응용 프로그램 은 redis 에서 count 의 값 을 찾 습 니 다.count 가 0 보다 크 면 count-1 을 사용 합 니 다.그러면 다른 요청 은 초 에 죽 일 수 없습니다.
# -*- coding: utf-8 -*-
import os
import arrow
import redis
from multiprocessing import Pool
HOT_KEY = 'count'
r = redis.Redis(host='localhost', port=6379)
def seckilling():
name = os.getpid()
v = r.get(HOT_KEY)
if int(v) > 0:
print name, ' decr redis.'
r.decr(HOT_KEY)
else:
print name, ' can not set redis.', v
def run_without_lock(name):
while True:
if arrow.now().second % 5 == 0:
seckilling()
return
if __name__ == '__main__':
p = Pool(16)
r.set(HOT_KEY, 1)
for i in range(16):
p.apply_async(run_without_lock, args=(i, ))
print 'now 16 processes are going to get lock!'
p.close()
p.join()
print('All subprocesses done.')
상기 코드 는 여러 프로 세 스 를 사용 하여 이러한 병렬 요청 장면 을 모방 합 니 다.프로그램 이 시 작 될 때 count 를 1 로 설정 한 다음 에 각 프로 세 스 가 대기 에 들 어가 기 시 작 했 습 니 다.초 수가 5 일 때 모든 프로 세 스 가 동시에 초살 함수 에 접근 하여 효 과 를 봅 니 다.실행 결과
redis 조회 전시
프로그램 인쇄 와 redis 검사 결과 뜻 대로 되 지 않 았 다.원래 상품 을 순식간에 죽 이 는 것 은 하나 뿐 이 었 으 나 4 차례 나 사재 기 에 성공 했다.이 는 각 프로 세 스 가 get count 의 값 을 사용 할 때 redis 값 업데이트 명령 을 보 냈 기 때문에 아직 완료 되 지 않 았 기 때문에 다른 프로 세 스 가 자신 이 구 매 할 수 있다 고 생각 할 수 있 습 니 다.
이런 문 제 는 중복 읽 을 수 없 는 종류의 데이터 병발 문제 로 분류 할 수 있다.
이런 보호 가 없 는 상황 에서 다른 흔히 볼 수 있 는 병발 문제 인 환 독,더러 운 읽 기,첫 번 째 두 번 째 유형의 분실 업데이트 등 이 모두 발생 할 수 있 으 므 로 여기 서 일일이 예 를 들 지 않 는 다.
ZooKeeper 를 사용 하여 분산 잠 금 을 만 듭 니 다.
분포 식 협동 문 제 를 해결 하 는 데 주력 하 는 유명 도구 로 서 zookeeper 가 제공 하 는 API 와 노드 의 유일 성과 순서 일치 성에 대한 보증 을 이용 하여 분식 자 물 쇠 를 실현 할 수 있 습 니 다.
실현 방향 은 각 프로 세 스 가
/exclusive_lock/lock
의 결산 점 을 만 드 는 것 입 니 다.zookeeper 는 하나의 client 만 성공 할 수 있다 고 보장 합 니 다.그러면 성공 적 인 client 를 만 드 는 데 자 물 쇠 를 얻 었 다 고 생각 합 니 다.업 무 를 처리 한 후에 이 node 를 삭제 하고 다른 client 는 이 사건 을 감청 하고 이 노드 를 다시 만 들 려 고 시도 합 니 다.이렇게 진행 합 니 다.Kazoo라 이브 러 리 는 이러한 Lock 을 실현 하여 사용 하기에 매우 간단 하 다.프로그래머 들 은 더 이상 acquire,release 등 자물쇠 의 유 니 버 설 인 터 페 이 스 를 실현 하지 않 아 도 된다.
또한 Python 에서 자물쇠 에 대한 사용 은 우아 한 컨 텍스트 관리자 with 를 통 해 이 루어 집 니 다.
def run_with_zk_lock(name):
zk = KazooClient()
zk.start()
lock = zk.Lock("/lockpath", "my-identifier")
while True:
if arrow.now().second % 5 == 0:
with lock:
seckilling()
return
zk 결과 사용
redis 조회 전시
스톱워치 가 발생 했 을 때 잠 금 을 얻 은 프로 세 스 만 스톱워치 작업 을 할 수 있 습 니 다.
자물쇠 의 도움 으로 프로그램 이 예상 한 대로 실행 되 었 다.
redis 를 분포 식 잠 금 으로 사용 합 니 다.
redis 홈 페이지 에는한 편의 문장redis 를 분포 식 자물쇠 로 어떻게 사용 하 는 지 전문 적 으로 소개 하고 있 으 며,문 미 에는 이 글 에 대한 반대 글 과 재 반격 글 도 첨부 되 어 있어 다소 흥미진진 하 다.
글 은 redlock 의 분포 식 잠 금 디자인 을 언급 했다.
잠 금 의 redis 명령
SET resource_name my_random_value NX PX 30000
을 설정 합 니 다.NX 인 자 를 추가 할 때 resoucename 이 존재 하지 않 아야 만 만 들 수 있 습 니 다.존재 하지 않 으 면 client 에 다른 결 과 를 되 돌려 줍 니 다.이 메커니즘 을 이용 하면 하나의 client 만 이 set 에 성공 할 수 있 습 니 다.위의 zk 와 같 습 니 다.그러나 이러한 분포 식 잠 금 을 실현 하 는 것 은 이렇게 간단 한 것 이 아니다.redis 는 zk 처럼 분포 식 협동 도구 가 아니 라 client 에 분포 식 에서 각종 일치 성과 잘못 사용,가용성 을 보장 할 것 이다.
redis 자체 도 클 러 스 터 배치 입 니 다.이들 사이 에 비동기 복제 시간 차이,잘못 사용 하 는 등 문제 가 발생 할 수 있 습 니 다.이 자 물 쇠 를 진정 으로 실현 하려 면 온라인 에서 대규모 분포 식 시스템 에서 사용 할 수 있 습 니 다.정말 여러 가지 상황 을 고려 해 야 하기 때문에 쉽 지 않 습 니 다.
언어 적 으로 자물쇠 의 인터페이스,redlock 의 원리 와 코드 실현,그리고 상기 kazoo 가방 에서 lock 의 소스 코드 를 실현 하 는 방법 에 대해 저 는 다른 전문 적 인 글 에서 말씀 드 리 겠 습 니 다.
redlock-py가방 은 python 언어 에서 상기 글 에 대한 실현 입 니 다.우 리 는 지금 그것 을 사용 하여 시도 하고 있 습 니 다.
rlock = RedLock([{"host": "localhost", "port": 6379, "db": 0}, ])
def run_with_redis_lock(name):
while True:
if arrow.now().second % 5 == 0:
with rlock:
seckilling()
return
redis 잠 금 실행 결과
실행 결 과 는 위 에서 zk 를 사용 한 것 과 마찬가지 로 프로그램 설계 예상 에 부합 합 니 다.
이상 은 python 언어 를 바탕 으로 하 는 일부 코드 전시 일 뿐 두 개의 제3자 패 키 지 를 사용 하여 분포 식 자 물 쇠 를 사용 하여 병발 프로그램의 혼란 을 피 할 수 있 습 니 다.
그러나 사실은 이 중간 에 단층 이 있다.즉,이 두 도 구 는 모두 하나의 체 제 를 제공 하 는 것 이지 대외 적 으로 자 물 쇠 를 조작 하 는 API 를 제공 하 는 것 이 아니다.그러면 이 체 제 를 어떻게 이용 하여 이런 자 물 쇠 를 실현 하 는 지 하 는 것 이 바로 이 두 제3자 가 하 는 일이 다.
이들 이 실현 하 는 소스 코드 와 threading 의 일부 lock 코드 를 간단하게 보면 자물쇠 의 실현 에 있어 공통점 이 있 고 모두 통용 되 는 acquire 와 release 방법 이 있 음 을 발견 한 다음 에 enter 와 exit 를 앞의 두 가지 방법 으로 문맥 관리자 with 의 용법 을 실현 합 니 다.
그 밖 에 관계 형 데이터 베 이 스 를 이용 하여 MySQL 고유의 잠 금 체 제 를 분포 식 잠 금 으로 할 수 있 지만 데이터 베 이 스 는 시스템 의 병목 이기 때문에 불필요 한 압력 을 도입 할 필요 가 없다.이 동시에 MySQL 의 잠 금,격 리 단계 도 할 말 이 많 습 니 다.github 에서 찾 아 보 았 지만 위 에 있 는 MySQL 을 바탕 으로 하 는 대외 노출 잠 금 통용 API 의 제3자 가방 을 찾 지 못 했 기 때문에 위 에서 보 여 주지 못 했 습 니 다.
이 일 을 분명하게 말 하 는 것 은 그리 쉽 지 않다.그 후에 나 는 비교적 진정한 자 물 쇠 를 어떻게 쓰 는 지 알 고 위의 두 제3자 가방 의 구체 적 인 실현 에 대해 연 구 를 하여 이 단층 을 보충 하도록 노력 할 것 이다.그 다음 에 MySQL 기반 의 유사 한 제3자 패 키 지 를 실현 하려 고 시도 할 수 있 습 니 다.이것 은 MySQL 의 일부 메커니즘 에 대해 더욱 분명하게 해 야 합 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Python의 None과 NULL의 차이점 상세 정보그래서 대상 = 속성 + 방법 (사실 방법도 하나의 속성, 데이터 속성과 구별되는 호출 가능한 속성 같은 속성과 방법을 가진 대상을 클래스, 즉 Classl로 분류할 수 있다.클래스는 하나의 청사진과 같아서 하나의 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.