일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 오어스
- JWT
- 살아남았다.
- MDC
- 우테코
- 테스트코드
- 커넥션 풀
- Elk
- 트랜잭션
- HikariCP
- 톰캣
- oauth
- AOP
- tomcat
- DispatcherServlet
- Thread
- resilience4j
- Spring Batch
- 최종 합격
- 우아한 테크 코스
- Gateway
- Spring cloud gateway
- spirng
- 우아한테크코스
- circuitbreaker
- Transactio
- redis
- 우테코 5기
- 동시성문제
- Kotlin
- Today
- Total
코딩은 내일부터
Redis의 특징 + 동작원리 본문
개발을 하면서 Redis라는 키워드를 많이 들었다.
In-memory~, 단일 스레드 등등 빠르고 캐싱할 때 많이 사용하는 저장소로만 알고 있어서
더 자세히 Redis의 대해서 알아보겠다.
Redis가 뭔가요?
Redis는 Key-value형식의 저장이다. 쉽게 말해 거대한 맵(Map)데이터 저장소라고 생각하면 좋다.
또한 NoSQL의 종류로 고정되지 않은 테이블 스키마를 가질 수 있고, RDBMS에 비해 훨씬 더 대용량의 데이터를 저장할 수 있다.
왜 Redis가 빠른가요?
Redis는 In-Memory데이터 저장소기 때문에 디스크 기반 DB에 비해 매우 빠른 성능을 제공한다.
위에 사진에서 나와있듯이 HDD는 1~10ms, RAM은 120ns로 RAM이 압도적으로 빠르다는 걸 알 수 있다.
In-Memory면 휘발되는 거 아닌가요?
일반적으로 인메모리는 서버를 재시작하면 휘발되지만 Redis는 AOF와 RDB라는 백업을 하는 기능을 제공한다.
AOF(Append Only)란 모든 쓰기 명령에 대한 로그를 남기고, RDB는 특정한 시점을 말 그대로 시냅샷 하는 방식의 백업이다.
두 개의 백업 방식을 선택하는 기준은 다음과 같이 나눌 수 있다.
- 백업은 필요하지만 어느 정도의 손실이 발생해도 괜찮은 경우
- RDB 단독 사용
- 장애 상황 직전까지의 모든 데이터가 보장되어야 할 경우
- AOF 사용
- APPENDFSYNC옵션이 everysec인 경우 최대 1초 사이의 데이터 유실 가능(기본 설정)
물론 제일 완벽한 백업이 필요하다면 AOF와 RDB를 동시에 사용하는 방법이다.
주의할 점
redis는 메모리에 데이터를 저장하기 때문에 물리메모리(RAM) 용량보다 더 많은 데이터를 사용하게 될 경우 메모리 부족으로 인해 swap이 발생하여 Redis의 성능 저하를 일으킬 수 있다.
Redis는 어떻게 동작하고 단일스레든데 왜 빠른가요?
Redis는 단일 CPU코어에서 초당 최대 500,000개의 SET/GET작업을 처리할 수 있다...(와우)
공식문서를 찾아보면
Redis는 대부분 단일 스레드 디자인을 사용합니다. 이는 single thread이며 multiplexing이라는 기술을 사용하여 모든 클라이언트 요청을 처리한다는 것을 의미합니다.
Node.js의 작동 방식과 매우 유사합니다.
Redis 2.4부터는 디스크 I/O와 관련된 느린 I/O 작업을 백그라운드에서 수행하기 위해 여러 개의 스레드를 사용하지만 Redis가 단일 스레드를 사용하여 모든 요청을 처리한다는 사실은 바뀌지 않습니다.
위와 같이 요약할 수 있습니다.
여기서 나온 내용을 하나하나 정리해 보면
"대부분" 단일 스레드이다.
실제로 redis의 스레드를 조회해 보면 여러 개가 쓰여있다.
하지만 하나의 스레드에서만 명령을 처리하고 나머지 스레드들은 disk를 flush하거나 파일을 닫기 위해 OS 작업이 되는것을 해당 쓰레드에서 처리하게 되면 다른 작업이 느려지기 때문에 해당 작업들을 OS레벨에서 비동기로 처리한다.
즉, Single Thread라는 의미는 클라이언트의 요청인 Redis의 명령어를 처리하는 것에만 유의미합니다.
multiplexing란?
multiplexing은 스레드를 차단하지 않고 단일 스레드를 사용하여 여러 클라이언트 연결을 모니터링하는 것을 의미한다.
Redis동작 과정을 다음과 같다.
- Redis는 새로운 클라이언트 연결, 클라이언트에서 들어오는 데이터 또는 I/O 작업 완료와 같은 이벤트가 발생하기를 기다리는 단일 이벤트 루프를 사용합니다.
- 새 클라이언트가 Redis에 연결되면 이벤트 루프에 등록되고 이벤트 루프는 들어오는 데이터에 대한 연결을 모니터링합니다.
- 클라이언트로부터 데이터가 도착하면 이벤트 루프는 이벤트 유형을 결정하고 그에 따라 처리합니다.
- 클라이언트의 요청에 I/O작업이 필요한 경우 이벤트 루프는 다른 클라이언트의 연결의 진행을 차단하지 않고 작업을 비동기적으로 수행합니다.
- 이벤트 루프가 여러 클라이언트의 이벤트를 처리할 때 각 클라이언트에 대해 보류 중인 작업 대기열을 유지 관리합니다. 이를 통해 Redis는 실제 처리가 단일 스레드 내에서 발생하더라도 동시에 여러 클라이언트에 서비스를 제공할 수 있습니다.
이렇게 multiplexing과 백그라운드에서 실행되는 다중 쓰레드 덕분에 Atomic과 빠른 성능을 기대할 수 있다.
이상!