순위가 동률일 때의 처리에 대해 질문드립니다.
10
1 asked
안녕하세요, 강의 잘 듣고 있습니다. 양질의 강의 감사드립니다.
Sorted Set을 활용한 리더보드 강의 시청 후 궁금한 점이 생겨 질문 남깁니다.
Redis 공식 문서에 따르면 Score가 동률일 때 사전순(lexicographical)으로 처리된다고 명시되어 있는데요, 실제 비즈니스 환경에서는 사전순이 아닌 여러 기준을 복합적으로 비교해야 하는 경우가 많을 것 같습니다.
Score가 64비트 부동소수점임을 활용해, 자릿수별로 기준을 나누는 방안(예: 1~8자리는 기본 점수, 9~12자리는 2순위 기준, 13~15자리는 3순위 기준 ...)도 생각해 보았습니다. 다만 동률 비교 기준이 많아지거나 기본 점수 자체가 클 경우 double 정밀도 한계로 인해 적용이 어렵겠다는 생각이 들었습니다.
실무에서는 이러한 복잡한 동률 상황을 어떤 방식으로 처리하는지 팁을 여쭤봐도 될까요?
감사합니다.
Answer 2
0
안녕하세요. 실무에서 부딪힐 만한 좋은 질문 주셨네요. 😊
여러 방안이 있을 수 있겠습니다.
1. 공동 순위로 처리
화면 표시 순서는 애플리케이션에서 담당.(예: 달성 시간, 닉네임 가나다순 등)
가장 심플. 안전. 권장.
(ZSet의 순위에 영향을 주는게 아니니 깔끔함)
(공동순위로 하고 화면 표시만 다르게 해도 대부분의 서비스에서 허용 가능)
2. 먼저 달성한 사람을 상위 순위로
점수 + 시간을 하나의 score로 인코딩합니다.
score = 실제점수 * scale + (scale - custom_timestamp)
scale
두 값의 자릿수를 분리하는 상수
custom_timestamp 최댓값보다 커야 함(ex: 10⁹)
custom_timestamp
먼저 달성한 사람이 더 작은 값이 되도록 해서 높은 순위가 되도록 함
계산식: 점수 달성 시각 - 기준 시각(ex: 서비스 출시일)
Unix timestamp를 그대로 사용하면, 초 단위로도 10자리라서 scale을 더 크게 잡아야 하고,그만큼 ZSET score의 double 정밀도 한계(~10¹⁵)에서 실제점수에 쓸 수 있는 자릿수가 줄어듦. 따라서 기준 시점을 서비스 출시일로 잡으면 custom_timestamp가 8~9자리로 줄어들어 정밀도 예산을 아낄 수 있음.
3. 3개 이상의 기준 필요시 (1)
말씀하신 대로 자릿수를 잘게 쪼개는 방식은 정밀도 한계 때문에 빠르게 무너질 수 있습니다. 이때는 Redis와 다른 자료구조의 역할을 분리하는 것을 생각해 볼 수 있습니다.
ZSET: 1차 정렬 기준만 score에 저장 (ex: 점수)
Hash 또는 RDBMS: 멤버별 상세 정보 저장 (2차·3차 기준)
이후 조회 흐름 (페이징 / Top-N 조회)
1) ZSET에서 1차 기준으로 해당 페이지에 해당하는 Top-N 후보 조회 (동점이 많을 수 있는 것을 감안해서 보여줄 개수보다 여유 있게 가져오기)
2) Hash 또는 RDBMS에서 후보들의 상세 정보 조회. (RDBMS 사용 시 IN 절 인덱스 쿼리 필수)
3) 애플리케이션에서 전체 기준으로 최종 정렬 후 페이지 단위로 응답
4. 3개 이상의 기준 필요시 (2)
순위에 영향을 주는 여러 요인을 서비스 내부 공식을 따로 만들어서 최종 계산 값을 score로 사용
기타 여러 방안이 있을 수 있겠으나, 대체로 이 범위 안에서 해결 할 수 있을거 같습니다.
좋은 질문 감사합니다. 화이팅입니다. 👍
0
안녕하세요, 인프런 AI 인턴입니다. Dong wook Kang님.
강의 잘 듣고 계시다니 기쁩니다. Redis의 Sorted Set을 사용하여 리더보드를 구현하는 과정에서, 동률에 대한 처리는 매우 중요하고 실제 비즈니스 환경에서는 다양한 요구사항이 있을 수 있습니다.
동률 처리 방법:
보조 정렬 기준 추가: 흔히 사용하는 방법은 추가적인 정렬 기준을 만들어 단일 점수로 활용하는 것입니다. 이를 위해 여러 속성을 결합한 복합 점수를 생성하고, 이를 점수로 사용하는 방식을 취할 수 있습니다.
멀티필드 데이터 구조 활용: 기본적으로 Sorted Set에 점수와 ID만 저장하고, 실제 데이터와 비교 기준은 별도의 해시(Hash)로 관리하여 필요 시 추가적인 정렬을 구현하는 것도 한 방법입니다.
데이터베이스의 보조 방식 활용: Redis가 아닌 다른 데이터 저장소(SQL 등)의 기능을 활용하는 방법도 있습니다. Redis에서 기본적인 점수 기반의 빠른 정렬/검색을 수행한 후, 세부 정렬은 다른 곳에서 처리할 수 있습니다.
스코어 변환: 예를 들어, 특정 점수 동률일 때 각 항목의 마지막 업데이트 시간이나 사용자 ID와 같은 추가 속성을 결합하여 64비트 점수로 변환하여 사용하면 복합적인 정렬 기준을 구현할 수 있습니다.
정밀도 문제 처리: 부동소수점으로 인한 정밀도의 한계가 있을 경우, 점수나 다른 기준을 정수형으로 변환하여 처리하거나, 고유의 단위를 사용하여 상대적인 크기를 나타내는 방법을 적용할 수 있습니다.
실무 예시 및 구현 팁:
복합적인 문제를 해결하는 방법은 실제 비즈니스 로직 및 데이터 특성에 따라 달라질 수 있습니다. 중요한 것은 이러한 처리 방식을 도입할 때 성능 저하가 발생하지 않도록 적절히 설계하는 것입니다. 정밀도가 요구되면, 로직의 일부를 애플리케이션 레벨에서 수행할 수도 있습니다.
자세한 구현과 관련된 내용으로는 Redis Container 해킹 및 다른 Redis 활용 사례들을 참고하시면 더욱 도움이 될 수 있습니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
Singleton 관련 질문입니다.
1
27
2
Service Create/Update Record 운용과 Delete Record 미운용의 차이 질문
0
18
1
조회속도 개선에서 더 개선하는 방법이 궁금합니다.
0
28
2
라우팅 테이블 설정 중 궁금한게 있습니다.
0
34
1
user-service jwt
0
32
2
애그리거트 질문있습니다!
0
31
2
Redlock 알고리즘 관해 궁금한게 있습니다!
0
47
2
좋아요/조회수 카운팅 병목현상에 대해서 궁금한점이 있습니다.
0
35
2
Agent Builder 서비스가 보이지 않아요
0
28
1
Build 관련 문제 (테스트 관련 문제)
0
43
2
consumer에서 에러가 발생할 경우 데이터 유실 문의
0
38
2
게시글 테스트 데이터 삽입
0
43
2
강의가 검은 화면으로 나옵니다.
0
48
1
mysql 의 bitmap
0
37
1
주제영역3 데이타 조회 문의
0
36
2
인덱스 관련 질문 있습니다.
0
68
2
비관적 락 구현 방식 문의 건
0
70
2
강의노트는 제공 안해주시는 게 맞나요?
0
48
1
[개발 환경 준비 인증하기] 미션 제출 방법 문의
0
66
3
백엔드 서버 코드 변경에서 프론트엔드 서버가 값을 파싱하지 못하는 문제
0
83
1
강사님 GETDEL 관련해서 질문 있습니다
0
94
2
비밀번호를 걸고 실행된 레디스 서버에 lua 스크립트를 등록하는 경우
0
78
2
보안 설정을 한 수강생들은 Connection Settings에 비밀번호를 넣어야 추가되네요
0
61
2
Redis Container 해킹
0
106
1

