개요
Multi Server 환경에서의 Session데이터를 Servere마다 관리하도록 설계한다면 어떻게 될까요? 사용자가 로그인한 상태에서 요청 서버가 바뀐다면, 해당 사용자는 로그인이 해제될 것입니다.(해당 서버의 세션 저장소에는 사용자가 로그인한 데이터가 없으므로) 그렇기 때문에 웹 서버에서는 세션 데이터를 서버가 아닌 외부 저장소에 저장합니다.
이때 사용하는 저장소에 대해 의문이 들었습니다. Spring의 세션 클러스터링은 기본적으로 Redis를 이용하여 진행됩니다. 세션 정보 저장과 캐싱에 Redis를 사용하던 도중 왜 Spring은 Redis를 이용하게 되었을까에 대한 궁금증이 생겼습니다. RDBMS에도 저장할 수 있고 MongoDB, Memcached 등 다른 NoSQL에도 데이터를 저장할 수 있기 때문입니다.
가장 큰 틀인 RDBMSA와 NoSQL을 비교해보았습니다. 캐싱 전략과 세션 저장에 RDBMS가 어울리지 않는다고 생각할 수 있지만 실제로 MySQL을 캐싱에 사용할 수도 있습니다. Spring Data Redis Doc에서는 왜 RDBMS 대신 NoSQL을 선택했는지 말해주고 있습니다.
RDBMS vs NoSQL
우선 Spring Data Redis Doc를 살펴보았습니다.
2. Why Spring Data Redis?The Spring Framework is the leading full-stack Java/JEE application framework. It provides a lightweight container and a non-invasive programming model enabled by the use of dependency injection, AOP, and portable service abstractions. NoSQL storage systems provide an alternative to classical RDBMS for horizontal scalability and speed. In terms of implementation, key-value stores represent one of the largest (and oldest) members in the NoSQL space. The Spring Data Redis (SDR) framework makes it easy to write Spring applications that use the Redis key-value store by eliminating the redundant tasks and boilerplate code required for interacting with the store through Spring’s excellent infrastructure support.
|
NoSQL은 RDBMS에 비해 속도와 확장성이 뛰어납니다. 위 문서를 통해 MySQL과 같은 RDBMS는 속도가 중요한 캐싱에는 적합하지 않다는 것을 알 수 있었습니다.
그렇다면 NoSQL 중 캐싱 전략에 자주 사용되는 Redis, Memcached 중 왜 Redis를 선택하게 되었을까요? 이 두 가지 선택지는 캐싱과 세션 저장 시 자주 비교되는 선택지입니다.
Spring Doc에는 왜 Redis를 선택했는지는 나와있지 않습니다. 그러므로 이 문단부터는 필자의 주관적인 분석을 적을 예정입니다.
NoSQL - Redis vs Memcached
1. 특징
우선 두 NoSQL의 특징을 정리해보았습니다.
Redis | Memcached | |
저장소 | In Memory Storage | |
저장 방식 | Key-Value | |
데이터 타입 | String, Set, Sorted Set, Hash, List | String |
데이터 저장 | Memory, Disk | Only Memory |
메모리 재사용 | 메모리 재사용 하지 않음(명시적으로만 데이터 삭제 가능) | 메모리 부족시 LRU 알고리즘을 이용하여 데이터 삭제 후 메모리 재사용 |
스레드 | Single Thread | Multi Thread |
캐싱 용량 | Key, Value 모두 512MB | Key name 250 byte, Value 1MB |
공통점
Redis와 Memcached 모두 In Memory, key-value 방식의 NoSQL입니다.
Redis > Memcached
1. 다양한 자료구조를 지원합니다.
String만 지원하는 Memcached에 비해 Redis는 더욱 다양한 자료구조를 지원하여 더 다양한 타입의 자료를 저장할 수 있습니다. 이는 Memcached에 비해 Redis가 가지는 강력한 장점 중 하나입니다.
2. 데이터 복구가 가능합니다.
프로세스의 돌발 종료, 서버 종료 등 돌발 상황에서 Memcached는 모든 데이터가 유실되지만, Redis는 데이터를 Disk에도 저장하기 때문에 메모리에서 유실된 데이터를 복구할 수 있습니다.
3. 다양한 Data Eviction 정책을 지원합니다.
Memcached는 LRU 알고리즘을 통한 Eviction을 지원합니다. 하지만 Redis는 6가지 Eviction정책을 통해 더욱 세밀한 Eviction 제어가 가능합니다.
Memcached > Redis
1. 멀티스레드를 아키텍처를 지원합니다.
Single Thread인 Redis에 비해 Memcached는 Multi Thread를 지원하기 때문에 서버 Scale up에 유리합니다.
2. Redis에 비해 적은 메모리를 요구합니다.
HTML과 같은 정적인 데이터를 캐싱하는 것에는 Memcached가 유리합니다. Redis는 Copy&Write 방식을 사용하기 때문에 실제 사용하는 메모리보다 더 많은 메모리를 요구합니다.
선호도
Stackoverflow
https://stackoverflow.com/questions/10558465/memcached-vs-redis
StackOverflow에서 Memcached와 Redis 중 어떤 것을 선택해야 하는지 질문이 올라온 적이 있습니다. 거의 대부분의 답변자들은 선택지가 있다면 무조건 Redis를 사용하라고 조언하였습니다. 또한 Memcached보다 Redis에 관련된 문서가 더 많기 때문에 Redis를 사용하는 데 있어서 유용한 정보가 더욱 풍부할 것이라고 조언하였습니다.
아래 내용은 이 질문의 답변 내용을 일부 스크랩 한 것입니다.
극찬 수준의 Redis 추천
ConclusionWithout hesitation I would recommend redis over memcached for any new projects, or existing projects that don't already use memcached. The above may sound like I don't like memcached. On the contrary: it is a powerful, simple, stable, mature, and hardened tool. There are even some use cases where it's a little faster than redis. I love memcached. I just don't think it makes much sense for future development. Redis does everything memcached does, often better. Any performance advantage for memcached is minor and workload specific. There are also workloads for which redis will be faster, and many more workloads that redis can do which memcached simply can't. The tiny performance differences seem minor in the face of the giant gulf in functionality and the fact that both tools are so fast and efficient they may very well be the last piece of your infrastructure you'll ever have to worry about scaling. There is only one scenario where memcached makes more sense: where memcached is already in use as a cache. If you are already caching with memcached then keep using it, if it meets your needs. It is likely not worth the effort to move to redis and if you are going to use redis just for caching it may not offer enough benefit to be worth your time. If memcached isn't meeting your needs, then you should probably move to redis. This is true whether you need to scale beyond memcached or you need additional functionality. |
AWS 공식 문서 비교
https://aws.amazon.com/ko/elasticache/redis-vs-memcached/
AWS에서는 서버의 동작 방식에 따라 Memcached와 Redis 중 선택하라고 말합니다. 다만 Redis의 장점을 더 명확하게 설명하고 있습니다.
성능 비교
응답 속도
Memcached는 Redis에 비해 안정적인 응답 속도를 기대할 수 있습니다. 트래픽이 많아질 때 Redis는 응답 속도가 불안정하다는 이슈가 있습니다. Redis가 jemalloc 메모리 할당 구조를 사용하기 때문인데 malloc과 free를 사용하여 메모리 파편화가 발생하고 이 할당 비용으로 인해 응답 속도가 느려지는 이슈입니다.
Memcached는 slab 메모리 할당 구조를 사용한다고 합니다.
Read / Write
Jedis jed = new Jedis("localhost", 6379);
int count = 100000;
long startTime = System.currentTimeMillis();
for (int i=0; i<count; i++) {
jed.set("u112-"+i, "v51"+i);
}
long endTime = System.currentTimeMillis();
System.out.println("Time taken to store "+ count + " values is ="+(endTime-startTime)+"ms");
startTime = System.currentTimeMillis();
for (int i=0; i<count; i++) {
client.get("u112-"+i);
}
endTime = System.currentTimeMillis();
System.out.println("Time taken to retrieve "+ count + " values is ="+(endTime-startTime)+"ms");
Redis
Memcached
|
스택오버플로에서 자신의 컴퓨터에서 직접 Redis와 Memcached의 성능을 비교한 답변이 달렸습니다. Redis는 Read/Write에서 균일한 속도를 보여주었고 Memcached는 저장 속도가 더욱 월등하지만 검색 속도가 Redis에 비해 느렸습니다.
결론
Redis는 Memcached의 단점을 개선하여 만들었다고 합니다. Spring 운영 서버에서 데이터 복구 기능과 다양한 자료구조를 가진 Redis는 캐싱과 세션 관리에 있어서 더욱 강력한 기능을 제공하고 있습니다.
그렇기 때문에 메모리 파편화와 약간의 속도 차이를 감수하고도 Memcached에 비해 강력한 운영 기능을 가진 Redis를 선택한 것이라고 생각합니다.
Reference
https://aws.amazon.com/ko/elasticache/redis-vs-memcached/
https://stackoverflow.com/questions/10558465/memcached-vs-redis
https://docs.spring.io/spring-data/data-redis/docs/current/reference/html/#reference
'Web > Spring' 카테고리의 다른 글
[Spring] 트랜잭션의 전파 설정별 동작 (11) | 2020.03.04 |
---|---|
[Spring] Spring session을 Redis에 저장했을 때 어떻게 저장될까? (2) | 2020.01.03 |
[Spring Mybatis] 중복 쿼리를 include, sql로 대체하기 (0) | 2019.10.16 |
[Spring-boot JPA] 쿼리와 파라미터 확인방법 (0) | 2019.09.09 |
[Spring-boot JPA] 즉시로딩(EAGER)과 지연로딩(LAZY) (0) | 2019.09.06 |
댓글