Redis
Redis 는 오픈소스로 ANSI C 언어로 작성되었으며 BSD 프로토콜을 준수하고, 네트워크를 지원하며, 메모리 기반, 분산, 선택적 영속성이 있는 키 - 값 (Key-Value) 저장 데이터베이스로, 여러 언어의 API 를 제공하며 Redis 는 NoSQL 데이터베이스로도 사용할 수 있고 고속 캐시 스토리지로도 사용할 수 있으며 간단한 메시지 큐도 지원합니다.
이 문서에서는 Go 언어 드라이버를 사용하여 Redis 데이터베이스를 조작하는 방법만 설명하며, Redis 자체에 대해서는 설명하지 않습니다.
공식 문서: Golang Redis client (uptrace.dev)
공식 저장소: go-redis/redis: Type-safe Redis client for Golang (github.com)
설치
Redis 드라이버는 여러 가지가 있으며, 이 문서에서는 github.com/go-redis/redis를 사용합니다.
Redis 버전이 6 인 경우
go get github.com/go-redis/redis/v8Redis 버전이 7 인 경우
go get github.com/go-redis/redis/v9빠른 시작
go
import (
"fmt"
"log"
"testing"
"github.com/go-redis/redis"
)
func TestQuickStart(t *testing.T) {
// Redis 연결 클라이언트 생성
redisClient := redis.NewClient(&redis.Options{
Addr: "192.168.48.134:6379",
Password: "123456",
DB: 0, // 기본 DB 사용
})
// 키 - 값 쌍 설정, 0 은 만료되지 않음
redisClient.Set("hello", "world", 0)
// 값 읽기
result, err := redisClient.Get("hello").Result()
if err == redis.Nil {
fmt.Println("ket not exist")
} else if err != nil {
log.Panic(err)
}
fmt.Println(result)
}연결 설정
go
type Options struct {
// 네트워크 유형 tcp 또는 unix.
// 기본값은 tcp.
Network string
// redis 주소, 형식 host:port
Addr string
// Dialer 는 새로운 네트워크 연결을 생성하며 Network 와 Addr 옵션보다 우선순위가 높음
// Network and Addr options.
Dialer func() (net.Conn, error)
// 새로운 redis 연결을 생성할 때 호출되는 함수
OnConnect func(*Conn) error
// redis 비밀번호, redis server 에 설정되지 않은 경우 비워둘 수 있음
Password string
// redis 데이터베이스, 인덱스는 0 부터 시작하며 기본값은 0, 설정하지 않아도 됨
DB int
// redis 작업 실패 시 최대 재시도 횟수, 기본값 0.
MaxRetries int
// 최소 재시도 시간 간격.
// 기본값은 8ms ; -1 은 비활성화.
MinRetryBackoff time.Duration
// 최대 재시도 시간 간격
// 기본값은 512ms; -1 은 비활성화.
MaxRetryBackoff time.Duration
// redis 새 연결 타임아웃 시간.
// 기본값은 5 초.
DialTimeout time.Duration
// socket 읽기 타임아웃 시간
// 기본값 3 초.
ReadTimeout time.Duration
// socket 쓰기 타임아웃 시간
WriteTimeout time.Duration
// redis 연결 풀의 최대 연결 수.
// 기본 연결 풀 크기는 cpu 개수 * 10
PoolSize int
// redis 연결 풀의 최소 유휴 연결 수.
MinIdleConns int
// redis 연결의 최대 수명 시간, 기본값은 만료된 연결을 닫지 않음.
MaxConnAge time.Duration
// redis 연결 풀에서 연결을 가져온 후, 연결 풀이 해당 연결을 얼마나 기다릴지.
// 기본값은 ReadTimeout + 1 초.
PoolTimeout time.Duration
// redis 연결 풀이 유휴 연결을 닫는 시간.
// 기본값은 5 분. -1 은 이 설정 항목 비활성화
IdleTimeout time.Duration
// 유휴 연결을 얼마나 자주 확인하는지
// 기본값은 1 분. -1 은 유휴 연결 확인 비활성화
IdleCheckFrequency time.Duration
// 읽기 전용 설정, true 로 설정하면 현재 노드 인스턴스에서 redis 는 쿼리만 가능하고 업데이트 불가.
readOnly bool
// TLS 설정
TLSConfig *tls.Config
}연결 설정
go
// Redis 연결 클라이언트 생성
redisClient := redis.NewClient(&redis.Options{
Addr: "192.168.48.134:6379",
Password: "123456",
DB: 0, // 기본 DB 사용
})연결 닫기
드라이버 내부에서 연결 풀을 관리하므로 작업할 때마다 연결을 닫을 필요가 없습니다.
go
defer redisClient.Close()이 Redis 드라이버는 거의 모든 작업을 캡슐화했으며, Redis 명령과 메서드 이름이 일대일로 대응되므로 기본적으로 Redis 명령 사용법을 알면 드라이버의 해당 메서드도 거의 사용할 수 있습니다.
Redis 명령: redis 명령 매뉴얼
기본 작업
키 삭제
go
redisClient.Set("name", "jack", 0)
fmt.Println(redisClient.Del("name").Result())만료 시간
go
redisClient.Set("name", "jack", 0)
// 만료 시간 설정
redisClient.Expire("name", time.Second*2)
fmt.Println(redisClient.Get("name").Val())
time.Sleep(time.Second * 3)
fmt.Println(redisClient.Get("name").Val())만료 시간 취소
go
redisClient.Set("name", "jack", 2)
// 만료 시간 취소
redisClient.Persist("name")
time.Sleep(time.Second * 2)
fmt.Println(redisClient.Get("name"))만료 시간 조회
go
fmt.Println(redisClient.TTL("name"))
fmt.Println(redisClient.PTTL("name"))이름 변경
go
redisClient.Rename("name", "newName")유형 조회
go
redisClient.Type("name")스캔
go
fmt.Println(redisClient.Scan(0, "", 4))문자열
단순 저장 및 읽기
go
redisClient.Set("token", "abcefghijklmn", 0)
fmt.Println(redisClient.Get("token").Val())일괄 저장 및 읽기
go
redisClient.MSet("cookie", "12345", "token", "abcefg")
fmt.Println(redisClient.MGet("cookie", "token").Val())숫자 증감
go
redisClient.Set("age", "1", 0)
// 증가
redisClient.Incr("age")
fmt.Println(redisClient.Get("age").Val())
// 감소
redisClient.Decr("age")
fmt.Println(redisClient.Get("age").Val())해시 테이블
읽기 및 쓰기 작업
go
// 단일 설정
redisClient.HSet("map", "name", "jack")
// 일괄 설정
redisClient.HMSet("map", map[string]interface{}{"a": "b", "c": "d", "e": "f"})
// 단일 액세스
fmt.Println(redisClient.HGet("map", "a").Val())
// 일괄 액세스
fmt.Println(redisClient.HMGet("map", "a", "b").Val())
// 전체 map 가져오기
fmt.Println(redisClient.HGetAll("map").Val())출력
b
[b <nil>]
map[a:b c:d e:f name:jack]키 삭제
go
// map 의 필드 삭제
redisClient.HDel("map", "a")키 존재 여부 확인
go
// 필드 존재 여부 확인
redisClient.HExists("map", "a")모든 키 가져오기
go
// map 의 모든 키 가져오기
redisClient.HKeys("map")해시 테이블 키 길이 가져오기
go
// map 길이 가져오기
redisClient.HLen("map")해시 테이블 키 - 값 쌍 순회
go
// map 의 키 - 값 쌍 순회
redisClient.HScan("map", 0, "", 1)리스트
요소 수정
go
// 왼쪽에 추가
redisClient.LPush("list", "a", "b", "c", "d", "e")
// 오른쪽에 추가
redisClient.RPush("list", "g", "i", "a")
// 참조 값 앞에 값 삽입
redisClient.LInsertBefore("list", "a", "aa")
// 참조 값 뒤에 값 삽입
redisClient.LInsertAfter("list", "a", "gg")
// 지정된 인덱스의 요소 값 설정
redisClient.LSet("list", 0, "head")길이 액세스
go
// 리스트 길이 액세스
redisClient.LLen("list")요소 액세스
go
// 왼쪽에서 요소 팝
redisClient.LPop("list")
// 오른쪽에서 요소 팝
redisClient.RPop("list")
// 지정된 인덱스의 요소 액세스
redisClient.LIndex("list", 1)
// 지정된 범위의 요소 액세스
redisClient.LRange("list", 0, 1)요소 삭제
go
// 지정된 요소 삭제
redisClient.LRem("list", 0, "a")
// 지정된 범위의 요소 삭제
redisClient.LTrim("list", 0, 1)
// 지정된 범위의 요소 유지
redisClient.LTrim("list", 0, 1)집합
요소 추가
go
// 집합에 요소 추가
redisClient.SAdd("set", "a", "b", "c")
redisClient.SAdd("set2", "c", "d", "e")집합 요소 액세스
go
// 집합의 모든 멤버 가져오기
redisClient.SMembers("set")
// 요소가 집합에 속하는지 확인
redisClient.SIsMember("set", "a")
// count 개의 요소 무작위 반환
redisClient.SRandMemberN("set", 1)
// 집합의 요소 개수 가져오기
redisClient.SCard("set")집합 작업
go
// 주어진 집합의 차집합 반환
redisClient.SDiff("set", "set2")
// 주어진 집합의 차집합을 결과 집합에 저장하고 결과 집합의 길이 반환
redisClient.SDiffStore("store", "set", "se2")
// 주어진 집합의 교집합 반환
redisClient.SInter("set", "set2")
// 주어진 집합의 교집합을 결과 집합에 저장하고 결과 집합의 길이 반환
redisClient.SInterStore("store", "set", "set2")
// 주어진 집합의 합집합 반환
redisClient.SUnion("set", "set2")
// 주어진 집합의 합집합을 결과 집합에 저장하고 결과 집합의 길이 반환
redisClient.SUnionStore("store", "set", "store")요소 삭제
go
// 요소 팝 및 삭제
redisClient.SPop("set")
// N 개 요소 팝 및 삭제
redisClient.SPopN("set", 2)요소 이동
go
// 소스 집합에서 지정된 요소를 대상 집합으로 이동
redisClient.SMove("set", "set2", "a")요소 삭제
go
// 지정된 요소 삭제
redisClient.SRem("set", "a", "b")순회
go
// 집합 순회
redisClient.SScan("set", 0, "", 2)정렬된 집합
요소 추가
go
// 정렬된 집합에 요소 추가
redisClient.ZAdd("ss", redis.Z{
Score: 1,
Member: "a",
}, redis.Z{
Score: 2,
Member: "b",
})요소 순위
go
// 정렬된 집합에서 요소의 순위 반환, 낮은 것에서 높은 것으로 정렬
redisClient.ZRank("ss", "1")
// 정렬된 집합에서 요소의 순위 반환, 높은 것에서 낮은 것으로 정렬
redisClient.ZRevRank("ss", "1")요소 액세스
go
// min 과 max 사이의 멤버 수 반환
redisClient.ZCount("ss", "1", "2")
// 요소의 가중치 반환
redisClient.ZScore("ss", "a")
// 지정된 구간의 요소 반환
redisClient.ZRange("ss", 1, 2)
// min 과 max 사이의 모든 멤버 목록 반환
redisClient.ZRangeByScore("ss", redis.ZRangeBy{
Min: "1",
Max: "2",
Offset: 0,
Count: 1,
})가중치 수정
go
// 해당 요소에 가중치 증가
redisClient.ZIncr("ss", redis.Z{
Score: 2,
Member: "b",
})요소 삭제
go
// 지정된 요소 삭제
redisClient.ZRem("ss", "a")
// 지정된 순위 구간의 요소 삭제
redisClient.ZRemRangeByRank("ss", 1, 2)
// min 과 max 구간의 가중치를 가진 요소 삭제
redisClient.ZRemRangeByScore("ss", "1", "2")스크립트
go
// 스크립트 로드, sha 값 반환
redisClient.ScriptLoad("return 0")
// sha 값으로 스크립트 실행
redisClient.EvalSha("sha", []string{}, "")
// 스크립트 직접 실행
redisClient.Eval("return 0", []string{}, "")
// 스크립트 캐시 지우기
redisClient.ScriptFlush()
// 현재 실행 중인 스크립트 중지
redisClient.ScriptKill()
// 해당 해시 값의 스크립트 존재 여부 확인
redisClient.ScriptExists("")게시 및 구독
go
// 지정된 채널로 메시지 전송
redisClient.Publish("channel", "message")
// 지정된 채널 구독
redisClient.Subscribe("channel")
// 구독 상태 확인
redisClient.PubSubNumSub("channel")