Redis에 사용되는 기본 데이터 구조는 무엇입니까?


305

결정적인 목록으로 두 가지 질문에 대답하려고합니다.

  1. Redis에 사용되는 기본 데이터 구조는 무엇입니까?
  2. 그리고 각 유형의 주요 장점 / 단점 / 사용 사례는 무엇입니까?

그래서 Redis 목록은 실제로 링크 된 목록으로 구현됩니다. 그러나 다른 유형의 경우 정보를 파낼 수 없습니다. 또한 누군가 가이 질문에 걸려서 다른 데이터 구조를 수정하거나 액세스하는 장단점을 요약하지 않은 경우 특정 유형가장 잘 사용 하여 참조 할 수 있는 시기 의 전체 목록이 있습니다.

특히 문자열, 목록, 설정, zset 및 해시와 같은 모든 유형을 간략하게 설명하려고합니다.

아, 나는 지금 까지이 기사를 보았습니다.


7
서버를 사용하는 방법은 간단합니까? 한 프로그래밍 구조를 다른 프로그래밍 구조보다 언제 사용해야하는지 어떻게 알 수 있습니까? 이것은 다른 용도로 다른 유형을 사용하기 때문에 프로그래밍에 직접 적용 할 수 있습니다.
Homer6

2
서버를 사용하는 방법이 반드시 사소한 것은 아니지만 주제에 맞지 않으며 요청한 것이 아닙니다. 특정 목적으로 사용할 데이터 구조는 국소적인 것이지만 요청한 것이 아닙니다. Redis에서 사용 된 것은 사소한 것이며, 특정 상황에서 왜 특정 구조를 사용했는지에 대한 추가 추론이 없습니다. 관련이 없습니다.
Jerry Coffin

5
"데이터 구조는 무엇이며 언제 다른 유형을 사용해야합니까?" 그 주제는 어떻습니까? 연결된 목록, 해시 및 배열에 대한 학습은 프로그래밍과 관련이 없다고 말하는가? 왜냐하면 그것들은 특히 성능을 위해 특별히 설계된 서버에서 직접 관련이 있다고 주장하기 때문입니다. 또한 잘못된 선택은 한 응용 프로그램에서 다른 응용 프로그램으로의 성능이 크게 저하 될 수 있기 때문에 관련이 있습니다.
Homer6

19
antirez의 답변이이 질문을 구속합니다. 프로그래머의 손해를 입히고 사방에 사용자를 재발급하십시오.
John Sheehan

75
@JerryCoffin은 모든 것을 존중하면서 소프트웨어 개발 도구이며 소프트웨어 개발 도구에 대한 질문은 주제에 대해 확고한 질문입니다. "원본에서 답변을 얻을 수 있습니다"라는 사실은 가까운 이유가 아닙니다. 소스에서 답변을받는 데 몇 시간이 걸립니다. 그리고 redis는 매우 널리 사용 되므로이 질문은 너무 현지화되지 않았습니다. 스택 오버플로는 프로그래밍에 대해 배우고 널리 사용되는 프로그래밍 도구가 어떤 데이터 구조를 사용하여 해당 목표에 기여하는지 묻습니다. 요컨대 나는이 질문을 닫을 이유를 찾지 못했습니다.
Joel Spolsky

답변:


612

귀하의 질문에 대답하려고 노력할 것이지만, 처음에는 이상하게 보일 수있는 것부터 시작할 것입니다. Redis 내부에 관심이 없다면 데이터 유형이 내부적으로 구현되는 방법에 대해서는 신경 쓰지 않아야합니다 . 이것은 간단한 이유입니다. 모든 Redis 작업마다 문서에서 시간 복잡성을 발견 할 수 있으며, 작업 집합과 시간 복잡성이있는 경우 필요한 다른 유일한 것은 메모리 사용에 대한 단서입니다. 우리는 데이터에 따라 다양한 최적화를 수행합니다.이 후자의 수치를 얻는 가장 좋은 방법은 몇 가지 사소한 실제 테스트를 수행하는 것입니다).

그러나 요청한 이후 모든 Redis 데이터 유형의 기본 구현은 다음과 같습니다.

  • 문자열 은 C 동적 문자열 라이브러리를 사용하여 구현되므로 추가 작업에서 할당에 대해 비용을 지불하지 않습니다. 이런 식으로 우리는 예를 들어 2 차 행동 대신 O (N) 덧셈을가집니다.
  • 리스트 는 링크 된 리스트 로 구현됩니다.
  • 세트해시 는 해시 테이블로 구현됩니다.
  • 정렬 된 집합건너 뛰기 목록 (특수 유형의 균형 잡힌 나무)으로 구현됩니다.

그러나 목록, 세트 및 정렬 된 세트가 항목 수와 최대 값의 크기가 작 으면 훨씬 더 작은 다른 인코딩이 사용됩니다. 이 인코딩은 유형에 따라 다르지만, 모든 작업에 대해 O (N) 스캔을 강제로 수행하는 컴팩트 한 데이터 덩어리라는 특징이 있습니다. 작은 객체에만이 형식을 사용하므로 문제가되지 않습니다. 작은 O (N) 블로 브를 스캔하는 것은 캐시가 불명확 하므로 실제로는 매우 빠르며, 너무 많은 요소가있는 경우 인코딩이 자동으로 기본 인코딩 (링크 된 목록, 해시 등)으로 전환됩니다.

그러나 귀하의 질문은 실제로 내부에 관한 것이 아니라 요점은 무엇을 달성하기 위해 어떤 유형을 사용해야합니까? .

이것은 모든 유형의 기본 유형입니다. List는 문자열 목록이고 Set은 문자열 집합 등이기 때문에 네 가지 유형 중 하나이지만 복잡한 유형의 기본 유형이기도합니다.

Redis 문자열은 HTML 페이지를 저장하려는 모든 명백한 시나리오뿐만 아니라 이미 인코딩 된 데이터를 변환하지 않으려는 경우에 좋습니다. 예를 들어 JSON 또는 MessagePack이있는 경우 객체를 문자열로 저장할 수 있습니다. Redis 2.6에서는 Lua 스크립트를 사용하여 이러한 종류의 오브젝트 서버 측을 조작 할 수도 있습니다.

Redis는 임의의 바이트 범위 또는 단일 비트에 액세스하는 명령을 내보내므로 문자열의 또 다른 흥미로운 사용법은 비트 맵이며 일반적으로 바이트의 임의 액세스 배열입니다. 예 를 들어이 좋은 블로그 게시물을 확인하십시오 : Redis를 사용한 Fast Easy 실시간 메트릭스 .

기울기

목록은 꼬리 근처 또는 머리 근처와 같이 목록의 극단에만 닿을 때 좋습니다. 랜덤 액세스가 느리기 때문에 목록은 페이지를 매기는 데 좋지 않습니다 .O (N). 따라서 목록을 잘 사용하면 일반 대기열 및 스택 또는 동일한 소스 및 대상이있는 RPOPLPUSH를 사용하여 항목의 고리를 "회전"하는 루프에서 항목을 처리하는 것입니다.

우리는 일반적으로 상단 또는 하단 항목에만 액세스하거나 N이 작은 경우 N 항목 의 캡이 지정된 모음을 만들려는 경우에도 좋습니다 .

세트

세트는 정렬되지 않은 데이터 콜렉션이므로 항목 콜렉션이있을 때마다 유용하며 콜렉션의 존재 또는 크기를 매우 빠른 방식으로 확인하는 것이 매우 중요합니다. 집합에 대한 또 다른 멋진 점은 임의의 요소를 엿보기 또는 팝업 (SRANDMEMBER 및 SPOP 명령)을 지원한다는 것입니다.

세트는 또한 "X 사용자의 친구는 무엇입니까?"와 같은 관계를 나타내는 것이 좋습니다. 기타 등등. 그러나 이런 종류의 물건에 대한 다른 좋은 데이터 구조는 우리가 볼 수 있듯이 정렬 된 세트입니다.

집합은 교차점, 공용체 등과 같은 복잡한 연산을 지원하므로 데이터가 있고 일부 데이터를 얻기 위해 해당 데이터에 대해 변환을 수행하려는 경우 "계산"방식으로 Redis를 사용하기에 적합한 데이터 구조입니다.

작은 세트는 매우 효율적인 방식으로 인코딩됩니다.

해시

해시는 필드와 값으로 구성된 객체를 나타내는 완벽한 데이터 구조입니다. HINCRBY를 사용하여 해시 필드를 원자 적으로 증가시킬 수도 있습니다. 사용자, 블로그 게시물 또는 다른 종류의 항목 과 같은 객체 가있는 경우 JSON 또는 이와 유사한 인코딩을 사용하지 않으려는 경우 해시가 갈 수 있습니다.

그러나 작은 해시는 Redis에 의해 매우 효율적으로 인코딩되며 Redis에 개별 필드를 원자 적으로 GET, SET 또는 증분하도록 매우 빠른 방식으로 요청할 수 있습니다.

해시는 참조를 사용하여 연결된 데이터 구조를 나타내는 데 사용될 수도 있습니다. 예를 들어 lamernews.com 주석 구현을 확인하십시오.

정렬 된 세트

정렬 된 집합은 정렬 된 요소를 유지하기 위해 목록 외에 다른 유일한 데이터 구조 입니다. 정렬 된 세트로 여러 가지 멋진 것을 할 수 있습니다. 예를 들어, 웹 응용 프로그램에 모든 종류의 Top Something 목록 이있을 수 있습니다 . 점수 별 상위 사용자, 페이지 뷰별 상위 게시물, 상위 항목이지만 단일 Redis 인스턴스는 초당 수많은 삽입 및 최상위 요소 작업을 지원합니다.

일반 세트와 같이 정렬 된 세트를 사용하여 관계를 설명 할 수 있지만 항목 목록을 페이지 매김하고 순서를 기억할 수도 있습니다. 예를 들어, 정렬 된 세트를 가진 사용자 X의 친구를 기억하면 허용 된 우정 순서대로 쉽게 기억할 수 있습니다.

정렬 된 세트는 우선 순위 큐에 적합합니다.

정렬 된 세트는 목록의 중간에서 범위를 삽입, 제거 또는 가져 오는 것이 항상 빠른 더 강력한 목록과 같습니다. 그러나 그들은 더 많은 메모리를 사용하며 O (log (N)) 데이터 구조입니다.

결론

이 게시물에 정보를 제공하기를 희망하지만 http://github.com/antirez/lamernews 에서 lamernews의 소스 코드를 다운로드하고 작동 방식을 이해하는 것이 훨씬 좋습니다 . Redis의 많은 데이터 구조가 Lamer News 내부에서 사용되며 주어진 작업을 해결하기 위해 무엇을 사용해야하는지에 대한 단서가 많이 있습니다.

문법 오타가 유감입니다. 자정이 지나서 게시물을 검토하기에는 너무 피곤합니다.)


45
이것은 Redis의 유일한 저자입니다. 나는 그에게 이메일을 보냈고 답장을 요청했다. 살바토레 감사합니다. 이것은 훌륭한 정보입니다.
Homer6

58
고맙지 만, 나는 유일한 큰 공헌자가 아닙니다. Pieter
Noordhuis

1
동일한 문자열이 여러 세트에있는 경우 문자열의 단일 사본 만 저장됩니까?
sbrian

건너 뛰기 목록 만 사용하여 zscore가 O (1)에 어떻게 있습니까?
Maxime

1
건너 뛰기 목록은 적절한 균형 트리가 아니지만 건너 뛰기 목록을 "반전 된"임의 트리로 볼 수 있습니다. 구현과 레이아웃이 다른 경우에도 기본적으로 동일합니다.
antirez

80

대부분의 경우 Redis에서 사용하는 기본 데이터 구조를 이해할 필요가 없습니다. 그러나 약간의 지식은 CPU v / s 메모리 교환을 만드는 데 도움이됩니다. 또한 효율적인 방식으로 데이터를 모델링하는 데 도움이됩니다.

내부적으로 Redis는 다음 데이터 구조를 사용합니다.

  1. 사전
  2. 이중 연결 목록
  3. 건너 뛰기 목록
  4. 우편 번호 목록
  5. 정수 세트
  6. Zip 맵 (Radis 2.6부터 Zip 목록을 위해 사용되지 않음)

특정 키가 사용하는 인코딩을 찾으려면 명령을 사용하십시오 object encoding <key>.

1. 현

Redis에서 문자열을 Simple Dynamic Strings 또는 SDS라고 합니다. char *문자열의 길이와 사용 가능한 바이트 수를 접두사로 저장할 수 있는 작은 래퍼 입니다.

문자열의 길이가 저장되므로 strlen 은 O (1) 연산입니다. 또한 길이가 알려져 있으므로 Redis 문자열은 이진 안전합니다. 문자열이 널 문자 를 포함하는 것은 완벽하게 합법적입니다 .

문자열은 Redis에서 사용 가능한 가장 다양한 데이터 구조입니다. 문자열은 모두 다음과 같습니다.

  1. 텍스트를 저장할 수있는 문자열 SETGET 명령을 참조하십시오 .
  2. 이진 데이터를 저장할 수있는 바이트 배열입니다.
  3. long번호를 저장 할 수 있습니다. INCR , DECR , INCRBYDECRBY 명령을 참조하십시오 .
  4. 배열 (의 chars, ints, longs효율적인 랜덤 액세스를 허용하거나 다른 데이터 유형). SETRANGEGETRANGE 명령을 참조하십시오 .
  5. 개별 비트를 설정하거나 가져올 수 있는 비트 배열 입니다. SETBITGETBIT 명령을 참조하십시오 .
  6. 다른 데이터 구조를 구축하는 데 사용할 수있는 메모리 블록입니다. 이것은 내부적으로 ziplists 및 intset을 빌드하는 데 사용되며 적은 수의 요소를위한 작고 메모리 효율적인 데이터 구조입니다. 이에 대한 자세한 내용은 아래를 참조하십시오.

2. 사전

Redis는 다음을 위해 사전 을 사용합니다 .

  1. 키를 관련 값에 매핑하려면 값은 문자열, 해시, 집합, 정렬 집합 또는 목록 일 수 있습니다.
  2. 키를 만료 타임 스탬프에 매핑합니다.
  3. 해시, 집합 및 정렬 집합 데이터 형식을 구현합니다.
  4. Redis 명령을 해당 명령을 처리하는 함수에 매핑합니다.
  5. Redis 키를 해당 키에서 차단 된 클라이언트 목록에 매핑합니다. BLPOP을 참조하십시오 .

Redis 사전은 해시 테이블을 사용하여 구현됩니다 . 구현을 설명하는 대신 Redis 관련 사항을 설명하겠습니다.

  1. 사전 dictType은 해시 테이블의 동작을 확장하기 위해 호출 된 구조를 사용 합니다. 이 구조에는 함수 포인터가 있으므로 a) 해시 함수, b) 키 비교, c) 키 소멸자 및 d) 값 소멸자 등의 작업을 확장 할 수 있습니다.
  2. 사전은 murmurhash2를 사용합니다 . (이전에는 seed = 5381과 함께 djb2 ​​해시 함수 를 사용 했지만 해시 함수 는 murmur2로 전환되었습니다 . djb2 ​​해시 알고리즘에 대한 설명은이 질문을 참조하십시오 .)
  3. Redis는 Incremental Resizing 이라고도하는 Incremental Hashing을 사용합니다 . 사전에는 두 개의 해시 테이블이 있습니다. 사전이 터치 될 때마다 하나의 버킷이 첫 번째 (더 작은) 해시 테이블에서 두 번째로 마이그레이션됩니다. 이런 식으로 Redis는 비싼 크기 조정 작업을 방지합니다.

Set데이터 구조에는 중복이없는 보장하기 위해 사전을 사용합니다. 가 Sorted Set왜 그 점수로 된 요소에 매핑하는 사전을 사용 ZSCORE는 O (1) 연산입니다.

3. 이중 연결리스트

list데이터 형식을 사용하여 구현 이중 연결리스트 . Redis의 구현은 바로 알고리즘 교과서입니다. 유일한 변경 사항은 Redis가 길이를 목록 데이터 구조에 저장한다는 것입니다. 이는 LLEN 이 O (1) 복잡성 을 갖도록 합니다.

4. 목록 건너 뛰기

Redis는 목록 건너 뛰기 를 정렬 된 세트의 기본 데이터 구조로 사용합니다 . Wikipedia에는 ​​좋은 소개가 있습니다. William Pugh의 논문 건너 뛰기 목록 : 균형 잡힌 나무에 대한 확률 적 대안 이 더 자세합니다.

정렬 된 세트는 건너 뛰기 목록과 사전을 모두 사용합니다. 사전은 각 요소의 점수를 저장합니다.

Redis의 건너 뛰기 목록 구현은 다음과 같은 방식으로 표준 구현과 다릅니다.

  1. Redis는 중복 점수를 허용합니다. 두 개의 노드가 동일한 점수를 갖는 경우 사전 순서에 따라 정렬됩니다 .
  2. 각 노드에는 레벨 0의 후면 포인터가 있습니다.이를 통해 점수의 역순으로 요소를 순회 할 수 있습니다.

5. 우편 목록

Zip 목록은 포인터를 사용하지 않고 데이터를 인라인으로 저장한다는 점을 제외하고 이중 연결 목록과 같습니다.

이중으로 연결된 목록의 각 노드에는 3 개의 포인터가 있습니다. 하나의 정방향 포인터, 하나의 역방향 포인터 및 해당 노드에 저장된 데이터를 참조하는 하나의 포인터입니다. 포인터는 메모리 (64 비트 시스템에서 8 바이트)가 필요하므로 작은 목록의 경우 이중 연결 목록은 매우 비효율적입니다.

Zip 목록은 요소를 Redis 문자열에 순차적으로 저장합니다. 각 요소에는 요소의 길이와 데이터 유형, 다음 요소에 대한 오프셋 및 이전 요소에 대한 오프셋을 저장하는 작은 헤더가 있습니다. 이 오프셋은 앞뒤 포인터를 대체합니다. 데이터는 인라인으로 저장되므로 데이터 포인터가 필요하지 않습니다.

Zip 목록은 작은 목록, 정렬 된 세트 및 해시를 저장하는 데 사용됩니다. 정렬 된 세트는 [element1, score1, element2, score2, element3, score3]Zip 목록과 같은 목록으로 병합되어 저장됩니다. 해시는 [key1, value1, key2, value2]등 의 목록으로 편 평화됩니다 .

Zip 목록을 사용하면 CPU와 메모리를 교환 할 수 있습니다. Zip 목록은 메모리 효율적이지만 링크 된 목록 (또는 해시 테이블 / 건너 뛰기 목록)보다 많은 CPU를 사용합니다. Zip리스트에서 요소를 찾는 것은 O (n)입니다. 새 요소를 삽입하려면 메모리 재 할당이 필요합니다. 이 때문에 Redis는 작은 목록, 해시 및 정렬 된 세트에만이 인코딩을 사용합니다. 당신의 값을 변경하여이 동작을 조정할 수 <datatype>-max-ziplist-entries<datatype>-max-ziplist-value>redis.conf에. 자세한 내용은 Redis 메모리 최적화, "소규모 집계 데이터 유형의 특수 인코딩"섹션 을 참조하십시오.

ziplist.c에 대한 의견은 우수, 당신은 코드를 읽을 필요없이 완전히이 데이터 구조를 이해할 수있다.

6. Int 세트

Int Sets는 "Sorted Integer Arrays"의 이름입니다.

Redis에서 집합은 일반적으로 해시 테이블을 사용하여 구현됩니다. 작은 세트의 경우 해시 테이블은 메모리 측면에서 비효율적입니다. 집합이 정수로만 구성된 경우 배열이 더 효율적입니다.

정수 세트는 정렬 된 정수 배열입니다. 요소를 찾기 위해 이진 검색 알고리즘 이 사용됩니다. 이것은 O (log N)의 복잡성을가집니다. 이 배열에 새로운 정수를 추가하려면 메모리 재 할당이 필요할 수 있으며, 이는 큰 정수 배열의 경우 비쌀 수 있습니다.

추가 메모리 최적화로 Int Sets는 16 비트, 32 비트 및 64 비트와 같이 정수 크기가 다른 3 가지 변형이 있습니다. Redis는 요소의 크기에 따라 올바른 변형을 사용할 수있을 정도로 똑똑합니다. 새 요소가 추가되고 현재 크기를 초과하면 Redis는 자동으로 다음 크기로 요소를 마이그레이션합니다. 문자열이 추가되면 Redis는 자동으로 Int 세트를 일반 해시 테이블 기반 세트로 변환합니다.

정수 세트는 CPU와 메모리 사이의 균형입니다. Int Sets는 메모리 효율성이 뛰어나고 작은 세트의 경우 해시 테이블보다 빠릅니다. 그러나 특정 수의 요소 후에 O (log N) 검색 시간과 메모리 재 할당 비용이 너무 커집니다. 실험을 기반으로 일반 해시 테이블로 전환하기위한 최적의 임계 값은 512로 나타났습니다. 그러나 응용 프로그램의 요구에 따라이 임계 값을 늘릴 수 있습니다 (이는 말이되지 않습니다). set-max-intset-entriesredis.conf를 참조하십시오 .

7. 우편 번호

Zip 맵은 사전으로 정리되어 목록에 저장됩니다. 그들은 우편 목록과 매우 유사합니다.

Zip지도는 Redis 2.6부터 더 이상 사용되지 않으며 작은 해시가 Zip 목록에 저장됩니다. 이 인코딩에 대한 자세한 내용은 zipmap.c주석을 참조하십시오 .


2

Redis는 값을 가리키는 키를 저장합니다. 키는 합리적인 크기의 이진 값일 수 있습니다 (가독성 및 디버깅 목적으로 짧은 ASCII 문자열을 사용하는 것이 좋습니다). 값은 5 가지 기본 Redis 데이터 유형 중 하나입니다.

1.strings-최대 512MB의 이진 안전 바이트 시퀀스

2. 해시 — 키 값 쌍의 모음

3.lists — 삽입 순서의 문자열 모음

4.sets — 순서가없는 고유 한 문자열 모음

5. 정렬 세트 — 사용자 정의 점수에 따라 주문 된 고유 한 문자열 모음

Redis 문자열은 일련의 바이트입니다.

Redis의 문자열은 바이너리 안전 (특별한 종료 문자에 의해 알려진 길이가 아님)을 의미하므로 한 문자열에 최대 512MB를 저장할 수 있습니다.

문자열은 표준 "키 값 저장소"개념입니다. 키와 값이 모두 텍스트 또는 이진 문자열 인 값을 가리키는 키가 있습니다.

문자열에 대한 모든 가능한 작업은 http://redis.io/commands/#string을 참조하십시오.

해시

Redis 해시는 키 값 쌍의 모음입니다.

Redis 해시는 많은 키 값 쌍을 보유하며 각 키와 값은 문자열입니다. Redis 해시는 복잡한 값을 직접 지원하지 않습니다 (즉, 해시 필드에 목록 또는 세트 값 또는 다른 해시 값을 가질 수 없음). 그러나 해시 필드를 사용하여 다른 최상위 복합 값을 가리킬 수 있습니다. 해시 필드 값에서 수행 할 수있는 유일한 특수 작업은 숫자 내용의 원자 단위 증감입니다.

Redis 해시는 직접 객체 표현과 많은 작은 값을 컴팩트하게 저장하는 방법으로 생각할 수 있습니다.

직접 객체 표현은 이해하기 쉽습니다. 객체에는 이름 (해시 키)과 값이있는 내부 키 모음이 있습니다. 예를 보려면 아래 예를 참조하십시오.

해시를 사용하여 많은 작은 값을 저장하는 것은 영리한 Redis 대규모 데이터 저장 기술입니다. 해시에 적은 수의 필드 (~ 100)가있는 경우 Redis는 전체 해시의 저장 및 액세스 효율성을 최적화합니다. Redis의 작은 해시 스토리지 최적화는 흥미로운 동작을 발생시킵니다. 문자열 값을 가리키는 10,000 개의 최상위 레벨 키를 가지지 않고 각각 100 개의 내부 키와 값을 갖는 100 개의 해시를 갖는 것이 더 효율적입니다. 이 방법으로 Redis 해시를 사용하여 데이터 스토리지를 최적화하려면 데이터가 끝나는 위치를 추적하는 데 추가 프로그래밍 오버 헤드가 필요하지만 데이터 스토리지가 주로 문자열 기반 인 경우이 이상한 트릭을 사용하여 많은 메모리 오버 헤드를 절약 할 수 있습니다.

해시에 대한 모든 가능한 작업은 해시 문서를 참조하십시오.

기울기

Redis 목록은 연결된 목록처럼 작동합니다.

목록의 머리 또는 꼬리에서 목록을 삽입, 삭제 및 탐색 할 수 있습니다.

값을 삽입 한 순서대로 유지해야 할 때 목록을 사용하십시오. Redis는 필요한 경우 임의의 목록 위치에 삽입 할 수있는 옵션을 제공하지만 시작 위치에서 멀리 삽입하면 삽입 성능이 저하됩니다.

Redis 목록은 종종 생산자 / 소비자 대기열로 사용됩니다. 목록에 항목을 삽입 한 다음 목록에서 항목을 팝업하십시오. 소비자가 요소가없는 목록에서 팝업을 시도하면 어떻게됩니까? Redis에 요소가 나타날 때까지 기다렸다가 추가되면 즉시 요소를 반환하도록 요청할 수 있습니다. 이는 Redis를 실시간 메시지 대기열 / 이벤트 / 작업 / 작업 / 알림 시스템으로 만듭니다.

목록 끝에서 요소를 원자 적으로 제거하여 목록을 스택 또는 대기열로 취급 할 수 있습니다.

삽입 할 때마다 목록을 특정 크기로 자르면 고정 길이 목록 (캡 모음)을 유지할 수도 있습니다.

목록에서 가능한 모든 작업은 목록 문서를 참조하십시오.

세트

Redis 세트는 세트입니다.

Redis 세트에는 각 문자열이 세트당 한 번만 존재하는 순서가없는 고유 한 Redis 문자열이 포함됩니다. 동일한 요소를 세트에 10 번 추가하면 한 번만 표시됩니다. 세트는 중복 요소가 누적되어 공간을 낭비하지 않고 적어도 한 번 이상 존재하는 것을 게으르게 보장하는 데 좋습니다. 이미 존재하는지 확인하지 않고도 원하는만큼 동일한 문자열을 추가 할 수 있습니다.

세트는 세트에서 멤버의 멤버쉽 확인, 삽입 및 삭제에 빠릅니다.

세트는 예상 한대로 효율적인 세트 작업을 수행합니다. 한 번에 여러 집합의 합집합, 교집합 및 차이를 취할 수 있습니다. 결과를 발신자에게 반환하거나 나중에 사용할 수 있도록 결과를 새 세트에 저장할 수 있습니다.

세트는 멤버십 확인 (목록과 달리)에 대한 일정한 시간 액세스 권한을 가지며, Redis는 편리한 무작위 멤버 제거 및 리턴 ( "세트에서 임의의 요소를 팝")하거나 대체하지 않고 리턴하는 임의 멤버를 갖습니다 ( "임의의 30 명의 고유 한 사용자 30 명 제공" ") 또는 교체 ("7 장의 카드를 주지만, 선택한 후에는 다시 샘플링 할 수 있도록 카드를 다시 넣습니다 ").

세트에서 가능한 모든 조작은 sets docs를 참조하십시오 .

정렬 된 세트

Redis 정렬 세트는 사용자 정의 순서가있는 세트입니다.

간단하게 정렬 된 집합을 고유 한 요소가있는 이진 트리로 생각할 수 있습니다. Redis 정렬 세트는 실제로 스킵 목록 입니다. 요소의 정렬 순서는 각 요소의 점수에 의해 정의됩니다.

정렬 된 세트는 여전히 세트입니다. 요소는 세트에서 한 번만 나타날 수 있습니다. 고유성을 위해 요소는 문자열 내용으로 정의됩니다. 정렬 점수가 3 인 "apple"요소를 삽입 한 다음 정렬 점수가 500 인 "apple"요소를 삽입하면 정렬 된 세트에 정렬 점수가 500 인 하나의 "apple"요소가 생성됩니다. 세트는 (스코어, 데이터) 쌍이 아닌 데이터를 기반으로 한 고유 한 것입니다.

데이터 모델이 고유성에 대한 요소의 점수가 아닌 문자열 내용에 의존하는지 확인하십시오. 점수는 반복 될 수 있지만 (또는 0), 마지막으로 세트 요소는 정렬 된 세트당 한 번만 존재할 수 있습니다. 예를 들어, 로그인의 신기원과 사용자 ID 값을 점수화하여 모든 사용자 로그인의 히스토리를 정렬 된 세트로 저장하려고하면 모든 사용자의 마지막 로그인 신기원 만 저장하게됩니다. 세트는 원하는 크기의 userbase * 로그인이 아닌 userbase 크기로 커집니다.

요소가 점수와 함께 세트에 추가됩니다. 언제든지 요소의 점수를 업데이트 할 수 있으며 새 점수로 요소를 다시 추가하기 만하면됩니다. 점수는 부동 소수점 배가로 표시되므로 필요한 경우 고정밀 타임 스탬프의 세분성을 지정할 수 있습니다. 여러 요소가 같은 점수를 가질 수 있습니다.

몇 가지 다른 방식으로 요소를 검색 할 수 있습니다. 모든 것이 정렬되었으므로 가장 낮은 점수에서 시작하는 요소를 요청할 수 있습니다. 최고 점수에서 시작하는 요소를 요청할 수 있습니다 ( "역순"). 정렬 점수를 기준으로 자연 또는 역순으로 요소를 요청할 수 있습니다.

정렬 된 집합에 대한 모든 가능한 작업은 정렬 된 집합 문서를 참조하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.