[Redis] 게임서버에서 왜 Redis를 사용할까??
Redis를 사용하다가 Redis가 무엇인지, 왜 사용하는지 궁금하게 되어 포스팅한다.
Redis 란?
Redis는 인메모리(In-memory) 데이터 구조 저장소로, 데이터베이스, 캐시(캐싱), 메시지 브로커 및 대기열로 사용된다.
아래는 aws.amazon 에서 퍼온 Redis 설명 글이다.
Redis란 무엇입니까?
Remote Dictionary Server를 나타내는 Redis는 빠른 오픈 소스 인 메모리 키 값 데이터 스토어입니다. 이 프로젝트는 Redis의 원 개발자인 Salvatore Sanfilippo 씨가 이탈리아 스타트업의 확장성을 개선하려고 했을 때 시작되었습니다. 거기에서 개발된 Redis는 이제 데이터베이스, 캐시, 메시지 브로커 및 대기열로 사용되고 있습니다.
Redis는 1밀리초 미만의 응답 시간을 제공하여 게임, 광고 기술, 금융 서비스, 의료 서비스 및 IoT 분야와 같은 산업에서 실시간 애플리케이션을 위해 초당 수백만 건의 요청을 지원할 수 있습니다. 빠른 성능 덕에 Redis는 캐싱, 세션 관리, 게임, 리더 보드, 실시간 분석, 지형 공간, 라이드 헤일링, 채팅/메시징, 미디어 스트리밍 및 게시/구독 앱에서 주로 사용됩니다.
인메모리 In-memory 란?
메인 메모리 RAM에 데이터를 올려서 사용하는 것은 SSD, HDD 같은 저장공간에서 읽어 오는 것보다 훨씬 빠르다.
컴퓨터의 메모리에 데이터를 올려서 사용하는 방법을 In-memory라고 한다.
캐시는 한번 읽어온 데이터를 메모리에 올려 다음에 읽을 때는 빠르게 결괏값을 받을 수 있다.
Redis는 빠른 속도가 장점이지만, 용량 한계의 단점이 있다.(모든 메모리 캐시의 단점)
Redis는 메인으로 사용하는 데이터베이스보다는 보조적인 수단(밑에서 설명)으로 많이 사용된다. (캐시 데이터베이스 서버)
게임서버의 Redis 사용
게임 랭킹에서 상위 100위 랭킹 컨텐츠가 있고, 이 랭킹 정보를 클라이언트가 요청할 때마다 전달해야 하거나 랭킹 순위 or 점수가 수시로 필요한 상황이 있을 때,
MS-SQL 같은 RDB에 랭킹 정보를 저장하고, order by로 정렬해서 사용할 수도 있다.(굳이 Redis를 사용하지 않고.)
하지만, 게임 유저가 점점 증가하고 데이터가 엄청나게 쌓인다면??
게임 랭킹 특성상, 데이터가 수시로 변경되며 바뀐 랭킹을 계속 불러와야 하는데 RDB에서는 read / write, order by에 비용이 많이 들것이다.
이럴 때, 상위 100명의 랭킹 정보를 Redis에 캐싱하고 있다면 성능에 훨씬 도움이 될 것이다.
Redis 데이터 구조
Redis는 key-value 형태의 데이터 저장소이고, 다양한 종류의 데이터 구조를 지원한다.
String / Sets / Lists / Sorted Sets / Hash .......
그중 게임 랭킹(상위 랭킹 100명)을 보여주는데 적합한 데이터 구조는 sorted sets (정렬 집합)이다.
key - 유저 unique id
value - 필요한 점수(레디스에서 순위를 자동 정렬)
Redis 단점
Redis의 장점을 알아봤는데, 그렇다면 단점은 없을까?
- 서버 장애 (Redis가 shutdown 되면 모든 데이터가 날아간다.)
위에 적은, Redis를 데이터베이스보다는 보조적인 수단으로 많이 사용한다는 이유이다.
- 인메모리 데이터 저장소 특성상, 서버에 장애가 발생했을 때, 데이터 유실이 발생할 수 있다.
메모리 용량의 한계가 있기 때문에 메모리 관리가 중요하다.
- 싱글 스레드로 작동된다.
atomic 보장은 되지만, 동시에 처리할 수 있는 명령어의 개수는 한 번에 하나이다.(O(N) 관련 명령어는 지양해야 한다.)
Redis 데이터 저장
어떤 이유에서든 게임서버나 레디스는 내려갈 수 있는데, 서버 프로그래머라면 당연히 이런 상황에 대한 처리를 생각해야 한다.
(Redis에는 Master-Slave 형식의 데이터 이중화 구조에 대한 Redis Replication, 분산 처리를 위한 Redis cluster, 장애 복구 시스템 Redis Sentinel, Redis Topology, Redis Sharding, Redis Failover 등의 Redis를 더 효율적으로 사용하기 위한 개념들이 존재한다.)
그럼, 데이터를 메모리에 올려놓고 쓴다면 레디스 데이터는 어디에 저장될까?
Redis는 두 가지의 persistence 모드를 제공한다.
- RDB
- AOF
Redis 데이터의 백업과 복원 방법에 대해서는 아래 링크에서 가져온 글을 첨부한다.
https://www.nakjunizm.com/2017/10/10/Redis_Backup_And_Restore/
Redis backup and restore
1. RDB
RDB persistence는 point-in-time snapshot을 사용자가 지정한 inverval 마다 찍어서 디스크에 .rdb file로 내립니다.
- 장점
- 특정 시점의 데이터를 file로 저장하고 저장된 파일을 안전한 backup 저장소로 옮길 수 있기 때문에 backup 용도로 좋음.
- AOF에 비해 상대적으로 빠른 복구가 가능
- 단점
- snapshot을 찍는 interval 사이에 들어온 데이터는 보존할 수 없음.
- RDB는 disk 에 파일을 내릴 때fork()를 수행하는데 이때 dataset 의 크기가 크면 Redis가 some millisecond 동안 응답을 못 줄 확률이 있음.
2. AOF
AOF는 모든 write operation에 대한 로그를 파일로 남깁니다.
그래서 redis가 startup 될 때 그 로그에 남아있는 command를 다시 play 함으로써 원본 dataset을 복원하는 방식입니다.
- 장점
- 모든 write operation이 로깅되므로 놓치는 data가 없이 완벽하게 복원 가능
- AOF 로그는 append only log이므로 파일이 corrupt 될 확률이 거의 없고 만약 disk full 등의 이유로 파일이 깨지더라도 redis-check-aof tool로 쉽게 고칠 수 있음.
- AOF 로그가 너무 커지면 Reis가 알아서 로그를 rewrite 할 수 있다.
- 단점
- 파일 크기가 일반적으로 RDB 파일보다 큼.
- fsync policy에 따라 다르긴 하지만 일반적으로 RDB에 비해 느림.
# RDB를 써야 하나 AOF를 써야 하나?
Redis 홈페이지의 article에 따르면
- 데이터의 양이 많고 몇 분간의 데이터 유실 정도는 감수할 수 있으면 간단히 RDB 만 사용해도 무방.
- 데이터의 유실이 절대 있으면 안 된다면 AOF를 단독으로 사용하지는 말고, AOF+RDB 사용을 권장함.
# RDB Backup
- 디폴트로 Redis는 snapshot을 save 하게 설정되어 있고 해당 파일은 dump.rdb라는 이름으로 디스크에 저장됩니다.
- dataset의 변경이 최소 M번 이상 있었는지 매 N 초마다 확인해서 save 하도록 설정할 수 있습니다.
- 수동으로 SAVE 혹은 BGSAVE 명령어를 사용하여 .rdb 파일을 생성할 수 있습니다.
- redis.conf 파일 설정 예) save 60 1000 <- 60초마다 최소 1000개의 key의 변화가 있을 시 save. 여러 개의 save 조건을 다른 라인으로 설정하는 것도 가능합니다.
주기적으로 데이터를 디스크에 백업하지만 백업되기 전에 Shutdown 되는 경우, 분명 유실되는 데이터가 있을 것이다.(흔하지는 않은 일이지만)
이러한 이유로 Redis는 아주 중요한 데이터를 저장하는 용도보다는 게임 랭킹처럼 정렬된 데이터를 빠르게 read write 하는 곳에 사용하기 적합한, 비관계형 데이터 베이스 관리 시스템이다.
요고는 메모용
https://youtu.be/mPB2CZiAkKM