순서 집합에 사용할 수 있는 두 가지 내부 구현, 즉 압축 목록(ziplist)과 건너뛰기 목록(skiplist)이 있습니다. 다음으로 각각에 대해 자세히 알아보겠습니다.
순서 집합의 요소 수가zset-max-ziplist-entries
(기본값은 128)보다 작고 각 요소 구성원의 길이가 다음과 같은 경우zset-max-ziplist-value
(기본값은 64바이트)보다 작으면 압축된 목록을 순서 집합의 내부 구현으로 사용합니다.zset-max-ziplist-entries
(默认为128个),并且每个元素成员的长度小于zset-max-ziplist-value
(默认为64字节)的时候,使用压缩列表作为有序集合的内部实现。
每个集合元素由两个紧挨在一起的两个压缩列表结点组成,其中第一个结点保存元素的成员,第二个结点保存元素的分支。通过按照分数的大小顺序将压缩列表中的元素依次排列在一起,可以有效地减少内存空间的使用。
举个例子,我们使用zadd
命令创建一个以压缩列表为实现的有序集合:
127.0.0.1:6379> zadd one-more-zset 1 one 2 two 3 three (integer) 3 127.0.0.1:6379> zrange one-more-zset 0 -1 1) "one" 2) "two" 3) "three" 127.0.0.1:6379> object encoding one-more-zset "ziplist"
当有序集合的元素个数大于等于zset-max-ziplist-entries
(默认为128个),或者每个元素成员的长度大于等于zset-max-ziplist-value
(默认为64字节)的时候,使用跳跃表作为有序集合的内部实现。
此时,在有序集合中其实包含了两个结构,一个是跳跃表,另一个是哈希表。
在跳跃表中,所有元素按照从小到大的顺序排列。跳跃表的结点中的object
指针指向元素成员的字符串对象,score
保存了元素的分数。通过跳跃表,Redis可以快速地对有序集合进行分数范围、排名等操作。
在哈希表中,为有序集合创建了一个从元素成员到元素分数的映射。在键值对中,键是字符串对象并指向元素成员,而值则保存了元素的分数。通过哈希表,Redis可以快速查找指定元素的分数。
虽然有序集合同时使用跳跃表和哈希表,但是这两种数据结构都使用指针共享元素中的成员和分数,不会额外的内存浪费。
举个例子,我们使用zadd
zadd
명령을 사용하여 압축 목록으로 구현된 순서 집합을 만듭니다.
127.0.0.1:6379> zadd one-more-zset 1 long-long-long-long-long-long-long-long-long-long-long-long-long-long (integer) 1 127.0.0.1:6379> zrange one-more-zset 0 -1 1) "long-long-long-long-long-long-long-long-long-long-long-long-long-long" 127.0.0.1:6379> object encoding one-more-zset "skiplist"
zset-max-ziplist-entries
보다 크거나 같거나(기본값은 128), 각 요소 멤버의 길이가
zset-max-ziplist-value<보다 크거나 같습니다. /code> (기본값은 64바이트) ), 순서 집합의 내부 구현으로 건너뛰기 목록을 사용합니다. 이때 주문한 세트에는 실제로 두 개의 구조가 포함되어 있는데, 하나는 점프 테이블이고 다른 하나는 해시 테이블입니다. 점프 목록에는 모든 요소가 작은 것부터 큰 것 순으로 배열되어 있습니다. 점프 테이블 노드의 object
포인터는 요소 멤버의 문자열 개체를 가리키며
score
는 요소의 점수를 저장합니다. 점프 테이블을 통해 Redis는 정렬된 세트에 대해 점수 범위, 순위 및 기타 작업을 신속하게 수행할 수 있습니다. 해시 테이블에서는 순서가 지정된 세트에 대해 요소 멤버십에서 요소 점수로의 매핑이 생성됩니다. 키-값 쌍에서 키는 문자열 객체이며 요소 멤버를 가리키는 반면, 값은 요소의 점수를 보유합니다. 해시 테이블을 통해 Redis는 지정된 요소의 점수를 빠르게 찾을 수 있습니다. 순서 있는 집합은 점프 테이블과 해시 테이블을 모두 사용하지만 두 데이터 구조 모두 포인터를 사용하여 추가 메모리 낭비 없이 요소의 멤버와 점수를 공유합니다. 예를 들어
zadd
명령을 사용하여 건너뛰기 목록으로 구현된 순서 집합을 만듭니다.
127.0.0.1:6379> zadd one-more-zset 1 one 2 two 3 three (integer) 3 127.0.0.1:6379> zrange one-more-zset 0 -1 1) "one" 2) "two" 3) "three" 127.0.0.1:6379> object encoding one-more-zset "ziplist"
로그인 후 복사
로그인 후 복사
내부 구현의 변환순서 집합이 압축 목록으로 구현되는 경우 내부 구현 이 정렬된 집합에 더 긴 요소 멤버가 추가되거나 이 정렬된 집합에 너무 많은 요소가 있는 경우 이 정렬된 집합은 내부 구현으로 점프 목록으로 변환됩니다. 내부 구현으로 압축 목록을 사용하는 순서 집합은 건너뛰기 목록으로 변환되지 않습니다. 예를 들어 먼저 내부 구현으로 압축된 목록을 사용하여 순서 집합을 만듭니다.
127.0.0.1:6379> zadd one-more-zset 4 long-long-long-long-long-long-long-long-long-long-long-long-long-long (integer) 1 127.0.0.1:6379> zrange one-more-zset 0 -1 1) "one" 2) "two" 3) "three" 4) "long-long-long-long-long-long-long-long-long-long-long-long-long-long" 127.0.0.1:6379> object encoding one-more-zset "skiplist"
로그인 후 복사
그런 다음 더 긴 멤버가 있는 요소를 추가하고 내부 구현으로 건너뛰기 목록으로 변환합니다.
127.0.0.1:6379> zrem one-more-zset long-long-long-long-long-long-long-long-long-long-long-long-long-long (integer) 1 127.0.0.1:6379> zrange one-more-zset 0 -1 1) "one" 2) "two" 3) "three" 127.0.0.1:6379> object encoding one-more-zset "skiplist"
로그인 후 복사
그런 다음 주문된 세트에서 더 긴 멤버의 요소를 제거합니다. 주문된 세트는 내부 구현으로 여전히 점프 목록을 사용합니다. rrreee
위 내용은 Redis에서 정렬된 컬렉션의 내부 구현을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!