redis 사무동력 노드 자바 대학 정리
하나: 실무,일,총무
구체 적 으로 사무 가 무엇 인지,무엇 을 보증 해 야 하 는 지...이 건 말 할 필요 가 없 을 것 같 습 니 다.먼저 무작정 redis 매 뉴 얼 을 보고 마력 을 음미 하 세 요.
1. multi,exec
sqlserver 어떻게 했 는 지 기억 나 세 요?보통 이런 세 가지 절차 입 니 다.사 무 를 만 들 고 명령 을 내 리 며 사 무 를 수행 합 니 다.그 렇 죠?redis 에 대응 하 는 것 은 요?multi 는 트 랜 잭 션 을 만 들 고 redis 명령 을 입력 하 며 마지막 으로 exec 로 명령 을 수행 합 니 다.아래 와 같이:
이 를 통 해 알 수 있 듯 이 제 가 set 명령 을 마 친 후에 피드백 정 보 는 QUEUED 입 니 다.마지막 에 제 가 exec 를 실행 해 야 이 명령 들 이 진정 으로 실 행 될 수 있 습 니 다.바로 이렇게 간단 합 니 다.모든 것 이 그렇게 순 조 롭 고 조금도 질질 끌 지 않 습 니 다.어떤 사람들 은 사실 업무 중 에 rollback 작업 이 있 지만 redis 에서 보지 못 한 것 같 습 니 다.안 타 깝 게 도 redis 에 rollback 작업 이 없습니다.예 를 들 어 아래 와 같 습 니 다.
그림 에서 나 는 고의로 lpush 명령 으로 string 을 실행 했다.당연히 성공 하지 못 할 것 이 라 고 짐작 할 수 있 지만 결과 에서 당신 은 무엇 을 보 았 습 니까?두 개 OK,한 개 Error,이것 이 바로 업무 의 원자 성 을 위반 한 것 입 니 다.그런데 제 가 어떻게 반박 해 야 합 니까? reids 는 데이터 구조 서버 일 뿐 입 니 다.얼마나 간단 한 일 인지 만 걸음 물 러 나 면 분명 한 오류 명령 이 바로 돌아 올 것 입 니 다.예 를 들 어 제 가 일부러 lpush 를 lpush 1 로 썼 습 니 다.
2. watch
멀 티 뒤에 있 는 세 개의 set 명령 을 보고 나 서 뭔 가 허전 한 느낌 이 들 었 는 지 모 르 겠 습 니 다.뭐라고 해 야 할 까요?명령 이 정확 하 다 면 redis 는 함께 임 무 를 수행 할 것 을 보증 합 니 다.명령 은 함께 수행 된다 고 하지만 누가 제 가 명령 을 수행 하 는 과정 에서 다른 client 가 이 값 을 수정 하지 않 을 것 이 라 고 보증 할 수 있 습 니까?만약 이 값 들 을 수정 했다 면,나의 exec 는 또 어떤 의미 가 있 습 니까?괜찮아,이런 나 쁜 거리의 수요,redis 가 어떻게 수수방관 할 수 있 겠 어??이곳 의 watch 가 당신 을 도 울 수 있 습 니 다.
WATCH
WATCH key [key ...]
하나 이상 감시 하기 key ,만약 업무 수행 전에 이것(또는 이것들) key 다른 명령 에 의 해 변경 되면 사 무 는 중 단 될 것 이다.위 는 바로 redis 매 뉴 얼 에서 watch 에 대한 설명 입 니 다.사용 하기 가 간단 한 것 같 습 니 다.바로 제 가 multi 전에 watch 로 제 가 수정 하고 자 하 는 key 를 감시 하 는 것 입 니 다.만약 에 제 가 exec 전에 multi 이후 의 이 시간 에 key 가 다른 client 에 의 해 수정 되면 exec 는 실 패 를 하고 돌아 갑 니 다.이렇게 간단 합 니 다.제 가 예 를 들 겠 습 니 다.
2.원리 탐구
트 랜 잭 션 작업 에 관 한 소스 코드 는 대부분 redis 소스 코드 에 있 는 multi.c 입 니 다. 파일 에서 다음 에 나 는 하나씩 간단하게 분석 할 것 이다.
1. multi
redis 의 소스 코드 에 서 는 대략 이렇게 쓰 여 있 습 니 다.
void multiCommand(redisClient *c) {
if (c->flags & REDIS_MULTI) {
addReplyError(c,"MULTI calls can not be nested");
return;
}
c->flags |= REDIS_MULTI;
addReply(c,shared.ok);
이 코드 에서 멀 티 는 리 디 스 클 라 이언 트 의 REDIS 만 간단하게 볼 수 있 습 니 다.MULTI 상태 가 열 리 면 이 redis 클 라 이언 트 가 트 랜 잭 션 모드 에 들 어 갔다 는 것 을 알려 줍 니 다.2. 생 성 명령
redisClient 에 multiState 명령 이 있 습 니 다:
typedef struct redisClient {
。。。
multiState mstate; /* MULTI/EXEC state */
。。。
} redisClient;
주석 에서 도 이 명령 이 multi/exec 와 관련 이 있 는 것 을 보 았 을 것 입 니 다.다음 에 궁금 한 것 은 multiState 의 정 의 를 보 겠 습 니 다.
typedef struct multiState {
multiCmd *commands; /* Array of MULTI commands */
int count; /* Total number of MULTI commands */
int minreplicas; /* MINREPLICAS for synchronous replication */
time_t minreplicas_timeout; /* MINREPLICAS timeout as unixtime. */
} multiState;
multiState 라 는 매 거 진 에서 아래 에*command 명령 이 있 는 것 을 볼 수 있 습 니 다.주석 에서 그것 이 가리 키 는 것 은 하나의 배열 입 니 다.그것 이 바로 당신 의 몇 가지 명령 입 니 다.다음은 실제 commands 의 총 수 를 볼 수 있 는 count 가 있 습 니 다. 3. watch
뒤의 exec 를 편리 하 게 말 하기 위해 watch 가 어떻게 이 루어 졌 는 지 말씀 드 리 고 싶 습 니 다.multi.c 소스 코드 에 이렇게 쓰 여 있 습 니 다.
typedef struct watchedKey {
robj *key;
redisDb *db;
} watchedKey;
void watchCommand(redisClient *c) {
int j;
if (c->flags & REDIS_MULTI) {
addReplyError(c,"WATCH inside MULTI is not allowed");
return;
}
for (j = 1; j < c->argc; j++)
watchForKey(c,c->argv[j]);
addReply(c,shared.ok);
}
/* Watch for the specified key */
void watchForKey(redisClient *c, robj *key) {
list *clients = NULL;
listIter li;
listNode *ln;
watchedKey *wk;
/* Check if we are already watching for this key */
listRewind(c->watched_keys,&li);
while((ln = listNext(&li))) {
wk = listNodeValue(ln);
if (wk->db == c->db && equalStringObjects(key,wk->key))
return; /* Key already watched */
}
/* This key is not already watched in this DB. Let's add it */
clients = dictFetchValue(c->db->watched_keys,key);
if (!clients) {
clients = listCreate();
dictAdd(c->db->watched_keys,key,clients);
incrRefCount(key);
}
listAddNodeTail(clients,c);
/* Add the new key to the list of keys watched by this client */
wk = zmalloc(sizeof(*wk));
wk->key = key;
wk->db = c->db;
incrRefCount(key);
listAddNodeTail(c->watched_keys,wk);
}
이 코드 에서 가장 핵심 적 인 것 은:
/* This key is not already watched in this DB. Let's add it */
clients = dictFetchValue(c->db->watched_keys,key);
바로 dicFetchValue 라 는 사전 방법 을 통 해 watchedkeys 에서 지정 한 key 의 value 를 찾 았 습 니 다.이 value 는 clients 의 링크 입 니 다.이 key 에 관 한 모든 client 를 찾 고 싶 은 것 임 을 설명 합 니 다.마지막 으로 이번 key 를 redisclient 의 watched 에 넣 을 것 입 니 다.keys 사전 에서 다음 코드:
/* Add the new key to the list of keys watched by this client */
wk = zmalloc(sizeof(*wk));
wk->key = key;
wk->db = c->db;
incrRefCount(key);
listAddNodeTail(c->watched_keys,wk);
굳이 그림 을 그 려 야 한다 면 아마 그 럴 것 이다.그 중 watchedkey 는 사전 구조 입 니 다.사전 의 키 는 위의 key 1,key 2 입 니 다.value 는 client 의 링크 입 니 다.그러면 어떤 key 에서 어떤 client 에 의 해 감시 되 고 있 는 지 잘 알 고 있 습 니 다.
4.exec
이 명령 에는 대략 두 가지 일 을 했다.
<1>: 판단 c->flags=REDISDIRTY_EXEC 열 었 는 지 여부 입 니 다.그렇다면 트 랜 잭 션 discardTransaction(c)을 취소 합 니 다.즉,이 키 는 다른 client 에 의 해 수정 되 었 습 니 다.
<2>: 수정 되 지 않 았 다 면 for 는 다음 그림 의 두 가지 정보 와 같이 comannd[]의 명령 을 반복 적 으로 실행 합 니 다.
자,대충 그렇게 말씀 드 리 겠 습 니 다.도움 이 되 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Redis 해시에 대한 완벽한 가이드변경 가능하므로 필요에 따라 쉽게 변경하고 업데이트할 수 있습니다. Redis 해시는 구조가 평평하므로 JSON에서와 같이 여러 수준을 가질 수 없습니다. redis 해시의 명명 규칙은 hash:key 로 입력되므로...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.