티스토리 뷰

728x90
반응형

https://instagram-engineering.com/storing-hundreds-of-millions-of-simple-key-value-pairs-in-redis-1091ae80f74c

 

Storing hundreds of millions of simple key-value pairs in Redis

When transitioning systems, sometimes you have to build a little scaffolding. At Instagram, we recently had to do just that: for legacy…

instagram-engineering.com

 

이 포스팅은 instagram engineering 블로그의 2011년 포스팅을 기반으로 이 내용을 이해하기 쉽게 다시 정리합니다.

 

10년이나 지난 포스팅이지만 지금도 여전히 그 방법론은 유효합니다

 

 

 

무수히 많은 사진이 있는 인스타그램과 같은 서비스가 있다고 가정해봅니다.

 

media ID와 user ID 를 매핑하여

 

특정 media ID로 해당 미디어에 매핑된 user ID를 빠르게 찾아 유저에게 빠른 응답속도를 서비스를 제공하려고 합니다

 

이를 위해 메모리에 데이터를 저장하는 redis를 이용하여

 

key - value 조회를 통해 빠른 응답속도를 제공해보겠습니다

 

 

키는 meida ID를, value는 userID가 되도록 설정합니다

 

SET media:1155315 939
GET media:1155315
> 939

redis를 사용하면 이러한 형태로 set, get 커맨드를 이용하여 저장 및 불러오기를 사용할수 있습니다

 

 

이방식으로 1,000,000(일백만)개의 키를 저장했을때 약 70MB 의 메모리를 사용하게 됩니다

 

사진이 3억개가 있다면 약 21GB 메모를 사용하게 될것입니다

 

 

 

메모리 사용을 좀 더 줄여볼수 없을까요?

 

 

redis 는 메모리를 효율적으로 사용할수 있는 ziplist라고 불리는 해시형태를 제공하는데

 

이를 사용해서 어디까지 메모리 사용이 최적화 되는지 알아봅니다

 

 

redis의 config중에 hash-max-ziplist-entries 는

 

ziplist형태로 저장할 엔트리의 최대 갯수를 지정할수 있습니다

 

이렇게 명령을 입력해보면 현재 해당 환경설정값이 얼마로 설정되어있는지 확인할수 있습니다

config get hash-max-ziplist-entries

기본값은 512로 설정되어있습니다

 

 

인스타그램 엔니지어링 블로그에서는

 

이 환경설정값으로 약 1000이라는 값을 넣는것이 메모리와 cpu의 사용면에서 최적의 숫자라고 찾아습니다

 

 

추가적인 내용은 여기서 더 알아볼수 있습니다

 

https://www.peterbe.com/plog/understanding-redis-hash-max-ziplist-entries

 

Understanding Redis hash-max-ziplist-entries - Peterbe.com

8 January 2018   1 comment   Python, Redis This blog post is 4 years old! Most likely, its content is outdated. Especially if it's technical. This is an advanced topic for people who do serious stuff in Redis. I need to do serious stuff in Redis so I'm t

www.peterbe.com

 

 

이 숫자를 아래의 명령어를 통해 1024로 변경해봅시다

 

config set hash-max-ziplist-entries 1024

 

이제 1024개까지는 ziplist라는 효율적인 스토리지 최적화 형태로 저장이 될것입니다

 

만약 1024를 넘어가는 숫자를 저장하는 경우 메모리 최적화된 저장방법을 사용할수가 없어 메모리 사용이 엄청나게 늘어납니다

 

 

이렇게 설정한 값과 해시타입의 장점을 살리기 위해

 

1000개씩의 media ID를 담는 버킷을 생성할것입니다

 

만약 1155315 라는 media ID를 가지고 있는 경우 1000으로 나눈 몫이 1155 이므로

 

이값이 버킷 번호가 되도록하고

 

HSET의 필드값으로는 media ID를 넣고

 

value 값으로 user ID를 넣습니다

 

HSET "mediabucket:1155" "1155315" "939"
HGET "mediabucket:1155" "1155315"
> "939"

이런식으로 redis 명령어를 사용합니다

 

 

이렇게 저장하면 1백만개의 키는 1000개의 버킷, 각 버킷당 1000개의 서브키로 저장할수가 있다 (1,000 X 1,000 = 1,000,000)

 

 

"mediabucket:1" "1000" "939"

"mediabucket:1" "1001" "939"

"mediabucket:1" "1002" "939"

...

"mediabucket:1" "1999" "939"

"mediabucket:2" "2000" "939"

"mediabucket:2" "2001" "939"

....

 

이런식의 느낌으로 말이죠

 

 

이렇게 1백만개의 키를 저장했을때는 얼만큼의 메모리를 사용했을까요?

 

 

1백만개의 키가 약 16MB에 저장되었습니다 (와우!)

 

약 3억개의 키는 5GB 미만의 메모리에 모두 적재가 된다는 뜻입니다

 

물론 O(1) 시간복잡도로 매우 빠르게 동작합니다

 

 

 

3억개의 미디어-유저 매핑정보를 단 5GB 메모리의 인스턴스에 올려둘수 있다면

 

이렇게 메모리에 올려진 3억개의 미디어정보에 대한 유저정보는 매우 빠르게 찾을수 있겠죠?

 

 

참조

https://instagram-engineering.com/storing-hundreds-of-millions-of-simple-key-value-pairs-in-redis-1091ae80f74c

728x90
반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
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 31
글 보관함