>  기사  >  데이터 베이스  >  Redis 데이터 유형 및 애플리케이션 시나리오

Redis 데이터 유형 및 애플리케이션 시나리오

angryTom
angryTom원래의
2020-02-13 13:23:368353검색

Redis 데이터 유형 및 애플리케이션 시나리오

redis 데이터 유형 및 애플리케이션 시나리오

Redis는 문자열(문자열), 해시(해시), 목록(목록), 집합(집합) 및 zset(정렬 집합: 순서 수집)의 5가지 데이터 유형을 지원합니다.

1. String

소개: 문자열 데이터 유형은 가장 일반적으로 사용되는 간단한 키-값 유형이며 일반적인 키/값 저장이 이 범주로 분류될 수 있습니다. 값은 문자열일 뿐만 아니라 숫자일 수도 있습니다. 바이너리 안전하므로 이미지 파일의 내용을 문자열로 저장할 수 있습니다. Redis의 문자열은 memcached의 현재 기능을 완전히 실현할 수 있으며 더 효율적입니다. Memcached와 동일한 get, set, incr, decr 및 기타 작업을 제공하는 것 외에도 Redis는 다음과 같은 추가 작업도 제공합니다.

1 문자열 길이 가져오기

2. 문자열에 콘텐츠 추가

3. 문자열의 특정 부분을 설정하고 가져옵니다

4. 문자열의 특정 비트를 설정하고 가져옵니다

5. 일련의 문자열 내용을 일괄적으로 설정합니다

일반적인 명령: set, get, decr, incr, mget , 등.

응용 시나리오:

1. Memcached 및 CKV가 적용되는 모든 시나리오. 문자열과 숫자에 직접 액세스됩니다. 구조화된 데이터는 먼저 직렬화한 다음 값으로 설정해야 하며, 따라서 값을 얻은 후에는 역직렬화가 필요합니다.

2. INCR, INCRBY, DECR, DECRBY 및 기타 redis 명령을 사용하여 원자 계산 효과를 얻을 수 있습니다. 즉, 비즈니스 통계 계산 요구 사항을 실현하는 데 사용될 수 있습니다. 또한 전역적으로 고유한 ID를 생성하는 idmaker를 구현하는 데에도 사용할 수 있습니다.

3. 세션 키를 저장하고 분산 세션 시스템을 구현합니다. Redis 키는 세션 키의 자동 만료를 실현하는 데 사용되는 만료 시간을 쉽게 설정할 수 있습니다. skey를 확인할 때 먼저 uid를 기준으로 해당 redis로 라우팅합니다. skey를 얻을 수 없으면 skey가 만료된 것이므로 skey를 얻고 확인에 성공하면 다시 로그인해야 합니다. 하늘의 시간을 업그레이드할 수 있습니다.

4. nx 또는 SetNx를 설정하고, 키가 존재하지 않는 경우에만 설정하세요. 마스터를 선택하거나 분산 잠금을 구현하는 데 사용할 수 있습니다. 모든 클라이언트는 지속적으로 SetNx 마스터 myName을 사용하여 마스터에 등록하려고 시도하며 성공한 클라이언트는 지속적으로 Expire를 사용하여 만료 시간을 새로 고칩니다. 마스터가 죽으면 키는 무효화되고 나머지 노드에서 새로운 빼앗기 라운드가 발생합니다.

5. redis2.6에서 지원하는 Lua 스크립트를 사용하면 두 가지 더 안전한 분산 잠금을 구현할 수 있습니다. 하나는 프로세스가 경쟁하지만 단일 프로세스가 항상 잠금을 획득하고 처리하는 시나리오에 적합합니다. 원래 처리 프로세스가 중단되고 잠금이 만료되지 않는 한 다른 프로세스가 잠금을 획득합니다. 적극적으로 잠금을 해제할 필요가 없습니다. get,expire/pexpire,setnx ex|px의 Lua 스크립트를 통해 각 프로세스가 잠금을 획득하고 처리하는 데 적합한 시나리오를 구현했습니다. set nx ex|px를 통해 잠금을 획득한 후 먼저 get으로 판단한 후 del로 잠금을 해제해야 합니다. 그렇지 않으면 잠금이 만료되기 전에 잠금을 획득할 수 없습니다.

6. GetSet, 새 값을 설정하고 이전 값을 반환합니다. 예를 들어 카운터를 구현하려면 GetSet을 사용하여 개수를 얻고 0으로 재설정할 수 있습니다.

7. GetBit/SetBit/BitOp/BitCount, BitMap 사용 방법, 예를 들어 오늘 고유한 방문 사용자 수를 계산할 때 등록된 각 사용자는 오늘 들어오면 해당 비트를 1로 설정하고 사용합니다. BitCount. 오늘의 총 인원 수를 알려줍니다.

8. Append/SetRange/GetRange/StrLen, 확장, 교체, 가로채기 및 텍스트 길이 찾기. 이는 특정 데이터 형식에 매우 유용합니다.

구현 방법: 문자열은 기본적으로 redisObject에 의해 참조되는 문자열로 저장됩니다. incr, decr 및 기타 작업이 발생하면 계산을 위해 숫자 유형으로 변환됩니다. redisObject는 int입니다.

2. Hash

소개: 해시는 문자열과 문자열 값 간의 매핑을 저장합니다. 해시는 객체의 다양한 속성을 맵에 저장하며 객체의 특정 속성만 읽고 업데이트할 수 있습니다. 이런 방식으로 너무 긴 일부 속성은 그대로 둘 수 있습니다. 또한 서로 다른 모듈은 서로의 동시성으로 인해 덮어쓰기 충돌을 일으키지 않고 관심 있는 속성만 업데이트할 수 있습니다.

일반적으로 사용되는 명령: hget, hset, hgetall 등

응용 시나리오:

1. 사용자 정보와 같은 구조화된 데이터를 저장합니다. Memcached나 CKV에서는 사용자의 닉네임, 나이, 성별, 포인트 등의 사용자 정보를 먼저 직렬화하여 문자열 값으로 저장해야 하는데, 이때 항목 중 하나를 수정해야 합니다. , 일반적으로 값을 꺼내고 역직렬화한 후 항목의 값을 수정한 다음 직렬화하여 다시 저장해야 합니다. 이는 오버헤드를 증가시킬 뿐만 아니라 동시 작업이 가능한 상황(예: 두 개의 동시 작업에 포인트 수정이 필요한 경우)에도 적합하지 않습니다. Redis의 해시 구조를 사용하면 데이터베이스의 속성을 업데이트하는 것처럼 특정 속성 값만 수정할 수 있습니다. 아래와 같이

2. 키는 사용자 ID, 값은 맵, 이 맵의 키는 구성원의 속성 이름, 값은 속성 값입니다. 데이터는 내부 Map의 Key(Redis에서는 내부 Map의 Key를 field라고 함)를 통해 직접 수행할 수 있습니다. 즉, 키(사용자 ID) + 필드(속성 라벨)를 통해 해당 속성 데이터를 조작할 수 있습니다. 데이터를 반복적으로 저장할 필요가 없으며 직렬화 및 동시 수정 문제가 발생하지 않습니다.

3. 단, Redis는 모든 속성 데이터를 직접 얻을 수 있는 인터페이스(hgetall)를 제공한다는 점에 유의해야 합니다. 그러나 내부 Map의 구성원이 많은 경우 내부 Map 전체를 순회하는 작업이 필요합니다. Redis의 단일 스레드 모델, 이 순회 작업은 시간이 많이 걸릴 수 있으며 다른 클라이언트의 요청에 전혀 응답하지 않을 수 있으므로 특별한 주의가 필요합니다.

4. 인덱스를 구축하는 데 사용할 수 있습니다. 예를 들어, ID 외에도 User 개체를 이름으로 쿼리해야 하는 경우가 있습니다. User 개체를 삽입할 때(user:101{"id":101 설정) user:name:id 키를 사용하여 해시를 구축할 수 있습니다. ,"name":"calvin "}) 그런데 이 해시에 항목을 삽입합니다(hset user:name:id calvin 101). 이때 calvin은 해시의 키로 사용되며 값은 다음과 같습니다. 101. 이름으로 쿼리할 때 hgetuser:name:id calvin을 사용하여 calvin이라는 키에서 ID를 가져옵니다. 특정 데이터 조각을 찾기 위해 여러 인덱스를 사용해야 하는 경우 하나의 해시 키를 사용하면 여러 문자열 키를 사용하여 인덱스 값을 저장하는 것을 피할 수 있습니다.

5. HINCRBY를 사용하여 idmaker를 구현할 수도 있습니다. 문자열 유형의 idmaker와 비교하면 각 유형에는 키가 필요하고 해시 유형에는 키가 하나만 필요합니다.

구현 방법:

값에 해당하는 Redis 해시는 실제로 HashMap입니다. 해시의 멤버 수가 적을 경우 Redis는 메모리를 절약하기 위해 1차원 배열을 사용하여 콤팩트하게 저장합니다. 실제 HashMap 구조를 사용하는 대신 해당 값 redisObject의 인코딩은 zipmap입니다. 멤버 수가 증가하면 자동으로 실제 HashMap으로 변환되며 인코딩은 ht입니다.

3. List

소개: List는 양방향 Pop/Push를 지원하는 양방향 연결 목록입니다. 세상의 규칙은 일반적으로 왼쪽 끝에서 푸시, 오른쪽 끝에서 팝입니다. , 차단 버전 BLPop/BRPop도 있습니다. 고객 클라이언트는 메시지가 도착할 때까지 차단할 수 있습니다. 또한 팝업되어 클라이언트로 돌아가는 RPopLPush/BRPopLPush도 있습니다. 동시에 다른 목록으로 자신을 푸시하고 LLen은 목록의 길이를 가져옵니다. 값에 의한 연산도 있습니다: LRem(값에 따라 요소 삭제), LInsert(특정 값의 요소 앞과 뒤에 삽입), 복잡성은 O(N), N은 목록의 길이입니다. 고유하지 않으므로 모든 요소를 ​​순회하려면 Set은 O(log(N))만 사용합니다.

아래 첨자에 의한 연산: 아래 첨자는 0부터 시작하고 대기열은 왼쪽에서 오른쪽으로 계산되며 아래 첨자가 음수인 경우 오른쪽에서 왼쪽으로 계산됩니다. LSet는 아래 첨자로 요소 값을 설정합니다. LIndex는 아래 첨자로 요소를 반환합니다. LRange는 요소를 직접 반송하는 POP와 달리 목록에 아래 첨자가 있는 요소만 반환합니다. 페이징에 가장 적합합니다. 예를 들어 LTrim은 목록의 크기를 제한하며 최신 20개의 메시지만 유지합니다. 복잡도도 O(N)인데, 여기서 LSet의 N은 List의 길이, LIndex의 N은 첨자의 값, LRange의 N은 start 값 + 나열된 요소의 개수이기 때문입니다. 배열이 아닌 연결된 목록의 경우 아래 첨자는 대기열의 머리와 끝이 아닌 한 실제로 Access에서 연결된 목록을 순회해야 합니다. LTrim의 N은 제거할 요소의 수입니다.

일반적으로 사용되는 명령: lpush, rpush, lpop, rpop, lrange 등

적용 시나리오:

1. Twitter의 팔로우 목록, 팬 목록 등 다양한 목록, 최신 뉴스 순위, 각 기사에 대한 댓글 등도 Redis의 목록 구조를 사용하여 구현할 수 있습니다.

2 메시지 큐에서는 목록의 PUSH 작업을 사용하여 목록에 작업을 저장할 수 있으며, 그런 다음 작업자 스레드는 POP 작업을 사용하여 실행할 작업을 꺼냅니다. 여기의 메시지 대기열에는 확인 메커니즘이 없습니다. 소비자가 Pop에 작업을 제공하고 작업을 완료하기 전에 충돌이 발생하면 어떻게 될까요? 한 가지 해결책은 배포할 때 이를 목록과 정렬 세트로 동시에 보내는 것입니다. 사용자가 작업을 완료한 후에는 ZREM을 사용하여 작업을 제거해야 합니다. 정렬된 세트에서 정기적으로 작업을 제거하고 시간이 초과된 완료되지 않은 작업을 제거하고 목록에 다시 넣습니다. 또 다른 접근 방식은 각 작업자에 대한 추가 목록을 추가하고, 작업을 팝업할 때 RPopLPush를 사용하고, 동시에 작업자의 목록에 작업을 넣고, 완료되면 LREM을 사용하여 제거하는 것입니다. 클러스터 관리(예: 사육사)가 작업자가 사망한 것을 발견하면 작업자의 목록 내용이 기본 목록으로 반환됩니다.

3 LRANGE를 사용하면 목록 콘텐츠의 페이징 기능을 쉽게 구현할 수 있습니다.

4. 최신 N 데이터 가져오기 작업: LPUSH를 사용하여 콘텐츠 ID를 삽입하고 목록 선두에 키워드로 저장합니다. LTRIM은 목록의 항목 수를 최대 5000개로 제한하는 데 사용됩니다. 사용자가 검색해야 하는 데이터의 양이 이 캐시 용량을 초과하는 경우 요청을 데이터베이스로 보내야 합니다.

구현 방법:

Redis 목록은 역방향 검색과 순회를 지원할 수 있는 양방향 연결 목록으로 구현되어 작업이 더 편리해집니다. 그러나 일부 추가 메모리 오버헤드가 발생하고 전송을 포함하여 Redis 내부에 많은 구현이 수행됩니다. 버퍼 큐 등. 이 데이터 구조도 사용됩니다.

4. 집합

소개: 집합의 요소는 순서가 없으며 반복되지 않습니다. 중복된 요소를 Set에 넣으면 자동으로 제거됩니다.

일반적으로 사용되는 명령:

sadd, spop, smembers, sunion 등

응용 시나리오:

1. 중복 제거가 필요한 일부 목록과 세트는 구성원이 세트 컬렉션에 있는지 여부를 결정하는 중요한 인터페이스를 제공합니다. 이 목록은 제공할 수 없습니다.

2. 일부 집단 데이터는 저장될 수 있습니다. 예를 들어 Weibo 애플리케이션에서는 사용자의 모든 팔로어가 컬렉션에 저장될 수 있습니다. Redis는 또한 컬렉션에 대한 교집합, 합집합, 차이 등의 작업을 제공하므로 공통 관심, 공통 선호도 및 2급 친구와 같은 기능을 구현하는 데 매우 편리할 수 있습니다. 위의 모든 컬렉션 작업에 대해 다른 명령을 사용할 수도 있습니다. 결과를 클라이언트에 반환하거나 새 컬렉션에 저장합니다. 또 다른 예로, QQ에는 "친구 태그"라는 소셜 기능이 있습니다. "큰 아름다움", "거물", "Ouba" 등과 같은 친구를 태그할 수 있습니다. 여기서 각 사용자의 태그를 컬렉션 내에 저장할 수도 있습니다. .

3. 특정 페이지를 방문한 특정 등록 사용자 또는 IP 주소 수를 알고 싶다면 SADD page:day1: 특정 사용자 수를 확인하려면 SCARD page:day1:를 사용하세요. 특정 사용자가 이 페이지를 방문했는지 테스트해야 합니까? SISMEMBER 페이지:day1:.

구현 방법:

set의 내부 구현은 값이 항상 null인 HashMap입니다. 실제로 해시를 계산하여 빠르게 정렬됩니다. 이것이 바로 set이 멤버가 세트에 있는지 확인할 수 있는 이유입니다.

5. Sorted Set

소개: Sorted Set과 비교하여 요소를 Set에 넣을 때 해당 요소의 점수도 제공되며, 점수에 따라 자동으로 정렬될 수 있습니다.

일반적인 명령:

zadd, zrange, zrem, zcard 등

사용 시나리오:

1. 순서가 지정되고 중복되지 않는 컬렉션 목록을 저장합니다. 예를 들어 Twitter의 공개 타임라인은 게시 시간을 점수로 저장할 수 있습니다. . 이러한 방식으로 파일은 획득 시 자동으로 시간별로 정렬됩니다.

2. 예를 들어 일반 메시지의 점수는 1이고 중요한 메시지의 점수는 2입니다. 그런 다음 작업자 스레드는 점수의 역순으로 작업 작업을 가져오도록 선택할 수 있습니다. 중요한 작업의 우선순위를 정하세요.

3. 순위 관련: ZADD 리더보드 높은 점수를 받은 상위 100명의 사용자를 얻는 것은 쉽습니다: ZREVRANGE 순위표 0 99. 사용자의 글로벌 순위도 비슷합니다. ZRANK 리더보드 을 실행하세요.

4. 뉴스는 사용자 투표 및 시간에 따라 정렬됩니다. ZADD = 포인트/시간^알파 이런 식으로 사용자 투표는 그에 따라 뉴스를 파헤치지만 시간은 특정 지수에 따라 뉴스를 묻습니다.

5. 만료된 항목 처리: 목록을 시간별로 정렬하려면 Unix 시간을 핵심으로 사용하세요. 만료된 항목을 찾는 어려운 작업을 완료하려면 current_time 및 time_to_live를 검색하세요. 또 다른 백그라운드 작업은 ZRANGE...WITHSCORES를 사용하여 만료된 항목을 쿼리하고 삭제합니다.

구현 방법:

Redis 정렬 세트는 내부적으로 HashMap 및 건너뛰기 목록(SkipList)을 사용하여 데이터의 저장 및 순서를 보장하며 건너뛰기 목록은 모든 구성원을 저장합니다. HashMap에 저장된 점수는 점프 테이블 구조를 사용하여 검색 효율성을 높일 수 있으며 구현이 비교적 간단합니다.

더 많은 Redis 지식을 알고 싶다면 redis 데이터베이스 튜토리얼 칼럼을 주목해 주세요.

위 내용은 Redis 데이터 유형 및 애플리케이션 시나리오의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.