[입 개발] Redis 데이터 모델링시에 주의할점

Redis를 사용하는 큰 이유중에 하나가 여러가지 자료구조를 제공해준다는 점입니다. set, list, sorted set, hash 등 그래서, 실제로 유저별 데이터를 prefix:id 또는 id:data_prefix 형태로 데이터를 set/get을 이용하거나 hset/hget/hgetall 등을 이용해서 데이터를 가져옵니다. 사실 이것은 적합한 형태는 서비스의 모델마다 틀리고, 어떤 목적으로 이용할 것인가에 따라서 틀리므로, 서비스에 맞게 설계하고, 사용해보면 됩니다.

예를 들어, 트위터와 비슷한 서비스를 만들때, 팔로워 정보를 list 나 set, sorted set에 넣어둘 수도 있고, hash를 이용할수도 있습니다. 즉 뭘해도 크게 상관이 없다는 것입니다. 바로 찾을 필요가 있다면 hash에 넣을것이고, 전체 순회만 한다면 list를 써도 되는거죠. 그런데, 여기서 놓치기 쉬운 문제가 하나 숨어있습니다.

자 list 나 set 등의 collection 에 친구목록을 넣는다고 합니다. 어떤 유저는 친구가 너무 많아서 백만명이고, 어떤 유저는 몇백명 또는 몇명일 수 있습니다. 그런데 이제 이 사용자가 탈퇴를 해야해서 데이터를 지우려고 합니다. 어떻게 해야할까요?

 del [key]

물론, 위의 형태로 간단하게 삭제가 가능합니다. 그러면 어떤 문제가 발생할까요? 레디스의 철학은 짧은 시간에 지울 수 있는 일만 하자입니다. 그래서 단순히 백만개 정도의 데이터를 지운다고 하면 1초 정도의 시간이 걸립니다. 자 그럼 백만개의 아이템이 들어있는 set을 지우는데는 얼마의 시간이 걸릴까요? 넵 당연히 1초 정도가 걸릴겁니다. 그러면, 이 시간동안 레디스는 다른 작업을 처리할 수 가 없습니다.

그래서 이런 삭제 문제가 사실 레디스에서 처리하기 어려운 문제입니다. 그렇다면 이런 문제는 어떻게 해결해야 할까요? 일단 다음과 같은 룰을 지켜야 합니다. 데이터 콜레션에는 데이터를 일정이상 넘기지 않는다. 많아도 몇천개 정도로 한정합니다. 그리고 이 몇천개의 데이터를 가지는 key 목록에 대해서 다시 한번 목록을 유지합니다.

즉 다음과 같은 형태가 됩니다.
목록(set1, set2, set3)
|
|
set1 —— set2 ——– set3

이걸 특정시간에 다 지우지 않고 한번에 한 set들만 지우는 것입니다. 이래야만 실제로, 하나의 거대한 작업을 쪼개서 처리할 수 있게 됩니다. 이런 테크닉은 사실, 싱글 스레드에서 대량의 데이터를 다뤄야 하는 경우에는, 다른 곳에서도 많이 응용되고 있습니다. 긴 작업은 여러 개의 작은 작업으로 나눠서 단계별로 처리하게 하는것이죠.

Advertisements