찾다
데이터 베이스Redisredis 연구 노트 목록 원칙

list 기본 기능

입니다. 을 반환합니다.
Command Description
BLPOP 키 1,키2,... 시간 초과 제거 목록의 첫 번째 요소 를 가져옵니다. 목록에 요소가 없으면 대기 시간이 초과되거나 요소가 표시될 때까지 목록이 차단됩니다.
BRPOP key1 [key2 ] timeout 목록에서 마지막 요소를 가져오세요. 대기 시간이 초과되거나 팝 가능한 요소가 발견될 때까지 나열합니다.
BRPOPLPUSH 소스 대상 시간 초과 목록에서 값을 팝하고, 팝된 요소를 다른 목록에 삽입하고, 목록에 요소가 없으면 반환합니다. 대기 시간이 초과되거나 팝업 가능한 요소가 발견될 때까지.
LIndex key index 通过索引获取列表中的元素
Linsert key before/after pivot value 在列表的元素前或者后插入元素
LLEN key 获取列表长度
LPOP key 移出并获取列表的第一个元素ㅋㅋㅋ
기존 목록의 헤드에 값을 삽입합니다 LRANGE 키 삭제 중지
목록의 지정된 범위에 있는 요소를 가져옵니다 LREM 키 count value
목록 요소 제거 LSET 키 인덱스 값
목록 요소의 값을 인덱스로 설정 LTRIM 키 시작 중지 목록 정리는 목록이 지정된 범위 내의 요소만 유지하고 지정된 범위 내에 없는 모든 요소가 삭제됨을 의미합니다. 인덱스는 0부터 시작하며 범위는 0부터 시작됩니다.
RPOP key 는 목록에서 마지막 요소를 제거하고 반환 값은 제거된 요소
RPOPPUSH 소스 대상 목록의 마지막 요소 를 제거하고 해당 요소를 다른 목록에 추가하고
RPUSH 키 값1 값2 …… 하나 추가 또는 목록 끝에 더 많은 값
RPUSHX 키 값 기존 목록에 값 추가

차트 출처: https://www.cnblogs.com/amyzhu/p/13466311.html

Singly linked list

redis의 목록 구현을 배우기 전에 살펴보겠습니다. 먼저 단일 연결 목록을 구현하는 방법:

각 노드에는 다음 노드를 가리키는 역방향 포인터(참조)가 있고, 마지막 노드는 끝을 나타 내기 위해 NULL을 가리키며, 노드를 가리키는 헤드 포인터가 있습니다. 시작을 나타내는 첫 번째 노드입니다.

redis 연구 노트 목록 원칙

이와 유사하지만 신규 및 삭제된 항목만 필요합니다 O(1)O(1),但是查找需要 O(n), 검색에는 O(n)

시간; 역방향 검색은 불가능하며 시작해야 합니다. 놓치면 처음부터 .

🎜노드 추가: 🎜🎜

redis 연구 노트 목록 원칙

노드 삭제:

redis 연구 노트 목록 원칙

이중 연결 목록

이중 연결 목록은 이중 연결 목록이라고도 합니다. 각 데이터 노드의 유형입니다. 에는 직계 후임자와 직계 전임자를 각각 가리키는 두 개의 포인터가 있습니다. 따라서 이중 연결 목록의 모든 노드에서 시작하면 이전 노드와 후속 노드에 쉽게 액세스할 수 있습니다.

redis 연구 노트 목록 원칙

특징:

  1. 노드가 삽입되거나 삭제될 때마다 2개가 아닌 4개의 노드 참조를 처리해야 합니다.

  2. 비교합니다. 단방향 연결 리스트라면 확실히 더 많은 메모리 공간을 차지하게 됩니다.

  3. 처음부터 끝까지 순회할 수 있고, 끝에서 선두까지 순회할 수도 있습니다

이는 이전과 이후 모두 구현될 수 있는 Redis의 문제를 해결한 것으로 보입니다. 이는 순회 문제입니다.

그럼 redis의 링크드 리스트 를 살펴보겠습니다. 처리 방법:

redis 연구 노트 목록 원칙

구조 정의 소스 코드를 살펴보겠습니다.

ListNode:

typedef struct listNode
{
    // 前驱节点
    struct listNode *prev;
    // 后继节点
    struct listNode *next;
    // 节点的值
    void *value;
} listNode;

List:

typedef struct listNode
{
    // 表头节点
    listNode *head;
    // 表尾节点
    listNode *tail;
    // 链表所包含的节点数量
    unsigned long len;
    // 节点值复制函数
    void *(*dup)(void *ptr);
    // 节点值释放函数
    void *(*free)(void *ptr);
    // 节点值对比函数
    int (*match)(void *ptr,void *key)
} list;

redis 연결 목록의 특징:

  • 순환: 연결리스트 노드 전륜 구동의 경우 후속 포인터로 노드의 선행 노드와 후속 노드를 얻는 시간 복잡도는 O(1)입니다. 헤드 노드의 선행 포인터와 테일 노드의 후속 포인터는 모두 NULL을 가리키고 다음 노드에 액세스합니다. 연결된 목록은 NULL로 끝납니다.

  • Length 카운터: List 구조의 len 속성을 통해 노드 수를 얻는 시간 복잡도는 O(1)입니다.

리스트에는 여전히 불연속적인 메모리 할당과 메모리 조각화 문제가 있는데, 메모리를 최적화할 수 있는 방법이 있나요?

redis 압축 목록

ZipList는 기본 데이터 구조가 아니며 Redis 자체에서 설계한 데이터 저장 구조입니다. 이는 연속적인 메모리 공간을 통해 데이터를 저장하는 배열과 다소 유사합니다.

배열과 달리 저장된 목록 요소가 다른 메모리 공간을 차지할 수 있습니다. 압축이라는 단어를 들으면 누구나 가장 먼저 생각할 수 있는 것은 메모리 절약입니다. 이 저장 구조가 메모리를 절약하는 이유는 배열과 비교되기 때문입니다.

우리 모두는 배열이 각 요소에 대해 동일한 크기의 저장 공간을 필요로 한다는 것을 알고 있습니다. 서로 다른 길이의 문자열을 저장하려면 최대 길이의 문자열이 차지하는 저장 공간을 문자열의 각 요소로 사용해야 합니다. 배열 공간의 크기입니다(50바이트인 경우).

그래서 문자수 값에 길이가 50바이트 미만인 문자열을 저장하면 저장 공간의 일부가 낭비됩니다.

array의 장점은 연속적인 공간을 차지하고 CPU 캐시를 잘 활용하여 데이터에 빠르게 액세스할 수 있다는 것입니다.

배열의 이러한 장점을 유지하고 저장 공간을 절약하려면 배열을 압축하면 됩니다.

redis 연구 노트 목록 원칙

그러나 압축된 목록을 순회할 때 알 수 없는 문제가 있습니다. 각 요소가 차지하는 메모리 크기는 얼마이므로 다음 요소의 구체적인 시작 위치를 계산하는 것은 불가능합니다.

그런데 생각해보니, 각 요소에 접근하기 전에 각 요소의 길이를 알 수 있다면 이 문제가 해결되지 않을까요?

redis 연구 노트 목록 원칙

다음으로 Redis가 어떻게 배열의 장점을 유지하면서 메모리를 절약하면서 ZipList를 구현하여 이들을 결합하는지 살펴보겠습니다.

redis 연구 노트 목록 원칙

  • zlbytes:压缩列表的字节长度,是uint32_t类型,占4字节,因此压缩列表最多有232-1字节,可以通过该值计算zlend的位置,也可以在内存重新分配的时候使用。

  • zltail:压缩列表尾元素相对于压缩列表起始地址的偏移量,是uint32_t类型,占4字节,可以通过该值快速定位到列表尾元素的位置。

  • zllen:压缩列表元素的个数,是uint16_t类型,占2字节,表示最多存储的元素个数为216-1=65 535,如果需要计算总数量,则需要遍历整个压缩列表。

  • entryx:压缩列表存储的元素,既可以是字节数组,也可以是整数,长度不限。

  • zlend:压缩列表的结尾,是uint8_t类型,占1字节,恒为0xFF。

  • previous_entry_length:表示前一个元素的字节长度,占1字节或者5字节,当前元素的长度小于254时用1字节,大于等于254时用5字节,previous_entry_length 字段的第一个字节固定是0xFE,后面的4字节才是真正的前一个元素的长度。

  • encoding:表示元素当前的编码,有整数或者字节数。为了节省内存,encoding字段长度可变。

  • content:表示当前元素的内容。

ZipList变量的读取和赋值都是通过宏来实现的,代码片段如下:

//返回整个压缩列表的总字节
#define ZIPLIST_BYTES(zl)       (*((uint32_t*)(zl)))

//返回压缩列表的tail_offset变量,方便获取最后一个节点的位置
#define ZIPLIST_TAIL_OFFSET(zl) (*((uint32_t*)((zl)+sizeof(uint32_t))))

//返回压缩列表的节点数量
#define ZIPLIST_LENGTH(zl)      (*((uint16_t*)((zl)+sizeof(uint32_t)*2)))

//返回压缩列表的表头的字节数
//(内存字节数zlbytes,最后一个节点地址ztail_offset,节点总数量zllength)
#define ZIPLIST_HEADER_SIZE     (sizeof(uint32_t)*2+sizeof(uint16_t))

//返回压缩列表最后结尾的字节数
#define ZIPLIST_END_SIZE        (sizeof(uint8_t))

//返回压缩列表首节点地址
#define ZIPLIST_ENTRY_HEAD(zl)  ((zl)+ZIPLIST_HEADER_SIZE)

//返回压缩列表尾节点地址
#define ZIPLIST_ENTRY_TAIL(zl)  ((zl)+intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl)))

//返回压缩列表最后结尾的地址
#define ZIPLIST_ENTRY_END(zl)   ((zl)+intrev32ifbe(ZIPLIST_BYTES(zl))-1)


对此,可以通过定义的结构体和对应的操作定义知道大概 redis 设计 压缩list 的思路;

这种方式虽然节约了空间,但是会存在每次插入和创建存在内存重新分配的问题。

quicklist

quicklist是Redis 3.2中新引入的数据结构,能够在时间效率和空间效率间实现较好的折中。Redis中对quciklist的注释为A doubly linked list of ziplists。顾名思义,quicklist是一个双向链表,链表中的每个节点是一个ziplist结构。quicklist可以看成是用双向链表将若干小型的ziplist连接到一起组成的一种数据结构。

当ziplist节点个数过多,quicklist退化为双向链表,一个极端的情况就是每个ziplist节点只包含一个entry,即只有一个元素。当ziplist元素个数过少时,quicklist可退化为ziplist,一种极端的情况就是quicklist中只有一个ziplist节点。

redis 연구 노트 목록 원칙

redis 연구 노트 목록 원칙


quicklist 结构定义:

typedef struct quicklist {
    // 指向quicklist的首节点
    quicklistNode *head;
    // 指向quicklist的尾节点
    quicklistNode *tail;
    // quicklist中元素总数
    unsigned long count;        /* total count of all entries in all ziplists */
    // quicklistNode节点个数
    unsigned long len;          /* number of quicklistNodes */
    // ziplist大小设置,存放list-max-ziplist-size参数的值
    int fill : 16;              /* fill factor for individual nodes */
    // 节点压缩深度设置,存放list-compress-depth参数的值
    unsigned int compress : 16; /* depth of end nodes not to compress;0=off */
    unsigned int bookmark_count: 4;
    quicklistBookmark bookmarks[];
} quicklist;

typedef struct quicklistBookmark {
    quicklistNode *node;
    char *name;
} quicklistBookmark;

quicklistNode定义如下:

typedef struct quicklistNode {
    struct quicklistNode *prev;
    struct quicklistNode *next;
    unsigned char *zl;
    unsigned int sz;             /* ziplist size in bytes */
    unsigned int count : 16;     /* count of items in ziplist */
    unsigned int encoding : 2;   /* RAW==1 or LZF==2 */
    unsigned int container : 2;  /* NONE==1 or ZIPLIST==2 */
    unsigned int recompress : 1; /* was this node previous compressed? */
    unsigned int attempted_compress : 1; /* node can't compress; too small */
    unsigned int extra : 10; /* more bits to steal for future usage */
} quicklistNode;

redis为了节省内存空间,会将quicklist的节点用LZF压缩后存储,但这里不是全部压缩,可以配置compress的值,compress为0表示所有节点都不压缩,否则就表示从两端开始有多少个节点不压缩;compress如果是1,表示从两端开始,有1个节点不做LZF压缩。compress默认是0(不压缩),具体可以根据你们业务实际使用场景去配置。

redis 的配置文件可以配置该参数

list-compress-depth 0

가치 의미
0 특수 값은 압축이 없음을 의미합니다.
1 퀵리스트의 각 끝에는 압축되지 않은 노드가 1개 있고, 중간 노드는 압축되어 있습니다.
2 퀵리스트의 각 끝에는 2개의 노드가 있습니다. 압축되지 않고 중간 노드가 압축됩니다
n quicklist 퀵리스트의 각 끝에는 압축되지 않은 n개의 노드가 있으며, 중간에 있는 노드는 압축되어 있습니다.


각 퀵노드 노드의 최대 용량을 의미하는 채우기 필드도 있습니다. 기본값은 -2입니다. ;

list-max-ziplist-size -2

  • 값이 양수이면 QuicklistNode 노드의 ziplist 길이를 나타냅니다. 예를 들어 값이 5인 경우 각 QuicklistNode 노드의 ziplist에는 최대 5개의 데이터 항목이 포함됩니다.

  • 값이 음수인 경우 QuicklistNode 노드의 ziplist 길이는 다음과 같습니다. 바이트 수에 따라 제한됩니다. 가능한 값은 -1 ~ -5입니다.

의미
-1 Ziplist 노드 최대 크기는 4kb
- 2 최대 ziplist 노드는 8kb
-3 최대 ziplist 노드는 16kb
-4 ziplist 노드 최대 크기는 32kb입니다
-5 ziplist 노드 최대 크기는 64kb

왜 구성이 제공되나요?

  • ziplist가 짧을수록 더 많은 메모리 조각이 발생하여 저장 효율성에 영향을 미칩니다. ziplist가 하나의 요소만 저장하는 경우 퀵리스트는 이중 연결 목록으로 변질됩니다. ziplist가 길수록 ziplist에 큰 연속 메모리 공간을 할당하기가 더 어려워지고 이로 인해 많은 작은 메모리 공간 블록이 차지하게 됩니다. . 낭비, 퀵리스트에 노드가 하나만 있고 모든 요소가 ziplist에 저장되면 퀵리스트는 ziplist로 변질됩니다

  • 결론

우리는 소스 코드를 완전히 이해하지 못하지만 이 기사를 통과할 수도 있습니다. Redis의 디자인 아이디어에 대해 알아봅시다. 그리고 그것이 어떻게 단계별로 최적화되는지 알아보세요. 성능에 대한 일반적인 아이디어를 얻으십시오.

위 내용은 redis 연구 노트 목록 원칙의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명
이 기사는 Golang菜鸟에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제
NOSQL 이해 : Redis의 주요 기능NOSQL 이해 : Redis의 주요 기능Apr 13, 2025 am 12:17 AM

Redis의 주요 기능에는 속도, 유연성 및 풍부한 데이터 구조 지원이 포함됩니다. 1) 속도 : Redis는 메모리 내 데이터베이스이며, 읽기 및 쓰기 작업은 거의 순간적이며 캐시 및 세션 관리에 적합합니다. 2) 유연성 : 복잡한 데이터 처리에 적합한 문자열, 목록, 컬렉션 등과 같은 여러 데이터 구조를 지원합니다. 3) 데이터 구조 지원 : 다양한 비즈니스 요구에 적합한 문자열, 목록, 컬렉션, 해시 테이블 등을 제공합니다.

REDIS : 기본 기능을 식별합니다REDIS : 기본 기능을 식별합니다Apr 12, 2025 am 12:01 AM

Redis의 핵심 기능은 고성능 인 메모리 데이터 저장 및 처리 시스템입니다. 1) 고속 데이터 액세스 : Redis는 메모리에 데이터를 저장하고 마이크로 초 수준 읽기 및 쓰기 속도를 제공합니다. 2) 풍부한 데이터 구조 : 문자열, 목록, 컬렉션 등을 지원하며 다양한 응용 프로그램 시나리오에 적응합니다. 3) 지속성 : RDB 및 AOF를 통해 디스크에 데이터를 지속하십시오. 4) 구독 게시 : 메시지 대기열 또는 실시간 통신 시스템에서 사용할 수 있습니다.

Redis : 인기있는 데이터 구조에 대한 안내서Redis : 인기있는 데이터 구조에 대한 안내서Apr 11, 2025 am 12:04 AM

Redis는 다음을 포함하여 다양한 데이터 구조를 지원합니다. 1. String, 단일 값 데이터 저장에 적합합니다. 2. 큐 및 스택에 적합한 목록; 3. 비면성 데이터 저장에 사용되는 세트; 4. 순서, 순위 목록 및 우선 순위 대기열에 적합한 순서 세트; 5. 해시 테이블, 객체 또는 구조화 된 데이터를 저장하는 데 적합합니다.

Redis 카운터를 구현하는 방법Redis 카운터를 구현하는 방법Apr 10, 2025 pm 10:21 PM

Redis Counter는 Redis Key-Value Pair 스토리지를 사용하여 다음 단계를 포함하여 계산 작업을 구현하는 메커니즘입니다. 카운터 키 생성, 카운트 증가, 카운트 감소, 카운트 재설정 및 카운트 얻기. Redis 카운터의 장점에는 빠른 속도, 높은 동시성, 내구성 및 단순성 및 사용 편의성이 포함됩니다. 사용자 액세스 계산, 실시간 메트릭 추적, 게임 점수 및 순위 및 주문 처리 계산과 같은 시나리오에서 사용할 수 있습니다.

Redis 명령 줄을 사용하는 방법Redis 명령 줄을 사용하는 방법Apr 10, 2025 pm 10:18 PM

Redis Command Line 도구 (Redis-Cli)를 사용하여 다음 단계를 통해 Redis를 관리하고 작동하십시오. 서버에 연결하고 주소와 포트를 지정하십시오. 명령 이름과 매개 변수를 사용하여 서버에 명령을 보냅니다. 도움말 명령을 사용하여 특정 명령에 대한 도움말 정보를 봅니다. 종금 명령을 사용하여 명령 줄 도구를 종료하십시오.

Redis 클러스터 모드를 구축하는 방법Redis 클러스터 모드를 구축하는 방법Apr 10, 2025 pm 10:15 PM

Redis Cluster Mode는 Sharding을 통해 Redis 인스턴스를 여러 서버에 배포하여 확장 성 및 가용성을 향상시킵니다. 시공 단계는 다음과 같습니다. 포트가 다른 홀수 redis 인스턴스를 만듭니다. 3 개의 센티넬 인스턴스를 만들고, Redis 인스턴스 및 장애 조치를 모니터링합니다. Sentinel 구성 파일 구성, Redis 인스턴스 정보 및 장애 조치 설정 모니터링 추가; Redis 인스턴스 구성 파일 구성, 클러스터 모드 활성화 및 클러스터 정보 파일 경로를 지정합니다. 각 redis 인스턴스의 정보를 포함하는 Nodes.conf 파일을 작성합니다. 클러스터를 시작하고 Create 명령을 실행하여 클러스터를 작성하고 복제본 수를 지정하십시오. 클러스터에 로그인하여 클러스터 정보 명령을 실행하여 클러스터 상태를 확인하십시오. 만들다

Redis 대기열을 읽는 방법Redis 대기열을 읽는 방법Apr 10, 2025 pm 10:12 PM

Redis의 대기열을 읽으려면 대기열 이름을 얻고 LPOP 명령을 사용하여 요소를 읽고 빈 큐를 처리해야합니다. 특정 단계는 다음과 같습니다. 대기열 이름 가져 오기 : "큐 :"와 같은 "대기열 : my-queue"의 접두사로 이름을 지정하십시오. LPOP 명령을 사용하십시오. 빈 대기열 처리 : 대기열이 비어 있으면 LPOP이 NIL을 반환하고 요소를 읽기 전에 대기열이 존재하는지 확인할 수 있습니다.

Redis Cluster ZSET 사용 방법Redis Cluster ZSET 사용 방법Apr 10, 2025 pm 10:09 PM

Redis 클러스터에서 ZSET 사용 : ZSET은 요소를 점수와 연관시키는 순서 컬렉션입니다. 샤딩 전략 : a. 해시 샤딩 : ZSET 키에 따라 해시 값을 배포하십시오. 비. 범위 샤딩 : 요소 점수에 따라 범위로 나누고 각 범위를 다른 노드에 할당합니다. 작업 읽기 및 쓰기 작업 : a. 읽기 작업 : ZSET 키가 현재 노드의 샤드에 속하는 경우 로컬로 처리됩니다. 그렇지 않으면 해당 샤드로 라우팅됩니다. 비. 쓰기 작업 : 항상 ZSET 키를 들고있는 파편으로 라우팅합니다.

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
4 몇 주 전By尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

안전한 시험 브라우저

안전한 시험 브라우저

안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.

에디트플러스 중국어 크랙 버전

에디트플러스 중국어 크랙 버전

작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

WebStorm Mac 버전

WebStorm Mac 버전

유용한 JavaScript 개발 도구