Redis 연결 목록의 하위 계층을 구현하는 방법
기본 구현
Redis 목록 데이터 구조의 기본 구현은 이중 연결 목록을 기반으로 합니다. 이중 연결 리스트는 일련의 노드로 구성된 공통 데이터 구조입니다. 각 노드는 이전 노드를 가리키는 포인터 prev, 다음 노드를 가리키는 다음 포인터 및 스토리지 A 포인터를 포함하는 listNode 구조로 표시됩니다. 가치를 소중히 여기다. Redis의 이중 연결 목록은 노드로 구성되며 각 노드는 요소를 나타내며 포인터를 통해 연결됩니다.
이중 연결 목록의 장점은 삽입 및 삭제 작업을 머리 부분과 꼬리 부분에서 빠르게 수행할 수 있다는 것입니다. Redis에서 새 요소가 목록의 헤드 또는 테일에 삽입되면 삽입 작업을 완료하려면 새 노드의 이전 및 다음 포인터와 원래 헤드 또는 테일 노드의 이전 또는 다음 포인터만 수정하면 됩니다. . 시간이 복잡합니다. 정도는 O(1)입니다. 마찬가지로 요소가 삭제되면 이전 노드의 다음 포인터나 다음 노드의 prev 포인터만 수정하면 삭제 작업이 완료되며 시간 복잡도도 O(1)입니다.
Redis는 이중 연결 목록을 사용하는 것 외에도 목록 데이터 구조의 성능을 향상하기 위해 다른 기술을 사용합니다. 예를 들어 목록의 요소 수가 특정 임계값을 초과하면 Redis는 목록을 압축 목록(zip 목록)으로 변환하여 메모리 사용량을 줄이고 액세스 속도를 높일 수 있습니다. 목록을 반복할 때 Redis는 반복자를 사용하여 목록의 요소를 순회하므로 순회 프로세스 중에 목록 수정으로 인해 발생하는 오류를 방지할 수 있습니다.
Redis의 목록형 데이터 구조는 목록의 시작이나 끝 부분에 요소를 추가하거나 제거할 수 있고, 지정된 위치에 요소를 삽입하거나 삭제할 수 있습니다. Redis의 이중 연결 목록 구현은 헤드 및 테일 노드에 대한 빠른 액세스는 물론 지정된 위치의 노드 삽입 및 삭제를 지원하므로 이러한 작업은 일정한 시간에 완료될 수 있습니다.
다음은 몇 가지 일반적인 Redis 목록 작업과 해당 시간 복잡도입니다.
LPUSH: 요소를 헤드에 삽입합니다. 시간 복잡도는 O(1)입니다.
RPUSH: 끝에 요소를 삽입하면 시간 복잡도는 O(1)입니다.
LPOP: 헤더 요소를 삭제합니다. 시간 복잡도는 O(1)입니다.
RPOP: 꼬리 요소를 삭제하면 시간 복잡도는 O(1)입니다.
LINDEX: 지정된 위치의 요소에 액세스합니다. 시간 복잡도는 O(n)입니다.
LINSERT: 지정된 위치에 요소를 삽입합니다. 시간 복잡도는 O(n)입니다.
LREM: 지정된 요소를 삭제합니다. 시간 복잡도는 O(n)입니다.
소스 코드 구현
Redis List 데이터 구조의 기본 코드는 C 언어를 사용하여 데모를 구현합니다.
typedef struct listNode { struct listNode *prev; struct listNode *next; void *value; } listNode; typedef struct list { listNode *head; listNode *tail; unsigned long len; } list; list *listCreate(void) { list *l; if ((l = malloc(sizeof(*l))) == NULL) return NULL; l->head = l->tail = NULL; l->len = 0; return l; } void listRelease(list *list) { unsigned long len; listNode *current, *next; current = list->head; len = list->len; while(len--) { next = current->next; free(current); current = next; } free(list); } listNode *listAddNodeHead(list *list, void *value) { listNode *node; if ((node = malloc(sizeof(*node))) == NULL) return NULL; node->value = value; if (list->len == 0) { list->head = list->tail = node; node->prev = node->next = NULL; } else { node->prev = NULL; node->next = list->head; list->head->prev = node; list->head = node; } list->len++; return node; } listNode *listAddNodeTail(list *list, void *value) { listNode *node; if ((node = malloc(sizeof(*node))) == NULL) return NULL; node->value = value; if (list->len == 0) { list->head = list->tail = node; node->prev = node->next = NULL; } else { node->prev = list->tail; node->next = NULL; list->tail->next = node; list->tail = node; } list->len++; return node; } void listDelNode(list *list, listNode *node) { if (node->prev) node->prev->next = node->next; else list->head = node->next; if (node->next) node->next->prev = node->prev; else list->tail = node->prev; free(node); list->len--; }
위 코드는 List 생성, 릴리스를 포함하여 List 데이터 구조의 기본 작업을 구현합니다. 헤더와 테일에 데이터를 나열하고 추가하며 요소 삽입 및 삭제를 수행합니다. 이러한 작업의 시간 복잡도는 O(1)입니다.
프로덕션에서의 실제 사용
Redis List 데이터 구조는 프로덕션 환경에서 많은 놀라운 용도를 가지고 있습니다.
메시지 대기열: Redis List는 메시지 대기열로 사용될 수 있으며 생산자는 메시지를 List에 푸시하고 소비자는 blpop을 사용합니다. , brpop 등. 이 명령은 메시지를 획득하고 이를 차단 방식으로 처리하여 간단한 메시지 대기열을 구현합니다.
주요 목록: Redis 목록의 푸시 및 팝 작업은 모두 O(1) 시간 복잡도를 가지며 사용자의 점수를 목록에 값으로 저장한 다음 lrange 명령을 통해 순위 목록을 얻을 수 있습니다.
최근 연락처 목록: 사용자의 최근 연락처 ID가 목록에 저장될 수 있습니다. 사용자가 연락처와 상호 작용할 때마다 연락처 ID가 목록의 맨 위로 이동되어 사용자의 최근 연락처를 가져옵니다. lrange 명령을 통한 연락처 목록.
페이징 쿼리: 데이터를 목록에 저장한 다음 lrange 명령을 사용하여 페이징 쿼리를 수행할 수 있습니다.
느린 로그: Redis는 실행 시간이 특정 임계값을 초과하는 명령을 기록하고 이러한 명령의 정보를 List에 저장하며 lrange 명령을 통해 느린 로그 정보를 얻을 수 있습니다.
채팅방: 채팅방의 메시지를 목록에 저장할 수 있습니다. 새 메시지가 있을 때마다 목록에 푸시한 후 lrange 명령을 통해 최신 메시지를 가져올 수 있습니다.
작업 대기열: 실행해야 하는 작업을 목록에 저장한 다음 lpop 명령을 통해 작업을 가져와 실행할 수 있습니다.
실시간 데이터 통계: 실시간 데이터를 List에 저장한 후 lrange 명령어를 사용하여 특정 시간 범위 내의 데이터를 얻어 통계 분석을 수행할 수 있습니다.
队列延迟处理:可以将需要延迟处理的任务存储在 List 中,同时将任务的执行时间作为 score 存储在 Sorted Set 中,然后使用 Redis 的定时任务功能,每隔一段时间就将 Sorted Set 中过期的任务移动到 List 中,然后通过 lpop 命令获取任务并执行。
日志收集:可以将应用程序的日志信息存储在 List 中,然后通过 lrange 命令获取日志信息进行分析和处理。
实战实例
基于 Redis List 数据结构实现消息队列的 Java 代码示例:
import redis.clients.jedis.Jedis; public class RedisMessageQueue { private Jedis jedis; private String queueKey; public RedisMessageQueue(Jedis jedis, String queueKey) { this.jedis = jedis; this.queueKey = queueKey; } public void enqueue(String message) { jedis.rpush(queueKey, message); } public String dequeue() { return jedis.lpop(queueKey); } }
示例中,定义了一个 RedisMessageQueue 类,包含一个 Jedis 对象和一个队列键名 queueKey。enqueue 方法用于将消息 push 到队列中,dequeue 方法用于从队列中获取消息并将其 pop 出来,使用该类可以方便地实现消息队列功能。
使用方法如下:
import redis.clients.jedis.Jedis; public class TestRedisMessageQueue { public static void main(String[] args) { Jedis jedis = new Jedis("localhost"); RedisMessageQueue queue = new RedisMessageQueue(jedis, "myqueue"); // 生产者向队列中添加消息 queue.enqueue("Hello, Redis!"); queue.enqueue("How are you?"); // 消费者从队列中获取消息 String message = queue.dequeue(); while (message != null) { System.out.println("Received message: " + message); message = queue.dequeue(); } } }
我已经构建了一个 RedisMessageQueue 实例,并向队列中添加了两条信息。接着,调用 dequeue 方法从队列中取出消息,并将其输出到控制台。
该示例代码仅为演示 Redis List 数据结构实现消息队列的思路,实际生产环境中需要考虑更多的细节问题,例如如何处理消息重复、如何保证消息的可靠性等等。
Redis 聊天室示例
import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPubSub; import java.util.Scanner; public class RedisChatRoom { private Jedis jedis; private String channel; private String chatListKey; public RedisChatRoom(Jedis jedis, String channel, String chatListKey) { this.jedis = jedis; this.channel = channel; this.chatListKey = chatListKey; } public void start() { // 订阅 Redis 频道 jedis.subscribe(new JedisPubSub() { @Override public void onMessage(String channel, String message) { System.out.println("Received message: " + message); // 将消息添加到聊天列表中 jedis.rpush(chatListKey, message); } }, channel); // 发布消息到 Redis 频道 Scanner scanner = new Scanner(System.in); while (true) { System.out.print("Enter message: "); String message = scanner.nextLine(); jedis.publish(channel, message); } } public void printChatList() { // 获取聊天列表中的所有消息并输出到控制台 System.out.println("Chat list:"); for (String message : jedis.lrange(chatListKey, 0, -1)) { System.out.println(message); } } }
示例中,RedisChatRoom 类中添加了一个聊天列表 chatListKey,用于存储聊天室中的所有消息。在订阅 Redis 频道时,通过 JedisPubSub 的 onMessage 方法将收到的消息添加到聊天列表中。在 printChatList 方法中,通过 lrange 命令获取聊天列表中的所有消息,并输出到控制台中。
使用方法如下:
import redis.clients.jedis.Jedis; public class TestRedisChatRoom { public static void main(String[] args) { Jedis jedis = new Jedis("localhost"); RedisChatRoom chatRoom = new RedisChatRoom(jedis, "mychannel", "mychatlist"); chatRoom.start(); chatRoom.printChatList(); } }
创建了一个 RedisChatRoom 对象,并指定了频道名为 mychannel 和聊天列表键名为 mychatlist。执行 start 方法即可开始 Redis 频道的订阅并发布消息。在最后一步中,使用 printChatList 方法从聊天列表中获取所有消息并输出到控制台上。
该示例仅仅简单演示 Redis List 数据结构实现聊天室的思路,实际项目中需要更周全的设计以及考虑。
위 내용은 Redis 연결 목록의 하위 계층을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

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

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

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

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

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











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

Redis 지시 사항을 사용하려면 다음 단계가 필요합니다. Redis 클라이언트를 엽니 다. 명령 (동사 키 값)을 입력하십시오. 필요한 매개 변수를 제공합니다 (명령어마다 다름). 명령을 실행하려면 Enter를 누르십시오. Redis는 작업 결과를 나타내는 응답을 반환합니다 (일반적으로 OK 또는 -err).

Redis는 단일 스레드 아키텍처를 사용하여 고성능, 단순성 및 일관성을 제공합니다. 동시성을 향상시키기 위해 I/O 멀티플렉싱, 이벤트 루프, 비 블로킹 I/O 및 공유 메모리를 사용하지만 동시성 제한 제한, 단일 고장 지점 및 쓰기 집약적 인 워크로드에 부적합한 제한이 있습니다.

Redis에서 모든 키를 보려면 세 가지 방법이 있습니다. 키 명령을 사용하여 지정된 패턴과 일치하는 모든 키를 반환하십시오. 스캔 명령을 사용하여 키를 반복하고 키 세트를 반환하십시오. 정보 명령을 사용하여 총 키 수를 얻으십시오.

Redis 서버를 시작하는 단계에는 다음이 포함됩니다. 운영 체제에 따라 Redis 설치. Redis-Server (Linux/MacOS) 또는 Redis-Server.exe (Windows)를 통해 Redis 서비스를 시작하십시오. Redis-Cli Ping (Linux/MacOS) 또는 Redis-Cli.exe Ping (Windows) 명령을 사용하여 서비스 상태를 확인하십시오. Redis-Cli, Python 또는 Node.js와 같은 Redis 클라이언트를 사용하여 서버에 액세스하십시오.

Redis 데이터를 지우는 방법 : Flushall 명령을 사용하여 모든 키 값을 지우십시오. FlushDB 명령을 사용하여 현재 선택한 데이터베이스의 키 값을 지우십시오. 선택을 사용하여 데이터베이스를 전환 한 다음 FlushDB를 사용하여 여러 데이터베이스를 지우십시오. del 명령을 사용하여 특정 키를 삭제하십시오. Redis-Cli 도구를 사용하여 데이터를 지우십시오.

Redis는 해시 테이블을 사용하여 데이터를 저장하고 문자열, 목록, 해시 테이블, 컬렉션 및 주문한 컬렉션과 같은 데이터 구조를 지원합니다. Redis는 Snapshots (RDB)를 통해 데이터를 유지하고 WRITE 전용 (AOF) 메커니즘을 추가합니다. Redis는 마스터 슬레이브 복제를 사용하여 데이터 가용성을 향상시킵니다. Redis는 단일 스레드 이벤트 루프를 사용하여 연결 및 명령을 처리하여 데이터 원자력과 일관성을 보장합니다. Redis는 키의 만료 시간을 설정하고 게으른 삭제 메커니즘을 사용하여 만료 키를 삭제합니다.

Redis 소스 코드를 이해하는 가장 좋은 방법은 단계별로 이동하는 것입니다. Redis의 기본 사항에 익숙해집니다. 특정 모듈을 선택하거나 시작점으로 기능합니다. 모듈 또는 함수의 진입 점으로 시작하여 코드를 한 줄씩 봅니다. 함수 호출 체인을 통해 코드를 봅니다. Redis가 사용하는 기본 데이터 구조에 익숙해 지십시오. Redis가 사용하는 알고리즘을 식별하십시오.
