소티드 셋이 헷갈리는 이유는 이름보다도 “일반 Set과 뭐가 다른가”가 바로 떠오르지 않기 때문입니다.
소티드 셋은 중복 없는 집합에 정렬 기준까지 함께 붙인 구조이고, 리더보드, 점수 순위, 예약 작업, Redis ZSET 같은 문제에서 자주 등장합니다.
이 글에서는 아래를 빠르게 정리합니다.
- 소티드 셋이 일반 Set과 무엇이 다른지
- 왜 단순 정렬 배열보다 더 적합한 경우가 있는지
- 리더보드와 스케줄링 예제를 어떻게 읽어야 하는지
- 우선순위 큐와 어떻게 구분하면 좋은지
짧게 말하면 소티드 셋은 순위와 정렬된 조회가 중요한 문제를 풀기 위한 자료 구조라고 보면 이해하기 쉽습니다.
소티드 셋이란 무엇인가?
일반적인 Set은 보통 “중복 없이 보관한다”는 특성에 초점이 있습니다.
소티드 셋은 여기에 한 가지가 더 붙습니다.
- 각 원소가 정렬 기준을 가짐
- 그 기준을 바탕으로 순서 있는 조회가 가능함
실무에서는 보통 “점수(score)“라는 표현을 많이 씁니다.
예를 들어:
- 플레이어와 점수
- 작업과 예약 시각
- 사용자와 우선순위 값
을 함께 관리한다고 생각하면 됩니다.
왜 일반 Set이나 배열 정렬만으로는 부족할까?
처음에는 이렇게 생각할 수 있습니다.
“그냥 배열에 넣고 정렬하면 되지 않나?”
작은 데이터에서는 맞는 말입니다. 하지만 아래 조건이 붙기 시작하면 상황이 달라집니다.
- 데이터가 자주 추가됨
- 기존 항목의 점수가 자주 바뀜
- 상위 10개처럼 범위 조회가 자주 필요함
- 특정 점수 구간만 잘라서 읽어야 함
- 중복 멤버는 막아야 함
이때 소티드 셋은 꽤 자연스러운 모델이 됩니다.
즉, 소티드 셋은 “정렬된 결과를 가끔 보는 배열”보다 정렬 자체가 핵심 기능인 집합에 가깝습니다.
소티드 셋은 언제 사용하는가?
1. 리더보드
점수 높은 순으로 상위 N명을 보여 줘야 하면 소티드 셋이 대표 후보입니다.
2. 예약 작업
실행 시각이 가장 이른 작업부터 처리해야 할 때도 잘 맞습니다.
3. 우선순위 기반 조회
단순 FIFO가 아니라 “우선순위 높은 것부터” 또는 “오래된 것부터”를 정렬 기준으로 삼을 수 있습니다.
4. 점수 범위 조회
예를 들어 1000점 이상 1500점 미만 사용자만 뽑아야 하는 경우도 소티드 셋이 잘 어울립니다.
Redis ZSET으로 소티드 셋을 어떻게 이해할까?
Redis의 소티드 셋은 member + score 조합으로 이해하면 쉽습니다.
member: 고유한 항목score: 정렬 기준
기본 예제
ZADD game:season1 1200 alice
ZADD game:season1 980 bob
ZADD game:season1 1450 chris
ZADD game:season1 1020 diana
위 예제는:
alice,bob,chris,diana를 멤버로 저장하고- 각자 점수를 부여한 뒤
- 점수 기준으로 정렬된 상태를 유지합니다.
상위 3명을 가져오고 싶다면:
ZREVRANGE game:season1 0 2 WITHSCORES
처럼 읽을 수 있습니다.
여기서 실무 감각으로 중요한 것은:
- 멤버는 중복되지 않음
- 점수는 갱신 가능함
- 정렬된 상태를 활용해 순위 조회가 쉬움
입니다.
소티드 셋 예제 1: 게임 리더보드는 어떻게 구현할까?
리더보드는 소티드 셋을 설명할 때 가장 좋은 예제입니다.
예를 들어 사용자 점수가 바뀔 때마다 다시 반영한다고 가정해 보겠습니다.
ZADD leaderboard 500 user:1
ZADD leaderboard 700 user:2
ZADD leaderboard 450 user:3
ZADD leaderboard 900 user:1
ZREVRANGE leaderboard 0 2 WITHSCORES
여기서 user:1은 같은 멤버이므로 새 멤버가 중복 추가되는 것이 아니라 점수가 갱신됩니다.
이 특성 덕분에 리더보드는 아래처럼 다루기 좋습니다.
- 점수 업데이트
- 상위 N명 조회
- 특정 사용자의 순위 확인
- 특정 구간 점수대 사용자 조회
배열을 매번 정렬하는 방식보다 훨씬 문제 구조에 잘 맞습니다.
소티드 셋 예제 2: 예약 작업은 어떻게 다룰까?
소티드 셋은 시간 기반 스케줄링에도 잘 맞습니다.
이 예제를 보면 “먼저 들어온 작업”보다 “먼저 실행해야 할 작업”이 더 중요하다는 점이 드러납니다. 그래서 FIFO가 핵심인 큐 자료 구조 가이드와는 사고 방식이 다릅니다.
실행 시각을 score로 넣으면 됩니다.
ZADD jobs:schedule 1711350000 email:user-1
ZADD jobs:schedule 1711350300 email:user-2
ZADD jobs:schedule 1711350600 cleanup:cache
가장 먼저 실행할 작업을 보려면:
ZRANGE jobs:schedule 0 0 WITHSCORES
를 사용하면 됩니다.
이 패턴이 좋은 이유는:
- 현재 시각보다 이전인 작업만 잘라서 읽을 수 있고
- 가장 이른 작업을 빠르게 찾을 수 있고
- 작업 이름 중복을 피하며 기준값을 관리할 수 있기 때문입니다.
메시지 큐는 보통 “도착 순서”에 강하지만, 예약 작업은 “실행 시각 순서”가 더 중요하므로 소티드 셋이 더 자연스럽습니다.
소티드 셋 예제 3: 우선순위 작업은 어떻게 다룰까?
어떤 작업은 사용자 요청보다 시스템 유지보수 작업이 더 급할 수도 있습니다.
이때는 score를 우선순위 값으로 해석할 수 있습니다.
ZADD tasks:priority 100 backup
ZADD tasks:priority 300 send-critical-alert
ZADD tasks:priority 200 resize-images
ZREVRANGE tasks:priority 0 0 WITHSCORES
이 예제에서는 우선순위가 높은 작업을 먼저 찾을 수 있습니다.
다만 여기서 기억할 점은, “맨 위 작업 하나만 반복해서 꺼내기”가 전부라면 힙 기반 우선순위 큐가 더 직접적인 선택일 수도 있다는 점입니다.
소티드 셋과 우선순위 큐는 무엇이 다를까?
둘은 비슷해 보여서 많이 헷갈립니다.
간단하게 구분하면:
- 우선순위 큐: 가장 높거나 낮은 우선순위 하나를 반복해서 꺼내는 문제에 집중
- 소티드 셋: 정렬된 집합 전체를 유지하고 범위 조회, 순위 조회까지 다루는 문제에 강함
예를 들어:
- “다음 작업 하나만 계속 꺼내기”는 우선순위 큐
- “상위 10명 보여 주기”는 소티드 셋
처럼 생각하면 편합니다.
최근 상태를 추적하는 스택 자료 구조 가이드와도 문제 성격이 완전히 다르다는 점을 같이 기억하면 헷갈림이 줄어듭니다.
소티드 셋과 큐는 무엇이 다를까?
이 차이도 실무에서 중요합니다.
- 큐는 FIFO
- 소티드 셋은 score 기준 정렬
즉, 먼저 들어왔는지가 중요하면 큐가 맞고, 점수나 시간 같은 외부 기준이 더 중요하면 소티드 셋이 맞습니다.
예를 들어:
- 문의 접수 순 처리: 큐
- 점수 높은 사용자 순 노출: 소티드 셋
- 예약 시간 빠른 작업 순 실행: 소티드 셋
입니다.
소티드 셋을 공부할 때 자주 하는 실수는?
1. 소티드 셋을 그냥 Set의 정렬 버전으로만 보는 경우
실제로는 “정렬된 조회”가 핵심 기능입니다. 이 차이를 놓치면 왜 쓰는지 감이 안 옵니다.
2. 배열 정렬과 완전히 같은 것으로 보는 경우
작은 예제에서는 비슷해 보여도, 갱신과 범위 조회가 많아지면 문제 구조가 달라집니다.
3. 큐와 혼동하는 경우
큐는 도착 순서, 소티드 셋은 정렬 기준 순서입니다. 기준 자체가 다릅니다.
4. 우선순위 큐와 같은 것으로 단정하는 경우
겹치는 부분은 있지만, 범위 조회와 순위 조회가 중요하면 소티드 셋이 더 강합니다.
어떤 문제에서 소티드 셋을 먼저 떠올리면 좋을까?
아래 질문에 “예”가 많다면 소티드 셋을 먼저 검토해 볼 수 있습니다.
- 각 항목에 점수나 시간 같은 정렬 기준이 있는가?
- 중복 없는 멤버를 관리해야 하는가?
- 상위 N개 또는 특정 범위 조회가 자주 필요한가?
- FIFO가 아니라 별도 기준 순서가 더 중요한가?
FAQ
Q. Redis를 안 써도 소티드 셋 개념이 중요한가요?
네. Redis 때문에 많이 알려졌을 뿐이고, 랭킹과 정렬 기반 조회 문제를 이해하는 데 자체적으로 중요한 개념입니다.
Q. 소티드 셋과 데이터베이스 정렬은 어떻게 다른가요?
데이터베이스도 정렬 조회를 할 수 있지만, 소티드 셋은 메모리 구조 차원에서 정렬된 집합을 다룬다는 관점이 더 강합니다. 어떤 저장소가 더 적합한지는 시스템 요구사항에 따라 달라집니다.
Q. 면접에서는 어떻게 나올 수 있나요?
랭킹 시스템, 실시간 점수판, 예약 작업, 우선순위 작업 처리 문제와 연결되어 나오는 경우가 많습니다.
Read Next
- FIFO 처리 흐름과 비교해 보고 싶다면 큐 자료 구조 가이드를 같이 보면 좋습니다.
- 최근 상태 복원과 백트래킹 흐름은 스택 자료 구조 가이드에서 대비해서 볼 수 있습니다.
Related Posts
심사 대기 중에는 광고 대신 관련 가이드를 먼저 보여줍니다.
먼저 읽어볼 가이드
검색 유입이 많은 핵심 글부터 이어서 보세요.
- 미들웨어 트러블슈팅 가이드: Redis vs RabbitMQ vs Kafka 개발자를 위한 미들웨어 트러블슈팅 허브 글입니다. Redis, RabbitMQ, Kafka 중 어떤 증상부터 먼저 봐야 하는지와 어떤 문제 패턴이 각 시스템에 가까운지 정리합니다.
- Kubernetes CrashLoopBackOff: 먼저 볼 것들 startup failure, probe, config, resource limit 관점에서 CrashLoopBackOff를 어떻게 나눠서 봐야 하는지 정리한 가이드입니다.
- Kafka consumer lag가 계속 늘 때: 트러블슈팅 가이드 Kafka consumer lag가 계속 늘어날 때 무엇부터 봐야 하는지 정리합니다. poll 주기, 처리 속도, rebalance, consumer 설정까지 실전 기준으로 다룹니다.
- Kafka Rebalancing Too Often 가이드 Kafka consumer group에서 rebalance가 너무 자주 일어날 때 membership flapping, poll timing, protocol, assignment churn을 어떤 순서로 봐야 하는지 설명하는 실전 가이드입니다.
- Docker container가 계속 재시작될 때: 먼저 확인할 것들 exit code, command failure, environment mistake, health check 관점에서 Docker restart loop를 푸는 실전 가이드입니다.
심사 대기 중에는 광고 대신 관련 가이드를 먼저 보여줍니다.