redis-cli로 핵심 명령 실습(STRING/LIST/SET/HASH/ZSET)sudo apt update
sudo apt install -y redis-server
sudo systemctl status redis-server --no-pager
redis-server --version
redis-cli ping
PONGss -lntp | grep 6379 || sudo lsof -i:6379
redis-cli
HELP
COMMAND COUNT
COMMAND INFO GET SET
INFO
INFO server
INFO memory
CONFIG GET *
CONFIG GET dir
CONFIG GET appendonly
운영에서는 KEYS * 금지(블로킹). 실습에서는 데이터가 적으므로 비교 용도만.
KEYS *
SCAN 0 MATCH * COUNT 10
FLUSHDB : 현재 DB 삭제
FLUSHALL : 모든 DB 삭제
설명
select 0~15로 DB(저장공간) 변경가능FLUSHALL은 모든 DB를 삭제하므로 실습에서는 FLUSHDB 권장[용도] : [도메인] : [식별자]
예시:
session:SID123
cache:product:100
cart:user:1001
view:product:100
📌 목적
SCAN 0 MATCH cache:product:*
Redis에는 테이블 개념이 없음.
cache:product:100
product:100
SET user:1:name "kim" // user:1:name이라는 키에 문자열 "kim" 저장
GET user:1:name
INCR page:view // page:view 값을 1 증가
GET page:view
MSET k1 v1 k2 v2 // 여러 키를 한 번에 저장
MGET k1 k2 // 여러 키를 한번에 조회
과제
SET counter 0 후 INCR counter 5회 실행하고 결과 확인DEL queue:email // 기존 리스트 키 삭제
LPUSH queue:email "mail1" "mail2" "mail3" //리스트 왼쪽(Head) 에 데이터 삽입
LRANGE queue:email 0 -1 // 리스트 전체 조회
RPOP queue:email // 리스트 오른쪽(Tail) 에서 데이터 하나 제거 후 반환
LRANGE queue:email 0 -1 // 데이터 확인
LRANGE 0 -1: 리스트 전체 출력
LRANGE 시작 끝: 0 ,1 번째 리스트 값 출력
-1: 리스트의 마지막 인덱스를 의미
-1: 마지막에서 두 번째 요소의 인덱스를 의미
LPUSH,RPUSH,LPOP,RPOP은 존재하지만RRANGE명령어는 존재하지 않는다.
블로킹 pop(워크 큐 스타일)
터미널 2개를 준비하세요.
redis-cli
BLPOP queue:job 0
queue:job 리스트에 값이 들어올 때까지 대기0은 무한 대기 의미redis-cli
LPUSH queue:job "job1"
터미널 A가 즉시 job을 받는지 확인.
과제
LPUSH/RPUSH 조합으로 “FIFO 큐” 구성해보기SADD class:students "kim" "lee" "park" "kim" // "kim"은 중복이므로 한 번만 저장
SMEMBERS class:students // 집합에 저장된 모든 값 조회, 순서 보장 X
SISMEMBER class:students "kim" // "kim"이 집합에 있는지 확인, 1(있음) 2(없음)
SCARD class:students // 집합에 포함된 원소 개수 반환
SREM class:students "park" // "park"를 집합에서 제거
SMEMBERS class:students
집합 연산
SADD class:A "kim" "lee"
SADD class:B "lee" "choi"
SINTER class:A class:B // 교집합 (공통 요소) → "lee"
SUNION class:A class:B // 합집합 (전체 요소)
SDIFF class:A class:B // 차집합 (A에는 있고 B에는 없는 값)
HSET user:1 name "kim" age "29" role "student" // 하나의 키(user:1)에 여러 필드-값 저장, JSON과 유사한 구조
HGET user:1 name // 특정 필드 값만 조회
HGETALL user:1 // 해당 키의 모든 필드와 값 조회
HINCRBY user:1 login_count 1 // login_count 필드를 생성 후 1 증가
HINCRBY user:1 login_count 1 // login_count 1 -> 2
HGET user:1 login_count // 최종 로그인 횟수 조회
과제
user:2를 만들고 필드 3개 이상 저장 후 HGETALL 출력HSET user:2 name "lee" age "30" role "student"
HGETALL user:2
ZADD ranking 100 "alice" 80 "bob" 120 "chris" // ranking이라는 ZSET에 데이터 추가, 숫자(score)를 기준으로 자동 정렬됨
ZRANGE ranking 0 -1 WITHSCORES // 점수 오름차순 정렬 결과 조회
ZREVRANGE ranking 0 -1 WITHSCORES // 점수 내림차순 정렬 결과 조회 (랭킹용)
ZINCRBY ranking 30 "bob" // "bob"의 점수를 +30 증가
ZREVRANGE ranking 0 -1 WITHSCORES // 점수 변경 후 순위 자동 재정렬 확인
ZREVRANGE ranking 0 2 WITHSCORES // 점수가 높은 순으로 상위 3개 조회
SET session:abc "user1" // 세션 데이터 저장
EXPIRE session:abc 60 // 60초 뒤 자동 삭제 설정
TTL session:abc // 남은 TTL 시간(초 단위) 확인
GET session:abc // TL 만료 전이면 값 반환, 만료 후면 (nil) 반환
SETEX otp:001 30 "123456" // 값을 저장하면서 TTL(초) 동시에 설정
TTL otp:001 // 남은 시간 확인
PSETEX otp:ms 5000 "999999" // TTL을 밀리초(ms) 단위로 설정
PTTL otp:ms // 남은 시간을 ms 단위로 확인
상황: “DB 조회 결과를 Redis에 10초 캐싱”
DEL cache:product:100 // 기존 캐시 삭제
GET cache:product:100 // 값 없음 → 캐시 미스(Cache Miss)
SET cache:product:100 "{'name':'mouse','price':12000}" // DB 조회 결과를 Redis에 저장
EXPIRE cache:product:100 10 // 10초 뒤 자동 삭제
TTL cache:product:100 // 캐시 만료까지 남은 시간 확인
GET cache:product:100 // TTL 만료 전 → 캐시 히트(Cache Hit)
Redis 설정 파일 위치(우분투 패키지 기본):
/etc/redis/redis.conf/var/lib/redissudo grep -E "^(save|appendonly|appendfsync|dir|dbfilename)" /etc/redis/redis.conf
sudo egrep "^(save|appendonly|appendfsync|dir|dbfilename)" /etc/redis/redis.conf

appendonly no: AOF 비활성화 상태
또는 redis-cli에서:
redis-cli CONFIG GET save
redis-cli CONFIG GET appendonly
redis-cli CONFIG GET dir
수동 저장:
redis-cli SAVE
백그라운드 저장:
redis-cli BGSAVE
RDB 파일 위치 확인:
redis-cli CONFIG GET dir
redis-cli CONFIG GET dbfilename
sudo ls -al /var/lib/redis
복구 실습(안전하게 진행)
redis-cli FLUSHDB
redis-cli SET rdb:test "hello"
redis-cli BGSAVE
sudo systemctl stop redis-server
sudo ls -al /var/lib/redis
sudo systemctl start redis-server
redis-cli GET rdb:test
sudo cp /etc/redis/redis.conf /etc/redis/redis.conf.bak
sudo sed -i 's/^appendonly no/appendonly yes/' /etc/redis/redis.conf
sudo sed -i 's/^# appendfsync everysec/appendfsync everysec/' /etc/redis/redis.conf
sudo systemctl restart redis-server
sudo ls -al /var/lib/redis
redis-cli CONFIG GET appendonly
AOF 재작성(압축)
redis-cli BGREWRITEAOF
INFO memory
MEMORY STATS
MEMORY USAGE user:1
redis-cli MONITOR
CONFIG SET slowlog-log-slower-than 10000
CONFIG SET slowlog-max-len 128
SLOWLOG LEN
SLOWLOG GET 10
INFO clients
CLIENT LIST
sudo grep -E "^(bind|protected-mode|requirepass)" /etc/redis/redis.conf
bind 127.0.0.1 ::1 유지 권장sudo sed -i 's/^# requirepass .*/requirepass StrongPassw0rd!/' /etc/redis/redis.conf
sudo systemctl restart redis-server
접속 테스트:
redis-cli ping
# (NOAUTH 에러 기대)
redis-cli -a 'StrongPassw0rd!' ping
sudo ufw status
sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw deny 6379/tcp
sudo ufw status
아래는 노션에 그대로 붙여넣기 가능한 Redis Master–Replica 복제 실습 교안입니다.
(우분투 기준, 2대 VM 또는 1대에서 포트만 다르게 2인스턴스 모두 제공)
192.168.80.110192.168.80.1206379sudo apt update
sudo apt install -y redis-server
redis-server --version
서비스 상태 확인:
sudo systemctl status redis-server --no-pager
UFW를 쓰는 경우(예시):
sudo ufw allow 6379/tcp
sudo ufw status
서로 통신 확인(Replica → Master):
nc -zv 192.168.80.110 6379
설정 파일:
sudo vi /etc/redis/redis.conf
아래 항목을 찾아 수정/확인:
bind 0.0.0.0
port 6379
protected-mode yes
requirepass StrongPassw0rd!
# (선택) 실습 중 위험 명령 막기 - 운영용 권장
# rename-command FLUSHALL ""
# rename-command FLUSHDB ""
재시작:
sudo systemctl restart redis-server
외부 접속 확인(로컬에서):
redis-cli -a StrongPassw0rd! PING
# PONG
Master 역할 확인:
redis-cli -a StrongPassw0rd! INFO replication | egrep "role|connected_slaves"
# role:master
# connected_slaves:0
설정 파일:
sudo vi /etc/redis/redis.conf
아래 항목을 찾아 수정/확인:
bind 0.0.0.0
port 6379
protected-mode yes
requirepass StrongPassw0rd!
# Master 인증 (Master에 requirepass가 있을 때 필수)
masterauth StrongPassw0rd!
# 복제 대상 지정 (중요)
replicaof 192.168.80.110 6379
재시작:
sudo systemctl restart redis-server
Replica 역할 확인:
redis-cli -a StrongPassw0rd! INFO replication | egrep "role|master_host|master_link_status"
정상 출력 예:
role:slave
master_host:192.168.80.110
master_link_status:up
Master에서 Replica 연결 확인:
redis-cli -a StrongPassw0rd! INFO replication | egrep "connected_slaves|slave0"
Master에서:
redis-cli -a StrongPassw0rd! SET demo:key "hello"
redis-cli -a StrongPassw0rd! INCR demo:counter
redis-cli -a StrongPassw0rd! INCR demo:counter
redis-cli -a StrongPassw0rd! GET demo:key
redis-cli -a StrongPassw0rd! GET demo:counter
Replica에서:
redis-cli -a StrongPassw0rd! GET demo:key
redis-cli -a StrongPassw0rd! GET demo:counter
기대 결과:
demo:key → "hello"demo:counter → "2"Replica에서:
redis-cli -a StrongPassw0rd! SET replica:write "no"
기대 결과:
(error) READONLY You can't write against a read only replica.
Replica에서:
redis-cli -a StrongPassw0rd! REPLICAOF NO ONE
확인:
redis-cli -a StrongPassw0rd! INFO replication | egrep "role|master_host"
# role:master
이제 Replica였던 서버에서 쓰기 가능:
redis-cli -a StrongPassw0rd! SET now:master "ok"
Replica(전환된 서버)에서:
redis-cli -a StrongPassw0rd! REPLICAOF 192.168.80.110 6379
bind를 내부망 IP로 제한하거나 보안그룹/방화벽으로 제한requirepass 설정masterauth 설정Replica에서:
redis-cli -a StrongPassw0rd! INFO replication | egrep "master_link_status|master_last_io_seconds_ago|master_host"
Master에서:
redis-cli -a StrongPassw0rd! INFO replication | egrep "connected_slaves|slave0"
로그 확인:
sudo journalctl -u redis-server -n 200 --no-pager
자주 원인:
bind 127.0.0.1로 외부 접속 불가requirepass는 있는데 Replica에 masterauth 누락