1) List형 개요
정의: 문자열(String)의 순서 있는 컬렉션. 앞/뒤에 값을 넣고 빼는 데 최적화(스택/큐 가능).
특징
삽입 순서 유지
양 끝단(왼쪽/오른쪽)에서 O(1)에 가까운 연산 제공
주요 유스케이스
스택/큐 구현
SNS/뉴스 피드(최신 N개 보여주기)
작업 대기열(간단한 워커 큐)
주의
중간 인덱스 접근·삽입/삭제는 O(N) → 데이터가 크면 느릴 수 있음
“애플리케이션에서 정말 리스트로 풀어야 하는가?”(예: 정렬/검색/필터가 많다면 다른 자료구조 검토)
2) 기본 작동 이미지(개념)
왼쪽/오른쪽 양 끝으로 PUSH(삽입), POP(제거)
왼쪽 = head, 오른쪽 = tail (편의상 그렇게 부름)
인덱스: 0이 왼쪽 첫 요소, -1이 오른쪽 마지막 요소
3) 핵심 명령어 요약표
명령 설명 시간복잡도(대략)
LPUSH / RPUSH 왼쪽/오른쪽에 값 삽입 O(1) amortized
LPOP / RPOP 왼쪽/오른쪽에서 값 꺼내기(6.2+ count 지원) O(1) amortized (count는 O(m))
BLPOP / BRPOP POP의 블로킹 버전(대기) O(1) / 타임아웃 고려
LMPop / BLMPOP 여러 리스트에서 한 번에 꺼내기(7.0+) O(m)
LINDEX 인덱스 위치 값 조회 O(N)
LINSERT 피벗 앞/뒤에 삽입 O(N)
LLEN 길이 O(1)
LRANGE 구간의 요소 반환 (양 끝 포함) O(S+N)
LREM 값 제거(최대 count개) O(N+M)
LSET 인덱스 위치 값 설정(덮어쓰기) O(N)
LTRIM 구간만 남기고 나머지 제거 O(N)
LPOS 값의 위치 찾기(옵션: RANK, COUNT, MAXLEN) O(N)
LMOVE / BLMOVE 한 리스트 ↔ 다른 리스트 사이로 이동 O(1)
LPUSHX / RPUSHX 리스트가 존재할 때만 push O(1)
폐지 예정(대체 제공): RPOPLPUSH / BRPOPLPUSH → LMOVE / BLMOVE로 대체
4) 필수 명령어 자세히 + 예제
4.1 삽입/삭제(PUSH/POP)
LPUSH mylist "foo" "bar" "baz" # 결과: ["baz","bar","foo"]
RPUSH mylist "A" "B" # 결과: ["baz","bar","foo","A","B"]
LPOP mylist # "baz"
RPOP mylist # "B"
LPOP mylist 2 # ["bar","foo"]
RPUSH mylist 1 2 3 4 5 # ["A",1,2,3,4,5]
RPOP mylist 3 # [5,4,3]
LPUSH/ RPUSH는 여러 값을 한 번에 넣을 수 있어요.
LPOP/RPOP (count) 로 일괄 소비 가능(배치 처리에 유용).
4.2 범위 조회/유지관리(LRANGE/LTRIM)
LRANGE timeline 0 2 # 처음 3개
LRANGE timeline -3 -1 # 마지막 3개
LTRIM timeline 0 99
피드/타임라인에서 “최신 N개만 유지하기”에 LTRIM이 표준 패턴.
4.3 개별 조회/수정(LINDEX/LSET/LINSERT/LLEN)
LINDEX mylist 0 # 첫 요소
LINDEX mylist -1 # 마지막 요소
LSET mylist 2 "hello"
LINSERT mylist BEFORE "foo" "new-left"
LINSERT mylist AFTER "foo" "new-right"
LLEN mylist
중간 접근/삽입은 O(N) → 커지면 부담. 극단적 중간 조작이 많으면 List보다 다른 타입을 고려.
4.4 값 제거/검색(LREM/LPOS)
LREM mylist 0 "to-delete" # 모든 "to-delete" 제거
LPOS mylist "x"
LPOS mylist "x" RANK 2
LPOS mylist "x" COUNT 3
LPOS mylist "x" MAXLEN 1000
LPOS는 “N번째 발생” 같은 세밀 검색을 지원.
4.5 여러 리스트 간 이동(LMOVE/BLMOVE)
LMOVE source dest LEFT RIGHT
BLMOVE source dest LEFT RIGHT TIMEOUT 5
예전의 RPOPLPUSH/BRPOPLPUSH를 완전히 대체.
4.6 블로킹 POP (BLPOP/BRPOP) & 멀티 팝(LMPOP/BLMPOP)
BLPOP queue 5
BLPOP queue1 queue2 0 # 0이면 무기한 대기
LMPOP 2 list1 list2 LEFT COUNT 3
BLMPOP 2 list1 list2 LEFT COUNT 3 TIMEOUT 10
워커/컨슈머 패턴에서 프로듀서-컨슈머 동기화에 유용.
4.7 존재할 때만 삽입(LPUSHX/RPUSHX)
LPUSHX mylist "only-if-exists"
RPUSHX mylist "only-if-exists"
5) 실무 패턴 모음
5.1 FIFO 큐(작업 대기열)
RPUSH jobs '{"id":1}' '{"id":2}'
BLPOP jobs 0 # 반환: (jobs, '{"id":1}')
장점: 구현 간단, 처리량 높음
주의: 멱등성 보장(중복 처리 대비), 장애 시 재처리 전략 필요
5.2 최신 N개 타임라인
LPUSH timeline "post-123"
LTRIM timeline 0 99 # 최신 100개만 유지
LRANGE timeline 0 9 # 클라이언트에 최근 10개 응답
읽기 빠르고, 메모리 예측 가능.
5.3 큐 간 이동(파이프라인/재시도)
LMOVE pending processing LEFT RIGHT
LMOVE processing pending RIGHT LEFT
간단한 가시성 타임아웃 비슷한 패턴을 구현할 수 있음(도큐먼트/스케줄러 보완 필요).
6) 성능 & 메모리 & 안정성 팁
항상 키 크기 관리: 무한히 커지지 않게 LTRIM/만료(PEXPIRE) 조합 고려.
네트워크 왕복 최소화: 파이프라이닝(클라이언트 측) 적극 활용.
메모리 정책(캐시로 쓸 때): maxmemory + maxmemory-policy(예: allkeys-lru) 설정.
AOF/RDB: 영속 필요 시 AOF(appendonly yes) 또는 RDB 스냅샷(save) 선택·병행.
보안: requirepass/ACL, bind, protected-mode, 보안그룹/방화벽 필수.
블로킹 명령은 워커 수/시간초과 값을 신중히 → 과도한 대기는 스레드/커넥션 고갈 유발.
중간 조작 많으면 List 대신 Sorted Set/Stream 고려(예: 시간순 정렬/다건 조회·필터).
7) 빠른 치트시트(복붙용)
LPUSH k a b c # c,b,a + 기존
RPUSH k a b c # 기존 + a,b,c
LPUSHX k v # k가 있을 때만
LPOP k [count]
RPOP k [count]
LREM k count value # 0=전부, >0 왼쪽→, <0 오른쪽←
LLEN k
LINDEX k idx # idx: 0, -1 가능
LRANGE k start stop # stop 포함, -1=끝
LSET k idx value
LINSERT k BEFORE|AFTER pivot value
LTRIM k start stop # 범위 밖 요소 제거
LPOS k value [RANK n][COUNT c] [MAXLEN m]
LMOVE src dst LEFT|RIGHT LEFT|RIGHT
BLMOVE src dst LEFT|RIGHT LEFT|RIGHT TIMEOUT t
BLPOP k1 [k2 ...] timeout
BRPOP k1 [k2 ...] timeout
LMPOP numkeys k1 ... LEFT|RIGHT [COUNT n]
BLMPOP numkeys k1 ... LEFT|RIGHT [COUNT n] TIMEOUT t
필요하시면 위 내용을 PDF 한 장짜리 치트시트 또는 사내 위키용 문서로도 바로 만들어 드릴게요.
또, Spring + Redis(List) 예제 코드(lettuce/jedis)도 같이 드릴 수 있어요—어떤 형식이 좋을까요?