개인의 기록
  • 소개
  • 프로젝트
  • 글
  • 링크

© 2026 newgirok

← 글 목록

Redis Hash — 객체를 필드 단위로 저장하기

2026년 1월 18일
RedisHash객체 저장캐시

사용자 프로필처럼 여러 속성을 가진 객체를 Redis에 저장해야 한다면 Hash가 적합합니다. 전체를 JSON 문자열로 묶지 않고 필드 하나씩 읽고 쓸 수 있어 훨씬 효율적입니다.

기본 명령

HSET / HGET

# 필드 설정 (여러 필드 한 번에 가능)
HSET user:1000 name "철수" email "cs@example.com" role "admin" age 30

# 단일 필드 읽기
HGET user:1000 name
# "철수"

# 여러 필드 읽기
HMGET user:1000 name email
# 1) "철수"
# 2) "cs@example.com"

# 전체 필드 읽기
HGETALL user:1000
# 1) "name"
# 2) "철수"
# 3) "email"
# 4) "cs@example.com"
# 5) "role"
# 6) "admin"
# 7) "age"
# 8) "30"

필드 존재 확인 및 삭제

# 필드 존재 여부
HEXISTS user:1000 email
# 1 (있음)

# 필드 삭제
HDEL user:1000 role

# 전체 필드 목록 / 값 목록 / 개수
HKEYS user:1000     # ["name", "email", "age"]
HVALS user:1000     # ["철수", "cs@example.com", "30"]
HLEN user:1000      # 3

숫자 필드 증감

HSET product:500 stock 100 price 9900

# 재고 1 감소
HINCRBY product:500 stock -1

# 가격 조정
HINCRBYFLOAT product:500 price 500.0

Hash vs String(JSON) 비교

# String(JSON) 방식: 이름 하나 수정에 전체 JSON 교체
SET user:1000 '{"name":"철수","email":"cs@example.com","role":"admin"}'

GET user:1000  # 역직렬화 필요
SET user:1000 '{"name":"영희","email":"cs@example.com","role":"admin"}'

# Hash 방식: 필드 하나만 수정
HSET user:1000 name "영희"

Hash가 유리한 경우:

  • 객체의 일부 필드만 자주 읽는 경우
  • 특정 필드만 자주 업데이트하는 경우
  • 필드에 숫자 연산이 필요한 경우

JSON 직렬화가 유리한 경우:

  • 객체 전체를 항상 한 번에 읽고 쓰는 경우
  • 객체 구조가 중첩되거나 배열을 포함하는 경우

직렬화(Serialization): 객체를 전송하거나 저장할 수 있는 형식(JSON, 바이너리 등)으로 변환하는 과정. Redis Hash는 직렬화 없이 개별 필드에 접근할 수 있습니다.

실전 사례

사용자 세션

HSET session:abc123
  user_id  1000
  name     "철수"
  role     "admin"
  login_at "2026-06-18T09:00:00"

EXPIRE session:abc123 3600

# 세션에서 역할만 조회
HGET session:abc123 role

상품 정보

HSET product:500
  name     "무선 마우스"
  price    29000
  stock    150
  category "전자기기"

# 구매 시 재고 감소
HINCRBY product:500 stock -1

실시간 통계

HSET stats:2026-06-18
  visits      0
  signups     0
  purchases   0

# 방문 시
HINCRBY stats:2026-06-18 visits 1

# 가입 시
HINCRBY stats:2026-06-18 signups 1

# 오늘 통계 조회
HGETALL stats:2026-06-18

주의 사항

Hash의 필드는 문자열만 저장됩니다. 중첩 객체나 배열은 직접 지원하지 않습니다.

# 불가: 중첩 객체
HSET user:1000 address '{"city":"서울","gu":"강남구"}'
# 가능하지만 address 필드 자체는 JSON 문자열이 됨

# 대안: 키 분리
HSET user:1000:address city "서울" gu "강남구"

또한 Hash 내 필드 개수가 수십만 개를 넘어가면 메모리 효율이 떨어집니다. 필드가 128개 이하이고 값이 64바이트 이하인 경우 내부적으로 더 효율적인 ziplist 인코딩을 사용합니다.

ziplist: Redis가 소용량 Hash/List/Set에 적용하는 내부 압축 인코딩. 포인터를 사용하지 않고 연속된 메모리 공간에 데이터를 저장해 메모리를 절약합니다.

← 이전 글Redis List — 순서 있는 목록과 큐 구현
다음 글 →Redis Set — 중복 없는 집합과 집합 연산