python my sql 기반 간단 한 대기 열 및 크로스 오 버 잠 금
오리지널 작품, 전재 허용.전재 할 때 원본 출처 와 본 성명 을 하이퍼링크 형식 으로 표시 해 주 십시오.
다음 을 입력 하 십시오:http://yunjianfei.iteye.com/blog/
============================================================================
다 중 프로 세 스 응용 개발 을 하 는 과정 에서 여러 프로 세 스 가 같은 자원 (임계 자원) 에 접근 하 는 상황 을 만 날 수 있 습 니 다. 전역 적 인 자 물 쇠 를 추가 하여 자원 의 동기 화 접근 을 실현 해 야 합 니 다 (같은 시간 에 하나의 프로 세 스 만 자원 에 접근 할 수 있 습 니 다).
예 를 들 어:
만약 에 우리 가 my sql 로 작업 대기 열 을 실현 한다 고 가정 하면 실현 하 는 과정 은 다음 과 같다.
1. Mysql 에서 Job 표를 만 들 고 대기 열 작업 을 저장 합 니 다. 다음 과 같 습 니 다.
create table jobs(
id auto_increment not null primary key,
message text not null,
job_status not null default 0
);
message 는 작업 정 보 를 저장 하 는 데 사 용 됩 니 다. jobstatus 는 작업 상 태 를 표시 하 는데 두 가지 상태 만 있다 고 가정 합 니 다. 0: 대기 열 에서 1: 이미 대기 열 이 나 왔 습 니 다.
2. 작업 표 에 새 데 이 터 를 넣 고 줄 을 서 는 생산자 프로 세 스 가 있 습 니 다.
insert into jobs(message) values('msg1');
3. 여러 소비자 프로 세 스 가 있다 고 가정 하고 job 표 에서 줄 서기 정 보 를 가 져 오 면 다음 과 같이 해 야 합 니 다.
select * from jobs where job_status=0 order by id asc limit 1;
update jobs set job_status=1 where id = ?; -- id 는 방금 얻 은 기록 id 입 니 다.
4. 프로 세 스 를 뛰 어 넘 는 자물쇠 가 없 으 면 두 소비자 프로 세 스 가 중복 되 는 정 보 를 동시에 얻 을 수 있 고 한 메시지 가 여러 번 소 비 될 수 있 습 니 다.이런 상황 은 우리 가 보고 싶 지 않 은 것 이다. 그래서 우 리 는 프로 세 스 를 뛰 어 넘 는 자 물 쇠 를 실현 해 야 한다.
여기에 제 가 아주 좋 은 글 을 붙 였 으 니 여러분 은 참고 하 셔 도 됩 니 다.
https://blog.engineyard.com/2011/5-subtle-ways-youre-using-mysql-as-a-queue-and-why-itll-bite-you
= = = = = = = = = = = = = = = = = = = = = = = = = = = 화려 한 분할 선 = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
크로스 프로 세 스 의 잠 금 실현 에 대해 우 리 는 주로 몇 가지 실현 방식 이 있다.
1. 신 호 량
2. 파일 잠 금 fcntl
3. socket (포트 번호 바 인 딩)
4. signal
이 몇 가지 방식 은 각각 장단 점 이 있 는데 전체적으로 말 하면 앞의 두 가지 방식 이 좀 많 을 수 있 습 니 다. 여기 서 저 는 상세 하 게 말 하지 않 겠 습 니 다. 여러분 은 자 료 를 찾 아 보 셔 도 됩 니 다.
자 료 를 조사 할 때 my sql 에 자물쇠 가 실현 되 고 성능 에 대한 요구 가 높 지 않 은 응용 장면 에 적용 되 며 동시 다발 적 인 분포 식 방문 은 병목 이 있 을 수 있 습 니 다. 링크 는 다음 과 같 습 니 다.
http://dev.mysql.com/doc/refman/5.0/fr/miscellaneous-functions.html
나 는 python 으로 demo 를 실현 했다. 다음 과 같다.
파일 이름: glock. py
#!/usr/bin/env python2.7
#
# -*- coding:utf-8 -*-
#
# Author : yunjianfei
# E-mail : [email protected]
# Date : 2014/02/25
# Desc :
#
import logging, time
import MySQLdb
class Glock:
def __init__(self, db):
self.db = db
def _execute(self, sql):
cursor = self.db.cursor()
try:
ret = None
cursor.execute(sql)
if cursor.rowcount != 1:
logging.error("Multiple rows returned in mysql lock function.")
ret = None
else:
ret = cursor.fetchone()
cursor.close()
return ret
except Exception, ex:
logging.error("Execute sql \"%s\" failed! Exception: %s", sql, str(ex))
cursor.close()
return None
def lock(self, lockstr, timeout):
sql = "SELECT GET_LOCK('%s', %s)" % (lockstr, timeout)
ret = self._execute(sql)
if ret[0] == 0:
logging.debug("Another client has previously locked '%s'.", lockstr)
return False
elif ret[0] == 1:
logging.debug("The lock '%s' was obtained successfully.", lockstr)
return True
else:
logging.error("Error occurred!")
return None
def unlock(self, lockstr):
sql = "SELECT RELEASE_LOCK('%s')" % (lockstr)
ret = self._execute(sql)
if ret[0] == 0:
logging.debug("The lock '%s' the lock is not released(the lock was not established by this thread).", lockstr)
return False
elif ret[0] == 1:
logging.debug("The lock '%s' the lock was released.", lockstr)
return True
else:
logging.error("The lock '%s' did not exist.", lockstr)
return None
#Init logging
def init_logging():
sh = logging.StreamHandler()
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s -%(module)s:%(filename)s-L%(lineno)d-%(levelname)s: %(message)s')
sh.setFormatter(formatter)
logger.addHandler(sh)
logging.info("Current log level is : %s",logging.getLevelName(logger.getEffectiveLevel()))
def main():
init_logging()
db = MySQLdb.connect(host='localhost', user='root', passwd='')
lock_name = 'queue'
l = Glock(db)
ret = l.lock(lock_name, 10)
if ret != True:
logging.error("Can't get lock! exit!")
quit()
time.sleep(10)
logging.info("You can do some synchronization work across processes!")
##TODO
## you can do something in here ##
l.unlock(lock_name)
if __name__ == "__main__":
main()
main 함수 에서 l. lock (lock name, 10) 에서 10 은 timeout 을 나타 내 는 시간 이 10 초 입 니 다. 10 초 동안 자 물 쇠 를 가 져 오지 못 하면 되 돌아 와 뒤의 작업 을 수행 합 니 다.
이 demo 에 서 는 TODO 를 표시 하 는 곳 에서 소비자 가 job 표 에서 메 시 지 를 찾 는 논 리 를 여기에 둘 수 있 습 니 다.즉, 분할 선 이상 의:
3. 여러 소비자 프로 세 스 가 있다 고 가정 하고 job 표 에서 줄 서기 정 보 를 가 져 오 면 다음 과 같이 해 야 합 니 다.
select * from jobs where job_status=0 order by id asc limit 1;
update jobs set job_status=1 where id = ?; -- id 는 방금 얻 은 기록 id 입 니 다.
이렇게 하면 여러 프로 세 스 가 임계 자원 에 접근 할 때 동기 화 되 어 데이터 의 일치 성 을 확보 할 수 있다.
테스트 할 때 두 개의 glock. py 를 시작 합 니 다. 결 과 는 다음 과 같 습 니 다.
[@tj-10-47 test]# ./glock.py
2014-03-14 17:08:40,277 -glock:glock.py-L70-INFO: Current log level is : DEBUG
2014-03-14 17:08:40,299 -glock:glock.py-L43-DEBUG: The lock 'queue' was obtained successfully.
2014-03-14 17:08:50,299 -glock:glock.py-L81-INFO: You can do some synchronization work across processes!
2014-03-14 17:08:50,299 -glock:glock.py-L56-DEBUG: The lock 'queue' the lock was released.
첫 번 째 glock. py 는... 17: 08: 50 에 자 물 쇠 를 풀 었 습 니 다. 아래 의 glock. py 는 17: 08: 50 에 자 물 쇠 를 얻 었 습 니 다. 이것 이 완전히 가능 하 다 는 것 을 증명 할 수 있 습 니 다.
[@tj-10-47 test]# ./glock.py
2014-03-14 17:08:46,873 -glock:glock.py-L70-INFO: Current log level is : DEBUG
2014-03-14 17:08:50,299 -glock:glock.py-L43-DEBUG: The lock 'queue' was obtained successfully.
2014-03-14 17:09:00,299 -glock:glock.py-L81-INFO: You can do some synchronization work across processes!
2014-03-14 17:09:00,300 -glock:glock.py-L56-DEBUG: The lock 'queue' the lock was released.
[@tj-10-47 test]#
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
MySQL에서 JSON 인덱싱 - aarondfrancis사람들은 종종 MySQL로 JSON을 인덱싱할 수 없다고 말하지만 완전히 정확하지는 않습니다. MySQL로 JSON 열을 인덱싱하는 것은 완전히 가능합니다! 사람들은 종종 MySQL로 JSON을 인덱싱할 수 없다고 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.