redis 의 increment()방법 으로 카운터 기능 사례 구현

redis 가 카운터 기능 을 실현 할 수 있다 는 것 을 알 고 있 었 지만 그 전에 실제 사용 한 적 이 없 었 습 니 다.어제 한 가지 수요 에 부 딪 혔 습 니 다.사용자 스 캔 당일 20 회 에 달 하면 바로 알림:당일 스 캔 횟수 가 상한 에 달 했 습 니 다!
그 때 는 redis 의 증가 방법 인 increment()를 사용 하여 카운터 기능 을 실현 할 생각 이 었 으 므 로 redisTemplate 와 stringRedisTemplate 의 사용 에 주의해 야 한다.
우선 키 설정:

이 키 는 사용자 id 와 당일 날 짜 를 키 의 일부분 으로 사 용 했 습 니 다.date:xxxx-xx-xx 형식 입 니 다.그러면 이 사용 자 는 다음날 코드 를 스 캔 할 때 또 하나의 새 키 입 니 다.날짜 가 다 르 기 때 문 입 니 다.
key 의 만 료 시간 설정:

카운터 기능 구현:



위의 방법 을 사용 하면 redis 의 카운터 기능 이 실 현 될 수 있 습 니 다.
사용 과정 에서 발생 한 문제:
사용 중 오류 가 발생 합 니 다:ERR value is not an integer or out of range
그 당시 에 제 가 사 용 했 던 방법 을 발 견 했 습 니 다.
string RedisTemplate,뒤에 get(key)을 원 할 때 방법 밑 에 있 는 템 플 릿 은 redisTemplate 를 사용 하고 뒤에 템 플 릿 의 사용 을 통일 한 다음 에 계산 합 니 다.
기기 기능 이 정상적으로 작 동 하여 더 이상 잘못 던 지지 않 습 니 다.
많은 글 을 보 았 습 니 다.직렬 화 된 냄비 라 고 합 니 다.increment 방법 은 string RedisTemplate 템 플 릿 이 어야 사용 할 수 있 습 니 다.하지만 저 는 실제 사용 할 때 도 그렇습니다.
redisTemplate 를 사 용 했 습 니 다.이 구체 적 인 이 유 는 아직 보고 있 습 니 다.이번 사용 에서 가장 중요 한 문 제 는 setKey 를 사용 할 때 사용 하 는 템 플 릿 과 key 를 가 져 올 때 사용 하 는 템 플 릿 입 니 다.
일치 해서 생 긴 것 이다.필기 로 기록 해 봐,구덩이 하 나 는 두 번 밟 지 않 아.모두 같은 문제 에 부 딪 히 면 함께 토론 하고 공부 할 수 있다.
redis:redis 카운터 와 수량 제어 인식
이 글 은 제 개인 적 으로 redis 에 대한 이해 로 여러분 의 체계 적 인 인식 redis 를 도 울 수 있 습 니 다.본 논문 의 목표 독 자 는 redis 를 사용 한 적 이 있 지만 redis 에 대해 잘 모 르 는 친구 이다.글 의 내용 은 redis 를 위주 로 하고 memcached 도 소량 언급 합 니 다.본 고 는 redis 의 디자인 목적,작업 모델,응용 장면 등 측면 에서 논술 하고 마지막 으로 구체 적 인 응용 장면 을 설명 하 며 코드 를'건어물'으로 추가 할 것 이다.
본인 의 수준 이 제한 되 어 있 음 을 감안 하여 글 에 정확 하지 않 은 내용 이 있 으 면 고 쳐 주 십시오.
redis 가 뭐 예요?
redis 는 메모리 형 데이터 메모리 로 장면 을 사용 합 니 다.
데이터베이스
캐 시
메시지 에이전트(메시지 브로커)
memcached 와 비교
memcached 는 분포 식 메모리 대상 캐 시 시스템 으로 데이터베이스 압력 을 완화 함으로써 웹 응용의 응답 속 도 를 가속 화 하려 는 의도 입 니 다.
위의 설명 은 각각 redis 와 memcached 의 홈 페이지 첫 페이지 에서 가장 눈 에 띄 는 위치 에 놓 여 있 는데 이것 도 redis 와 memcached 의 본질 적 인 차이 에 대답 했다.
redis 작업 모드
redis 의 작업 모드 는 단일 프로 세 스 입 니 다.이것 은 redis 가 하나의 cpu 커 널 에 만 사용 할 수 있다 는 것 을 의미 합 니 다.redis 는 요청 에 대한 처 리 를 직렬 로 합 니 다.동시에 몰 려 오 는 여러 요청 에 대해 redis 는 먼저 요청 을 대기 열 에 저장 하고 요청 한 선착순 으로 직렬 로 처리 합 니 다.
단일 프로 세 스 와 직렬 이라는 두 가지 특징 을 이해 하면 우리 가 redis 를 사용 할 때'장점 을 살 리 고 단점 을 피 하 는 데 도움 이 된다'.
전에 동료 가 말 했 듯 이,왜 redis 는 큰 데 이 터 를 저장 하기에 적합 하지 않 습 니까?redis 의 작업 모델 을 통 해 알 수 있 듯 이 하나,둘:큰 덩어리의 데 이 터 는 메모리 io 와 네트워크 의 io 를 포함 하여 비교적 긴 io 시간 이 필요 하 다 는 것 을 의미한다.cpu 자원 은 io 과정 에서 계속 점용 되 고 다른 요청 을 막 아서 redis 의 전체 성능 에 영향 을 줄 수 있다.
데이터 형식
redis 의 데이터 형식 에 대해 잘 알 고 있 습 니 다.주로 다음 과 같은 5 가지 가 있 습 니 다.string list hash set sorted set각종 데이터 형식의 상용 조작
string
set,get,setnx,setex,psetex
조립 하 다
증가,감소(정수 형 문자열)
비트 조작
list
입 열,출 열(이 두 명령 은 모두 차단 모드 가 있 습 니 다)
순위 에 따라 일부 요 소 를 가 져 옵 니 다.
hash
색인 설정
색인 가 져 오기
색인 값 추가/감소(정수 문자열)
모든 인덱스 값 가 져 오기
set
집합 은 수학 개념 이다.
요소 추가
요소 삭제
요소 가 집합 되 어 있 는 지 확인 합 니 다.
집합의 원소 수 가 져 오기
이차 집합
원소 이동(집합 a 에서 집합 b 로 이동)
zset
질서 있 게 집합 합 니 다.모든 요 소 는 하나의 값 을 가지 고 요 소 를 정렬 하 는 데 사 용 됩 니 다.
모으다
요소 의 rank 가 져 오기
특정한 범위 내 에 있 는 요소 의 수 를 가 져 옵 니 다.
특정한 범위 내 에 있 는 요 소 를 가 져 옵 니 다.
rank 범위 에 따라 요소 가 져 오기
실무,일,총무
redis 사 무 는 우리 가 잘 아 는 my sql 업무 와 차이 가 있 습 니 다.똑 같은 것 은 하나 또는 한 그룹의 명령 에 대한 포장 집행 입 니 다.다른 점 은 redis 업무 가 스크롤 백 할 수 없다 는 것 입 니 다.
redis 의 사 무 는 원자 성 을 가지 고 있 으 며,한 업무 의 집행 은 두 가지 결과 가 있다.
완전 집행
전혀 실행 하지 않 음
서비스 가 끊 기 면 서버 에 전기 가 끊 기 는 등 불가항력 적 인 요 소 를 제외한다.redis 사 무 는 독립 적 인 요청 으로 실행 과정 에서 다른 요청 을 막 을 수 있 습 니 다.
redis 사 무 를 실현 하 는 데 는 다음 과 같은 두 가지 방식 이 있다.
multi-exec
lua 스 크 립 트
multi-exec

127.0.0.1:6380[1]> set counter1 1
OK
127.0.0.1:6380[1]> set counter2 2
OK
127.0.0.1:6380[1]> set counter3 3
OK
127.0.0.1:6380[1]>
127.0.0.1:6380[1]>
127.0.0.1:6380[1]> multi
OK
127.0.0.1:6380[1]> incr counter1
QUEUED
127.0.0.1:6380[1]> sadd counter2 1
QUEUED
127.0.0.1:6380[1]> incr counter3
QUEUED
127.0.0.1:6380[1]> exec
1) (integer) 2
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
3) (integer) 4
위의 업무 수행 출력 을 통 해 알 수 있 듯 이,우리 의 sadd 실행 이 잘못 되 었 습 니 다.이 유 는 작업 의 데이터 형식 이 정확 하지 않 기 때 문 입 니 다.그러나 redis 는 전체 업 무 를 중단 하지 않 고 계속 실행 합 니 다.redis 가 이렇게 하 는 것 은 일리 가 있 습 니 다.참고 문헌 1 참조.
multi-exec 와 watch 의 조합 은 my sql 사무 와 유사 한 기능 을 실현 할 수 있 습 니 다.watch 의 key 가 업무 수행 전에 수정 되면 redis 는 실 무 를 포기 합 니 다.
lua 스 크 립 트
multi-exec 에 비해 lua 스 크 립 트 의 장점 은 유연성 에 있 고 일정한 네트워크 시간 소 모 를 줄 일 수 있다(왜?).
redis 의 작업 모델 을 감안 하여 lua 스 크 립 트 로 오래 걸 리 는 업 무 를 수행 하 는 것 을 권장 하지 않 습 니 다.
lua 스 크 립 트 의 실행 이 다른 요청 을 막 는 장면 을 모 의 했 습 니 다.직접 시도 해 보 세 요.
client 1
eval "local i=0; while(i<1000000) do redis.call('keys', '*'); i=i+1; end" 0
client 2
incr counter
redis 의 실제 응용
자물쇠.
형식:string
명령:setnx name alice|set name alice NX
true 로 돌아 가면 잠 금 에 성공 합 니 다.그렇지 않 으 면 잠 금 에 실패 합 니 다.
redis 의 작업 모델 을 알 게 되면 왜 redis 로 자 물 쇠 를 실현 하 는 것 이 이렇게 쉬 운 지 알 수 있 습 니 다.memcache 로 도 잠 금 을 실현 할 수 있 지만 코드 차원 이 복잡 해 야 합 니 다.memcached.ca 를 참조 하 십시오.
이벤트 큐
형식:zset
명령:zadd,zrangebyscore,zrem
순서대로 처리 해 야 할 이 벤트 를 저장 하기에 적합 합 니 다.이벤트 의 score 값 을 시간 스탬프 나 자체 증가 id 로 설정 하면 됩 니 다.왜 list 로 안 돼 요?
카운터
형식:string
명령:incr
추첨 한도액
형식:string
명령:incrby
어떤 행사 의 현금 보 너 스 는 하루 에 최대 10000 위안 만 발송 할 수 있다.다음은 이 논리의 위조 코드 입 니 다.하 나 를 보면 열 을 안다 면 이 코드 는 큰 도움 이 될 것 입 니 다.여러분 은 동시 테스트 도구 로 이 코드 를 테스트 할 수 있 습 니 다.bug 를 발견 하거나 더 좋 은 실현 방식 이 있 으 면 저 에 게- -

$key = 'max_amount';
$amountLimit = 10000;

if (!$currAmount = Redis::get($key)) {
  $currAmount = 9990;     //                 
  //    
  Redis::setnx($key, $currAmount);
}

if ($currAmount >= $amountLimit) {
  //       
}

//     
$rewardAmount = 10;
if ($rewardAmount > $amountLimit - $currAmount) {
  $rewardAmount = $amountLimit - $currAmount;
}
if (Redis::incrby($key, $rewardAmount) > $amountLimit) {
  //       
} else {
  //     
}
초기 화 는 왜 setnx 를 사용 하 는 지,set 를 사용 하면 되 나 요?
마지막 으로 왜 incrby 를 사 용 했 는 지 안 써 도 될까요?
총결산
글 의 내용 이 많 지 않 고 이른바 건어물 이 더 적다.이것 은 작가 의 수준 과 관련 이 있 고 문장의 포 지 셔 닝 과 도 관련 이 있다.세심 한 친 구 는 글 에 물음표 가 있 고 관심 이 있 는 친 구 는 생각 할 수 있다 는 것 을 알 게 되 었 을 것 이다.여러분 들 께 참고 가 될 수 있 기 를 바 랍 니 다.여러분 들 도 많이 응원 해 주시 기 바 랍 니 다.

좋은 웹페이지 즐겨찾기