Redis가 단일 스레드를 사용하면 왜 이렇게 빠른가요?
Redis는 왜 단일 스레드를 사용하나요?
멀티스레딩의 오버헤드
좋은 시스템 설계가 없는 경우 멀티스레딩을 사용하면 일반적으로 오른쪽에 표시된 결과가 나타납니다(세로 좌표 참조). 스레드 수를 처음 늘리면 시스템 처리 속도가 증가합니다. 스레드 수를 더 늘리면 시스템 처리 속도가 천천히 증가하거나 감소합니다.
주요 병목 현상은 다음과 같습니다. 일반적으로 시스템에는 여러 스레드가 동시에 액세스하는 공유 리소스가 있습니다. 공유 리소스의 정확성을 보장하려면 스레드 안전을 보장하는 추가 메커니즘이 필요합니다. 잠금으로 인해 추가 비용이 발생합니다.
예를 들어 가장 일반적으로 사용되는 List
유형을 예로 들어 Redis가 멀티 스레드 설계를 채택하고 LPUSHList
/code> 및 LPUSH
작업은 실행될 때마다 동일한 결과를 얻기 위해, 즉 [B 스레드는 A 스레드가 입력한 데이터를 가져옵니다] , 이 두 프로세스는 순차적으로 실행되어야 합니다. 이는 다중 스레드 프로그래밍 모델이 직면한 공유 리소스의 동시 액세스 제어 문제입니다. List
类型来举例吧,假设Redis采用多线程设计,有两个线程A和B分别对List
做LPUSH
和LPUSH
操作,为了使得每次执行都是相同的结果,即【B线程取出A线程放入的数据】就需要让这两个过程串行执行。这就是多线程编程模式面临的共享资源的并发访问控制问题。
并发访问控制一直是多线程开发中的一个难点问题:如果只是简单地采用一个互斥锁,就会出现即使增加了线程,大部分线程也在等待获取互斥锁,并行变串行,系统吞吐率并没有随着线程的增加而增加。
同时加入并发访问控制后也会降低系统代码的可读性和可维护性,所以Redis干脆直接采用了单线程模式。
Redis가 단일 스레드를 사용하면 왜 이렇게 빠른가요??
之所以使用单线程是Redis设计者多方面衡量的结果。
Redis的大部分操作在内存上完成
采用了高效的数据结构,例如哈希表和跳表
采用了多路复用机制,使其在网络IO操作中能并发处理大量的客户端请求,实现高吞吐率
既然Redis使用单线程进行IO,如果线程被阻塞了就无法进行多路复用了,所以不难想象,Redis肯定还针对网络和IO操作的潜在阻塞点进行了设计。
网络与IO操作的潜在阻塞点
在网络通信里,服务器为了处理一个Get请求,需要监听客户端请求(bind/listen
),和客户端建立连接(accept
),从socket中读取请求(recv
),解析客户端发送请求(parse
),最后给客户端返回结果(send
)。
最基本的一种单线程实现是依次执行上面的操作。
上面标红的accept和recv操作都是潜在的阻塞点:
当Redis监听到有连接请求,但却一直不能成功建立起连接时,就会阻塞在
accept()
函数这里,其他客户端此时也无法和Redis建立连接当Redis通过
recv()
从一个客户端读取数据时,如果数据一直没有到达,也会一直阻塞
基于多路复用的高性能IO模型
为了解决IO中的阻塞问题,Redis采用了Linux的IO多路复用机制,该机制允许内核中,同时存在多个监听套接字和已连接套接字(select/epoll
)。
内核会一直监听这些套接字上的连接或数据请求。Redis会处理到达的请求,从而实现了一个线程处理多个IO流的效果。
此时,Redis线程就不会阻塞在某一个特定的客户端请求处理上,所以它可以同时和多个客户端连接并处理请求。
回调机制
select/epoll一旦监测到FD上有请求到达时,就会触发相应的事件被放进一个队列里,Redis线程对该事件队列不断进行处理,所以就实现了基于事件的回调。
例如,Redis会对Accept和Read事件注册accept
和get
回调函数。当Linux内核监听到有连接请求或读数据请求时,就会触发Accept事件和Read事件,此时,内核就会回调Redis相应的accept
和get

- 🎜Redis의 대부분의 작업은 메모리에서 완료됩니다🎜
- 🎜해시 테이블, 스킵 테이블 등 효율적인 데이터 구조 사용🎜
- 🎜네트워크 IO 작업에서 동시에 많은 수의 클라이언트 요청을 처리하고 높은 처리량을 달성할 수 있도록 멀티플렉싱 메커니즘을 채택합니다.🎜 🎜🎜Redis는 IO에 단일 스레드를 사용하므로 스레드가 차단된 경우 , 멀티플렉싱을 수행할 수 없으므로 Redis가 네트워크 및 IO 작업의 잠재적인 차단 지점을 위해 설계되었을 것이라고 상상하는 것은 어렵지 않습니다. 🎜🎜네트워크 및 IO 작업의 잠재적 차단 지점🎜🎜네트워크 통신에서 Get 요청을 처리하려면 서버가 클라이언트 요청(
- 🎜 Redis가 연결 요청을 감지했지만 연결을 성공적으로 설정할 수 없으면
accept에서 차단됩니다. ()
함수를 사용하면 현재 다른 클라이언트는 Redis와 연결을 설정할 수 없습니다🎜 - 🎜Redis가 클라이언트에서
recv()
를 전달하면 끝이 데이터를 읽을 때, 데이터가 도착하지 않으면 항상 차단됩니다🎜 🎜🎜다중화 기반의 고성능 IO 모델🎜🎜IO의 차단 문제를 해결하기 위해 Redis는 Linux의 IO 다중화 메커니즘을 사용하여 경로 다중화 메커니즘을 허용합니다. 여러 개의 청취 소켓과 연결된 소켓이 커널에 동시에 존재합니다( Redis를 사용하는 이유는 메모리에 직접 접근하는 것도 나쁘지 않나요?
메모리에 저장할 수 없는 데이터가 너무 많으면 어떻게 해야 하나요? 예를 들어, 100G의 데이터를 캐시하고 싶다면 어떻게 해야 합니까?
bind/listen
)을 수신하고 연결을 설정해야 합니다. 클라이언트(accept
), 소켓에서 요청을 읽고(recv
), 클라이언트가 보낸 요청을 구문 분석하고(parse
) 마지막으로 결과를 클라이언트에 반환합니다(send
). 🎜🎜가장 기본적인 단일 스레드 구현은 위 작업을 순서대로 수행하는 것입니다. 🎜🎜
select/epoll
). 🎜🎜커널은 항상 이러한 소켓에 대한 연결이나 데이터 요청을 수신합니다. Redis는 들어오는 요청을 처리하여 하나의 스레드가 여러 IO 스트림을 처리하는 효과를 얻습니다. 🎜🎜
accept
및 get
콜백 함수를 등록합니다. Linux 커널은 연결 요청이나 데이터 읽기 요청을 모니터링할 때 Accept 이벤트 및 Read 이벤트를 트리거합니다. 이때 커널은 해당 accept
및 get을 콜백합니다. code>를 처리할 함수입니다. 🎜🎜Redis의 성능 병목 현상🎜🎜위 분석 후, 멀티플렉싱 메커니즘을 통해 여러 클라이언트 요청을 동시에 모니터링할 수 있지만 Redis에는 여전히 성능 병목 현상이 있으며 이는 일상적인 프로그래밍에서 피해야 하는 상황이기도 합니다. . 🎜<h4 id="시간이-많이-걸리는-작업">1. 시간이 많이 걸리는 작업</h4>
<p>Redis에서 요청이 오래 걸리면 전체 서버 성능에 영향을 미칩니다. 후속 요청은 처리되기 전에 시간이 많이 걸리는 이전 요청이 처리될 때까지 기다려야 합니다. </p>
<p>비즈니스 시나리오를 설계할 때 이는 피해야 합니다. Redis의 <code>lazy-free
메커니즘은 또한 실행을 위해 비동기 스레드에서 메모리를 해제하는 데 시간이 많이 걸리는 작업을 수행합니다.
2. 높은 동시성 시나리오
동시성이 매우 클 경우 단일 스레드로 클라이언트 IO 데이터를 읽고 쓰는 데 성능 병목 현상이 발생합니다. IO 다중화 메커니즘을 사용하더라도 여전히 클라이언트를 읽을 수만 있습니다. 여러 CPU 코어를 활용할 수 없는 단일 스레드로 데이터를 순차적으로 처리합니다.
6.0의 Redis는 CPU 멀티 코어 및 멀티 스레딩을 사용하여 클라이언트 데이터를 읽고 쓸 수 있지만 클라이언트에 대한 읽기 및 쓰기만 병렬이며 각 명령의 실제 작업은 여전히 단일 스레드입니다.
Redis와 관련된 다른 흥미로운 질문
이 기회에 Redis와 관련된 몇 가지 흥미로운 질문을 던져보고 싶습니다.
사실 이 글은 명확하게 정의되어 있지 않습니다. 자주 변경되지 않는 일부 데이터의 경우에는 Redis에 직접 배치할 필요가 없습니다. 데이터를 업데이트할 때 일관성 문제가 발생할 수 있습니다. 즉, 한 서버의 데이터만 수정될 수 있으므로 데이터는 로컬 메모리에만 존재합니다. Redis 서버에 액세스하면 Redis를 사용하여 일관성 문제를 해결할 수 있습니다.
여기에도 광고가 있습니다. Tair는 Taobao의 오픈 소스 분산 KV 캐시 시스템입니다. 이론적으로 전체 데이터 양은 무제한입니다. 업그레이드, 관심있는 친구들이 알아보세요~
위 내용은 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는 해시 테이블을 사용하여 데이터를 저장하고 문자열, 목록, 해시 테이블, 컬렉션 및 주문한 컬렉션과 같은 데이터 구조를 지원합니다. Redis는 Snapshots (RDB)를 통해 데이터를 유지하고 WRITE 전용 (AOF) 메커니즘을 추가합니다. Redis는 마스터 슬레이브 복제를 사용하여 데이터 가용성을 향상시킵니다. Redis는 단일 스레드 이벤트 루프를 사용하여 연결 및 명령을 처리하여 데이터 원자력과 일관성을 보장합니다. Redis는 키의 만료 시간을 설정하고 게으른 삭제 메커니즘을 사용하여 만료 키를 삭제합니다.

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

Redis를 사용하여 잠금 작업을 사용하려면 SetNX 명령을 통해 잠금을 얻은 다음 만료 명령을 사용하여 만료 시간을 설정해야합니다. 특정 단계는 다음과 같습니다. (1) SETNX 명령을 사용하여 키 값 쌍을 설정하십시오. (2) 만료 명령을 사용하여 잠금의 만료 시간을 설정하십시오. (3) DEL 명령을 사용하여 잠금이 더 이상 필요하지 않은 경우 잠금을 삭제하십시오.

Redis Counter는 Redis Key-Value Pair 스토리지를 사용하여 다음 단계를 포함하여 계산 작업을 구현하는 메커니즘입니다. 카운터 키 생성, 카운트 증가, 카운트 감소, 카운트 재설정 및 카운트 얻기. 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 소스 코드를 이해하는 가장 좋은 방법은 단계별로 이동하는 것입니다. Redis의 기본 사항에 익숙해집니다. 특정 모듈을 선택하거나 시작점으로 기능합니다. 모듈 또는 함수의 진입 점으로 시작하여 코드를 한 줄씩 봅니다. 함수 호출 체인을 통해 코드를 봅니다. Redis가 사용하는 기본 데이터 구조에 익숙해 지십시오. Redis가 사용하는 알고리즘을 식별하십시오.
