国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Go語言之 go-redis 基本使用

這篇具有很好參考價(jià)值的文章主要介紹了Go語言之 go-redis 基本使用。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

Go語言之 go-redis 基本使用

Redis 介紹

Redis:https://redis.io/

Redis 中文網(wǎng):https://www.redis.net.cn/

REmote DIctionary Server(Redis) 是一個(gè)由Salvatore Sanfilippo寫的key-value存儲系統(tǒng)。

Redis是一個(gè)開源的使用ANSI C語言編寫、遵守BSD協(xié)議、支持網(wǎng)絡(luò)、可基于內(nèi)存亦可持久化的日志型、Key-Value數(shù)據(jù)庫,并提供多種語言的API。

它通常被稱為數(shù)據(jù)結(jié)構(gòu)服務(wù)器,因?yàn)橹担╲alue)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等類型。

macOS 安裝Redis

brew install redis

Windows 安裝 Redis

下載地址:https://github.com/dmajkic/redis/tags/

https://github.com/ServiceStack/redis-windows

https://github.com/microsoftarchive/redis/releases

go-redis 使用

安裝 go-redis 庫 https://github.com/redis/go-redis

go get github.com/redis/go-redis/v9

Go-Redis 中文文檔:https://redis.uptrace.dev/zh/

安裝

go-redis 支持 2 個(gè)最新的 go 版本且依賴Go modules,如果 你還沒有 go mod,你需要首先初始化:

go mod init github.com/my/repo

安裝 go-redis/v9 (支持所有的 redis 版本):

go get github.com/redis/go-redis/v9

#連接到 Redis 服務(wù)器

連接到 Redis 服務(wù)器示例,更多配置參數(shù),請參照 redis.Options:

import "github.com/redis/go-redis/v9"

rdb := redis.NewClient(&redis.Options{
	Addr:	  "localhost:6379",
	Password: "", // 沒有密碼,默認(rèn)值
	DB:		  0,  // 默認(rèn)DB 0
})

同時(shí)也支持另外一種常見的連接字符串:

opt, err := redis.ParseURL("redis://<user>:<pass>@localhost:6379/<db>")
if err != nil {
	panic(err)
}

rdb := redis.NewClient(opt)

#使用 TLS

你需要手動設(shè)置 tls.Config,你可以在 這里 了解相關(guān) tls.Config更多的配置信息:

rdb := redis.NewClient(&redis.Options{
	TLSConfig: &tls.Config{
		MinVersion: tls.VersionTLS12,
		ServerName: "you domain",
		//Certificates: []tls.Certificate{cert}
	},
})

如果你使用的是域名連接,且遇到了類似 x509: cannot validate certificate for xxx.xxx.xxx.xxx because it doesn't contain any IP SANs的錯(cuò)誤 ,應(yīng)該在 ServerName 中指定你的域名:更多詳情請參考本鏈接

rdb := redis.NewClient(&redis.Options{
	TLSConfig: &tls.Config{
		MinVersion: tls.VersionTLS12,
		ServerName: "你的域名",
	},
})

#SSH 方式

使用 SSH 協(xié)議連接:

sshConfig := &ssh.ClientConfig{
	User:			 "root",
	Auth:			 []ssh.AuthMethod{ssh.Password("password")},
	HostKeyCallback: ssh.InsecureIgnoreHostKey(),
	Timeout:		 15 * time.Second,
}

sshClient, err := ssh.Dial("tcp", "remoteIP:22", sshConfig)
if err != nil {
	panic(err)
}

rdb := redis.NewClient(&redis.Options{
	Addr: net.JoinHostPort("127.0.0.1", "6379"),
	Dialer: func(ctx context.Context, network, addr string) (net.Conn, error) {
		return sshClient.Dial(network, addr)
	},
	// SSH不支持超時(shí)設(shè)置,在這里禁用
	ReadTimeout:  -1,
	WriteTimeout: -1,
})

#dial tcp: i/o timeout

當(dāng)你遇到 dial tcp: i/o timeout 錯(cuò)誤時(shí),表示 go-redis 無法連接 Redis 服務(wù)器,比如 redis 服務(wù)器沒有 正常運(yùn)行或監(jiān)聽了其他端口,以及可能被防火墻攔截等。你可以使用一些網(wǎng)絡(luò)命令排查問題,例如 telnet:

telnet localhost 6379
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused

如果你使用 Docker、Kubernetes、Istio、Service Mesh、Sidecar 方式運(yùn)行,應(yīng)該確保服務(wù)在容器完全可用后啟 動,你可以通過參考該地址、Readiness Gate、Istio holdApplicationUntilProxyStarts等。

Context 上下文

go-redis 支持 Context,你可以使用它控制 超時(shí) 或者傳遞一些數(shù)據(jù), 也可以 監(jiān)控 go-redis 性能。

ctx := context.Background()

go-redis 實(shí)操 https://pkg.go.dev/github.com/go-redis/redis

安裝

Code/go/redis_demo via ?? v1.20.3 via ?? base 
? go get github.com/redis/go-redis/v9
go: downloading github.com/redis/go-redis/v9 v9.0.5
go: downloading github.com/redis/go-redis v6.15.9+incompatible
go: downloading github.com/cespare/xxhash/v2 v2.2.0
go: downloading github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f
go: added github.com/cespare/xxhash/v2 v2.2.0
go: added github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f
go: added github.com/redis/go-redis/v9 v9.0.5

Code/go/redis_demo via ?? v1.20.3 via ?? base took 2.4s 
? 

連接 Redis 服務(wù)器并初始化

package main

import (
	"context"
	"fmt"
	"github.com/redis/go-redis/v9"
)

// 聲明一個(gè)全局的 rdb 變量
var rdb *redis.Client

// 初始化連接
func initRedisClient() (err error) {
	// NewClient將客戶端返回給Options指定的Redis Server。
	// Options保留設(shè)置以建立redis連接。
	rdb = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // 沒有密碼,默認(rèn)值
		DB:       0,  // 默認(rèn)DB 0 連接到服務(wù)器后要選擇的數(shù)據(jù)庫。
		PoolSize: 20, // 最大套接字連接數(shù)。 默認(rèn)情況下,每個(gè)可用CPU有10個(gè)連接,由runtime.GOMAXPROCS報(bào)告。
	})

	// Background返回一個(gè)非空的Context。它永遠(yuǎn)不會被取消,沒有值,也沒有截止日期。
	// 它通常由main函數(shù)、初始化和測試使用,并作為傳入請求的頂級上下文
	ctx := context.Background()

	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		return err
	}
	return nil
}

func main() {
	if err := initRedisClient(); err != nil {
		fmt.Printf("initRedisClient failed: %v\n", err)
		return
	}
	fmt.Println("initRedisClient started successfully")
	defer rdb.Close() // Close 關(guān)閉客戶端,釋放所有打開的資源。關(guān)閉客戶端是很少見的,因?yàn)榭蛻舳耸情L期存在的,并在許多例程之間共享。
}

運(yùn)行

Code/go/redis_demo via ?? v1.20.3 via ?? base took 2.1s 
? go run main.go
initRedisClient started successfully

Code/go/redis_demo via ?? v1.20.3 via ?? base 
? 

執(zhí)行 Redis 命令

執(zhí)行 Redis 命令:

val, err := rdb.Get(ctx, "key").Result()
fmt.Println(val)

你也可以分別訪問值和錯(cuò)誤:

get := rdb.Get(ctx, "key")
fmt.Println(get.Val(), get.Err())

執(zhí)行尚不支持的命令

可以使用 Do() 方法執(zhí)行尚不支持或者任意命令:

val, err := rdb.Do(ctx, "get", "key").Result()
if err != nil {
	if err == redis.Nil {
		fmt.Println("key does not exists")
		return
	}
	panic(err)
}
fmt.Println(val.(string))

Do() 方法返回 Cmd 類型,你可以使用它獲取你 想要的類型:

// Text is a shortcut for get.Val().(string) with proper error handling.
val, err := rdb.Do(ctx, "get", "key").Text()
fmt.Println(val, err)

方法列表:

s, err := cmd.Text()
flag, err := cmd.Bool()

num, err := cmd.Int()
num, err := cmd.Int64()
num, err := cmd.Uint64()
num, err := cmd.Float32()
num, err := cmd.Float64()

ss, err := cmd.StringSlice()
ns, err := cmd.Int64Slice()
ns, err := cmd.Uint64Slice()
fs, err := cmd.Float32Slice()
fs, err := cmd.Float64Slice()
bs, err := cmd.BoolSlice()

#redis.Nil

redis.Nil 是一種特殊的錯(cuò)誤,嚴(yán)格意義上來說它并不是錯(cuò)誤,而是代表一種狀態(tài),例如你使用 Get 命令獲取 key 的值,當(dāng) key 不存在時(shí),返回 redis.Nil。在其他比如 BLPOP 、 ZSCORE 也有類似的響應(yīng),你需要區(qū) 分錯(cuò)誤:

val, err := rdb.Get(ctx, "key").Result()
switch {
case err == redis.Nil:
	fmt.Println("key不存在")
case err != nil:
	fmt.Println("錯(cuò)誤", err)
case val == "":
	fmt.Println("值是空字符串")
}

Conn

redis.Conn 是從連接池中取出的單個(gè)連接,除非你有特殊的需要,否則盡量不要使用它。你可以使用它向 redis 發(fā)送任何數(shù)據(jù)并讀取 redis 的響應(yīng),當(dāng)你使用完畢時(shí),應(yīng)該把它返回給 go-redis,否則連接池會永遠(yuǎn)丟失一個(gè)連 接。

cn := rdb.Conn(ctx)
defer cn.Close()

if err := cn.ClientSetName(ctx, "myclient").Err(); err != nil {
	panic(err)
}

name, err := cn.ClientGetName(ctx).Result()
if err != nil {
	panic(err)
}
fmt.Println("client name", name)

基本使用 執(zhí)行命令

package main

import (
	"context"
	"fmt"
	"github.com/redis/go-redis/v9"
	"time"
)

// 聲明一個(gè)全局的 rdb 變量
var rdb *redis.Client

// 初始化連接
func initRedisClient() (err error) {
	// NewClient將客戶端返回給Options指定的Redis Server。
	// Options保留設(shè)置以建立redis連接。
	rdb = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // 沒有密碼,默認(rèn)值
		DB:       0,  // 默認(rèn)DB 0 連接到服務(wù)器后要選擇的數(shù)據(jù)庫。
		PoolSize: 20, // 最大套接字連接數(shù)。 默認(rèn)情況下,每個(gè)可用CPU有10個(gè)連接,由runtime.GOMAXPROCS報(bào)告。
	})

	// Background返回一個(gè)非空的Context。它永遠(yuǎn)不會被取消,沒有值,也沒有截止日期。
	// 它通常由main函數(shù)、初始化和測試使用,并作為傳入請求的頂級上下文
	ctx := context.Background()

	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		return err
	}
	return nil
}

// doCommand go-redis基本使用示例
func redisCommand() {
	ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
	defer cancel()

	// 獲取Redis的“Get key”命令。它返回redis。當(dāng)鍵不存在時(shí)出現(xiàn)Nil錯(cuò)誤。
	val, err := rdb.Get(ctx, "key").Result()
	if err != nil {
		fmt.Printf("redis command failed: %v\n", err)
	}
	fmt.Printf("redis command get key %v\n", val)

	// 分別訪問值和錯(cuò)誤:
	get := rdb.Get(ctx, "key")
	fmt.Println("redis command get value: ", get.Val()) // 獲取值
	fmt.Println("redis command get err: ", get.Err())   // 獲取錯(cuò)誤

	// 設(shè)置Redis ' Set key value [expiration] '命令。
	err = rdb.Set(ctx, "key", 10, time.Hour).Err()
	fmt.Printf("rdb set err: %v\n", err)

	// 獲取Redis的“Get key”命令。它返回redis。當(dāng)鍵不存在時(shí)出現(xiàn)Nil錯(cuò)誤。
	value := rdb.Get(ctx, "key").Val()
	fmt.Printf("rdb get value: %v\n", value)
}

func main() {
	if err := initRedisClient(); err != nil {
		fmt.Printf("initRedisClient failed: %v\n", err)
		return
	}
	fmt.Println("initRedisClient started successfully")
	defer rdb.Close() // Close 關(guān)閉客戶端,釋放所有打開的資源。關(guān)閉客戶端是很少見的,因?yàn)榭蛻舳耸情L期存在的,并在許多例程之間共享。

	redisCommand()
}

運(yùn)行

Code/go/redis_demo via ?? v1.20.3 via ?? base 
? go run main.go
initRedisClient started successfully
redis command failed: redis: nil
redis command get key 
redis command get value:  
redis command get err:  redis: nil
rdb set err: <nil>
rdb get value: 10

Code/go/redis_demo via ?? v1.20.3 via ?? base 
? 

Go Redis 配置

Redis Client

type Options struct {
    // 連接網(wǎng)絡(luò)類型,如: tcp、udp、unix等方式
    // 如果為空默認(rèn)tcp
    Network string
	
    // redis服務(wù)器地址,ip:port格式,比如:192.168.1.100:6379
    // 默認(rèn)為 :6379
    Addr string
    
    // ClientName 是對網(wǎng)絡(luò)連接設(shè)置一個(gè)名字,使用 "CLIENT LIST" 命令
    // 可以查看redis服務(wù)器當(dāng)前的網(wǎng)絡(luò)連接列表
    // 如果設(shè)置了ClientName,go-redis對每個(gè)連接調(diào)用 `CLIENT SETNAME ClientName` 命令
    // 查看: https://redis.io/commands/client-setname/
    // 默認(rèn)為空,不設(shè)置客戶端名稱
    ClientName string
	
    // 如果你想自定義連接網(wǎng)絡(luò)的方式,可以自定義 `Dialer` 方法,
    // 如果不指定,將使用默認(rèn)的方式進(jìn)行網(wǎng)絡(luò)連接 `redis.NewDialer`
    Dialer func(ctx context.Context, network, addr string) (net.Conn, error)
    
    // 建立了新連接時(shí)調(diào)用此函數(shù)
    // 默認(rèn)為nil
    OnConnect func(ctx context.Context, cn *Conn) error
	
    // 當(dāng)redis服務(wù)器版本在6.0以上時(shí),作為ACL認(rèn)證信息配合密碼一起使用,
    // ACL是redis 6.0以上版本提供的認(rèn)證功能,6.0以下版本僅支持密碼認(rèn)證。
    // 默認(rèn)為空,不進(jìn)行認(rèn)證。
    Username string

    // 當(dāng)redis服務(wù)器版本在6.0以上時(shí),作為ACL認(rèn)證信息配合密碼一起使用,
    // 當(dāng)redis服務(wù)器版本在6.0以下時(shí),僅作為密碼認(rèn)證。
    // ACL是redis 6.0以上版本提供的認(rèn)證功能,6.0以下版本僅支持密碼認(rèn)證。
    // 默認(rèn)為空,不進(jìn)行認(rèn)證。
    Password string
	
    // 允許動態(tài)設(shè)置用戶名和密碼,go-redis在進(jìn)行網(wǎng)絡(luò)連接時(shí)會獲取用戶名和密碼,
    // 這對一些認(rèn)證鑒權(quán)有時(shí)效性的系統(tǒng)來說很有用,比如一些云服務(wù)商提供認(rèn)證信息有效期為12小時(shí)。
    // 默認(rèn)為nil
    CredentialsProvider func() (username string, password string)
    
    // redis DB 數(shù)據(jù)庫,默認(rèn)為0
    DB int
    
    // 命令最大重試次數(shù), 默認(rèn)為3
    MaxRetries int
	
    // 每次重試最小間隔時(shí)間
    // 默認(rèn) 8 * time.Millisecond (8毫秒) ,設(shè)置-1為禁用
    MinRetryBackoff time.Duration

    // 每次重試最大間隔時(shí)間
    // 默認(rèn) 512 * time.Millisecond (512毫秒) ,設(shè)置-1為禁用
    MaxRetryBackoff time.Duration
    
    // 建立新網(wǎng)絡(luò)連接時(shí)的超時(shí)時(shí)間
    // 默認(rèn)5秒
    DialTimeout time.Duration
	
    // 從網(wǎng)絡(luò)連接中讀取數(shù)據(jù)超時(shí)時(shí)間,可能的值:
    //  0 - 默認(rèn)值,3秒
    // -1 - 無超時(shí),無限期的阻塞
    // -2 - 不進(jìn)行超時(shí)設(shè)置,不調(diào)用 SetReadDeadline 方法
    ReadTimeout time.Duration
	
    // 把數(shù)據(jù)寫入網(wǎng)絡(luò)連接的超時(shí)時(shí)間,可能的值:
    //  0 - 默認(rèn)值,3秒
    // -1 - 無超時(shí),無限期的阻塞
    // -2 - 不進(jìn)行超時(shí)設(shè)置,不調(diào)用 SetWriteDeadline 方法
    WriteTimeout time.Duration
	
    // 是否使用context.Context的上下文截止時(shí)間,
    // 有些情況下,context.Context的超時(shí)可能帶來問題。
    // 默認(rèn)不使用
    ContextTimeoutEnabled bool

    // 連接池的類型,有 LIFO 和 FIFO 兩種模式,
    // PoolFIFO 為 false 時(shí)使用 LIFO 模式,為 true 使用 FIFO 模式。
    // 當(dāng)一個(gè)連接使用完畢時(shí)會把連接歸還給連接池,連接池會把連接放入隊(duì)尾,
    // LIFO 模式時(shí),每次取空閑連接會從"隊(duì)尾"取,就是剛放入隊(duì)尾的空閑連接,
    // 也就是說 LIFO 每次使用的都是熱連接,連接池有機(jī)會關(guān)閉"隊(duì)頭"的長期空閑連接,
    // 并且從概率上,剛放入的熱連接健康狀態(tài)會更好;
    // 而 FIFO 模式則相反,每次取空閑連接會從"隊(duì)頭"取,相比較于 LIFO 模式,
    // 會使整個(gè)連接池的連接使用更加平均,有點(diǎn)類似于負(fù)載均衡尋輪模式,會循環(huán)的使用
    // 連接池的所有連接,如果你使用 go-redis 當(dāng)做代理讓后端 redis 節(jié)點(diǎn)負(fù)載更平均的話,
    // FIFO 模式對你很有用。
    // 如果你不確定使用什么模式,請保持默認(rèn) PoolFIFO = false
    PoolFIFO bool

    // 連接池最大連接數(shù)量,注意:這里不包括 pub/sub,pub/sub 將使用獨(dú)立的網(wǎng)絡(luò)連接
    // 默認(rèn)為 10 * runtime.GOMAXPROCS
    PoolSize int
	
    // PoolTimeout 代表如果連接池所有連接都在使用中,等待獲取連接時(shí)間,超時(shí)將返回錯(cuò)誤
    // 默認(rèn)是 1秒+ReadTimeout
    PoolTimeout time.Duration
	
    // 連接池保持的最小空閑連接數(shù),它受到PoolSize的限制
    // 默認(rèn)為0,不保持
    MinIdleConns int
	
    // 連接池保持的最大空閑連接數(shù),多余的空閑連接將被關(guān)閉
    // 默認(rèn)為0,不限制
    MaxIdleConns int

    // ConnMaxIdleTime 是最大空閑時(shí)間,超過這個(gè)時(shí)間將被關(guān)閉。
    // 如果 ConnMaxIdleTime <= 0,則連接不會因?yàn)榭臻e而被關(guān)閉。
    // 默認(rèn)值是30分鐘,-1禁用
    ConnMaxIdleTime time.Duration

    // ConnMaxLifetime 是一個(gè)連接的生存時(shí)間,
    // 和 ConnMaxIdleTime 不同,ConnMaxLifetime 表示連接最大的存活時(shí)間
    // 如果 ConnMaxLifetime <= 0,則連接不會有使用時(shí)間限制
    // 默認(rèn)值為0,代表連接沒有時(shí)間限制
    ConnMaxLifetime time.Duration
    
    // 如果你的redis服務(wù)器需要TLS訪問,可以在這里配置TLS證書等信息
    // 如果配置了證書信息,go-redis將使用TLS發(fā)起連接,
    // 如果你自定義了 `Dialer` 方法,你需要自己實(shí)現(xiàn)網(wǎng)絡(luò)連接
    TLSConfig *tls.Config
    
    // 限流器的配置,參照 `Limiter` 接口
    Limiter Limiter
    
    // 設(shè)置啟用在副本節(jié)點(diǎn)只讀查詢,默認(rèn)為false不啟用
    // 參照:https://redis.io/commands/readonly
    readOnly bool
}

獲取 Redis 值 GET Key

package main

import (
	"context"
	"fmt"
	"github.com/redis/go-redis/v9"
	"time"
)

// 聲明一個(gè)全局的 rdb 變量
var rdb *redis.Client

// 初始化連接
func initRedisClient() (err error) {
	// NewClient將客戶端返回給Options指定的Redis Server。
	// Options保留設(shè)置以建立redis連接。
	rdb = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // 沒有密碼,默認(rèn)值
		DB:       0,  // 默認(rèn)DB 0 連接到服務(wù)器后要選擇的數(shù)據(jù)庫。
		PoolSize: 20, // 最大套接字連接數(shù)。 默認(rèn)情況下,每個(gè)可用CPU有10個(gè)連接,由runtime.GOMAXPROCS報(bào)告。
	})

	// Background返回一個(gè)非空的Context。它永遠(yuǎn)不會被取消,沒有值,也沒有截止日期。
	// 它通常由main函數(shù)、初始化和測試使用,并作為傳入請求的頂級上下文
	ctx := context.Background()

	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		return err
	}
	return nil
}


func redisGetKey(key string) (string, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
	defer cancel()

	val, err := rdb.Get(ctx, key).Result()
	if err != nil {
		if err == redis.Nil {
			return "", nil
			// DeadlineExceeded是Context返回的錯(cuò)誤。當(dāng)上下文的截止日期過去時(shí)發(fā)生錯(cuò)誤。
		} else if err == context.DeadlineExceeded {
			return "", fmt.Errorf("獲取值超時(shí)")
		} else {
			return "", fmt.Errorf("獲取值失敗: %v", err)
		}
	}

	if val == "" {
		return "", nil
	}

	return val, nil
}

func main() {
	if err := initRedisClient(); err != nil {
		fmt.Printf("initRedisClient failed: %v\n", err)
		return
	}
	fmt.Println("initRedisClient started successfully")
	defer rdb.Close() // Close 關(guān)閉客戶端,釋放所有打開的資源。關(guān)閉客戶端是很少見的,因?yàn)榭蛻舳耸情L期存在的,并在許多例程之間共享。

	//redisCommand()

	// get key
	value, _ := redisGetKey("key")
	fmt.Printf("get key: %v\n", value)
}

運(yùn)行

Code/go/redis_demo via ?? v1.20.3 via ?? base 
? go run main.go
initRedisClient started successfully
get key: 10

Code/go/redis_demo via ?? v1.20.3 via ?? base 
? 

設(shè)置值 SET

package main

import (
	"context"
	"fmt"
	"github.com/redis/go-redis/v9"
	"time"
)

// 聲明一個(gè)全局的 rdb 變量
var rdb *redis.Client

// 初始化連接
func initRedisClient() (err error) {
	// NewClient將客戶端返回給Options指定的Redis Server。
	// Options保留設(shè)置以建立redis連接。
	rdb = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // 沒有密碼,默認(rèn)值
		DB:       0,  // 默認(rèn)DB 0 連接到服務(wù)器后要選擇的數(shù)據(jù)庫。
		PoolSize: 20, // 最大套接字連接數(shù)。 默認(rèn)情況下,每個(gè)可用CPU有10個(gè)連接,由runtime.GOMAXPROCS報(bào)告。
	})

	// Background返回一個(gè)非空的Context。它永遠(yuǎn)不會被取消,沒有值,也沒有截止日期。
	// 它通常由main函數(shù)、初始化和測試使用,并作為傳入請求的頂級上下文
	ctx := context.Background()

	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		return err
	}
	return nil
}


func redisSetKey(key string, val string) error {
	ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
	defer cancel()

	// 設(shè)置Redis ' Set key value [expiration] '命令。
	err := rdb.Set(ctx, key, val, time.Hour).Err()
	if err != nil {
		fmt.Printf("redis set failed, err: %v\n", err)
		return err
	}
	return nil

}

func main() {
	if err := initRedisClient(); err != nil {
		fmt.Printf("initRedisClient failed: %v\n", err)
		return
	}
	fmt.Println("initRedisClient started successfully")
	defer rdb.Close() // Close 關(guān)閉客戶端,釋放所有打開的資源。關(guān)閉客戶端是很少見的,因?yàn)榭蛻舳耸情L期存在的,并在許多例程之間共享。

	// set value
	err := redisSetKey("name", "xia")
	if err != nil {
		fmt.Printf("redisSetKey failed: %v\n", err)
		return
	}
	fmt.Println("redisSetKey succeeded")
}

運(yùn)行

Code/go/redis_demo via ?? v1.20.3 via ?? base 
? go run main.go
initRedisClient started successfully
redisSetKey succeeded

HGetAll HSET

127.0.0.1:6379> hset user name "lixia"
(integer) 1
127.0.0.1:6379> hgetall user
1) "name"
2) "lixia"
127.0.0.1:6379> hset user age 14
(integer) 1
127.0.0.1:6379> hgetall user
1) "name"
2) "lixia"
3) "age"
4) "14"
127.0.0.1:6379>

main.go

package main

import (
	"context"
	"fmt"
	"github.com/redis/go-redis/v9"
	"time"
)

// 聲明一個(gè)全局的 rdb 變量
var rdb *redis.Client

// 初始化連接
func initRedisClient() (err error) {
	// NewClient將客戶端返回給Options指定的Redis Server。
	// Options保留設(shè)置以建立redis連接。
	rdb = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // 沒有密碼,默認(rèn)值
		DB:       0,  // 默認(rèn)DB 0 連接到服務(wù)器后要選擇的數(shù)據(jù)庫。
		PoolSize: 20, // 最大套接字連接數(shù)。 默認(rèn)情況下,每個(gè)可用CPU有10個(gè)連接,由runtime.GOMAXPROCS報(bào)告。
	})

	// Background返回一個(gè)非空的Context。它永遠(yuǎn)不會被取消,沒有值,也沒有截止日期。
	// 它通常由main函數(shù)、初始化和測試使用,并作為傳入請求的頂級上下文
	ctx := context.Background()

	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		return err
	}
	return nil
}


func hGetDemo(key string) (map[string]string, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
	defer cancel()

	val, err := rdb.HGetAll(ctx, key).Result()
	if err != nil {
		// redis.Nil
		// 其它錯(cuò)誤
		fmt.Printf("hgetall failed, err: %v\n", err)
		return nil, err
	}
	return val, nil
}

func main() {
	if err := initRedisClient(); err != nil {
		fmt.Printf("initRedisClient failed: %v\n", err)
		return
	}
	fmt.Println("initRedisClient started successfully")
	defer rdb.Close() // Close 關(guān)閉客戶端,釋放所有打開的資源。關(guān)閉客戶端是很少見的,因?yàn)榭蛻舳耸情L期存在的,并在許多例程之間共享。

	// hgetall()
	value, err := hGetDemo("user")
	if err != nil {
		fmt.Printf("hGetDem failed with error: %v\n", err)
		return
	}
	fmt.Printf("hgetall successful, value: %v\n", value)
}

運(yùn)行

Code/go/redis_demo via ?? v1.20.3 via ?? base took 3.8s 
? go run main.go 
initRedisClient started successfully
hgetall successful, value: map[age:14 name:lixia]

Code/go/redis_demo via ?? v1.20.3 via ?? base 
? 

HMGet HGet

package main

import (
	"context"
	"fmt"
	"github.com/redis/go-redis/v9"
	"time"
)

// 聲明一個(gè)全局的 rdb 變量
var rdb *redis.Client

// 初始化連接
func initRedisClient() (err error) {
	// NewClient將客戶端返回給Options指定的Redis Server。
	// Options保留設(shè)置以建立redis連接。
	rdb = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // 沒有密碼,默認(rèn)值
		DB:       0,  // 默認(rèn)DB 0 連接到服務(wù)器后要選擇的數(shù)據(jù)庫。
		PoolSize: 20, // 最大套接字連接數(shù)。 默認(rèn)情況下,每個(gè)可用CPU有10個(gè)連接,由runtime.GOMAXPROCS報(bào)告。
	})

	// Background返回一個(gè)非空的Context。它永遠(yuǎn)不會被取消,沒有值,也沒有截止日期。
	// 它通常由main函數(shù)、初始化和測試使用,并作為傳入請求的頂級上下文
	ctx := context.Background()

	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		return err
	}
	return nil
}


func hMGetDemo() {
	ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
	defer cancel()

	val := rdb.HMGet(ctx, "user", "name", "age").Val()
	fmt.Printf("redis HMGet %v\n", val)

	value := rdb.HGet(ctx, "user", "age").Val()
	fmt.Printf("redis HGet value: %v\n", value)
}

func main() {
	if err := initRedisClient(); err != nil {
		fmt.Printf("initRedisClient failed: %v\n", err)
		return
	}
	fmt.Println("initRedisClient started successfully")
	defer rdb.Close() // Close 關(guān)閉客戶端,釋放所有打開的資源。關(guān)閉客戶端是很少見的,因?yàn)榭蛻舳耸情L期存在的,并在許多例程之間共享。

	hMGetDemo()
}

運(yùn)行

Code/go/redis_demo via ?? v1.20.3 via ?? base 
? go run main.go 
initRedisClient started successfully
redis HMGet [lixia 14]
redis HGet value: 14

Code/go/redis_demo via ?? v1.20.3 via ?? base 
? 

ZSET 使用

package main

import (
	"context"
	"fmt"
	"github.com/redis/go-redis/v9"
	"time"
)

// 聲明一個(gè)全局的 rdb 變量
var rdb *redis.Client

// 初始化連接
func initRedisClient() (err error) {
	// NewClient將客戶端返回給Options指定的Redis Server。
	// Options保留設(shè)置以建立redis連接。
	rdb = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // 沒有密碼,默認(rèn)值
		DB:       0,  // 默認(rèn)DB 0 連接到服務(wù)器后要選擇的數(shù)據(jù)庫。
		PoolSize: 20, // 最大套接字連接數(shù)。 默認(rèn)情況下,每個(gè)可用CPU有10個(gè)連接,由runtime.GOMAXPROCS報(bào)告。
	})

	// Background返回一個(gè)非空的Context。它永遠(yuǎn)不會被取消,沒有值,也沒有截止日期。
	// 它通常由main函數(shù)、初始化和測試使用,并作為傳入請求的頂級上下文
	ctx := context.Background()

	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		return err
	}
	return nil
}


// zset Demo 操作 zset 示例
func zSetDemo() {
	// key
	zSetKey := "language_rank"
	// value Z表示有序集合的成員。
	languages := []redis.Z{
		{Score: 90.0, Member: "Golang"},
		{Score: 95.0, Member: "Python"},
		{Score: 97.0, Member: "Rust"},
		{Score: 99.0, Member: "C/C++"},
		{Score: 88.0, Member: "Java"},
	}
	// WithTimeout返回WithDeadline(parent, time.Now(). add (timeout))。
	ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
	defer cancel()

	// ZAdd Redis `ZADD key score member [score member ...]` command.
	num, err := rdb.ZAdd(ctx, zSetKey, languages...).Result()
	if err != nil {
		fmt.Printf("zadd failed, err:%v\n", err)
		return
	}
	fmt.Printf("zadd successful num: %v\n", num)

	// ZIncrBy 給某一個(gè)元素添加分?jǐn)?shù)值 把Golang的分?jǐn)?shù)加 10
	newScore, err := rdb.ZIncrBy(ctx, zSetKey, 10.0, "Golang").Result()
	if err != nil {
		fmt.Printf("ZIncrBy failed, err:%v\n", err)
		return
	}
	fmt.Printf("ZIncrBy success Golang's score is %f now.\n", newScore)

	// 取分?jǐn)?shù)最高的3個(gè)  適用于 排行榜、充值榜...
	// ZRevRangeWithScores according to the Redis documentation, if member does not exist
	// in the sorted set or key does not exist, it will return a redis.Nil error.
	ret, err := rdb.ZRevRangeWithScores(ctx, zSetKey, 0, 2).Result()
	if err != nil {
		fmt.Printf("zRevRangeWithScores failed, err: %v\n", err)
		return
	}
	for _, z := range ret {
		fmt.Printf("z.Member: %v, z.Score: %v\n", z.Member, z.Score)
	}

	// 取95~100分的
	op := &redis.ZRangeBy{
		Min: "95",
		Max: "100",
	}
	ret, err = rdb.ZRangeByScoreWithScores(ctx, zSetKey, op).Result()
	if err != nil {
		fmt.Printf("zrangebyscore failed, err:%v\n", err)
		return
	}
	fmt.Printf("zrangebyscore returned %v\n", ret)
	for _, z := range ret {
		fmt.Printf("ZRangeByScoreWithScores success Member: %v, Score: %v\n", z.Member, z.Score)
	}
}

func main() {
	if err := initRedisClient(); err != nil {
		fmt.Printf("initRedisClient failed: %v\n", err)
		return
	}
	fmt.Println("initRedisClient started successfully")
	defer rdb.Close() // Close 關(guān)閉客戶端,釋放所有打開的資源。關(guān)閉客戶端是很少見的,因?yàn)榭蛻舳耸情L期存在的,并在許多例程之間共享。

	zSetDemo()
}

運(yùn)行

Code/go/redis_demo via ?? v1.20.3 via ?? base 
? go run main.go
initRedisClient started successfully
zadd successful num: 5
ZIncrBy success Golang's score is 100.000000 now.
z.Member: Golang, z.Score: 100
z.Member: C/C++, z.Score: 99
z.Member: Rust, z.Score: 97
zrangebyscore returned [{95 Python} {97 Rust} {99 C/C++} {100 Golang}]
ZRangeByScoreWithScores success Member: Python, Score: 95
ZRangeByScoreWithScores success Member: Rust, Score: 97
ZRangeByScoreWithScores success Member: C/C++, Score: 99
ZRangeByScoreWithScores success Member: Golang, Score: 100

Code/go/redis_demo via ?? v1.20.3 via ?? base 
? 

Redis 查詢

127.0.0.1:6379> ZREVRANGE language_rank 0 2
1) "Golang"
2) "C/C++"
3) "Rust"
127.0.0.1:6379> ZREVRANGE language_rank 0 2 withscores
1) "Golang"
2) "100"
3) "C/C++"
4) "99"
5) "Rust"
6) "97"
127.0.0.1:6379> ZRANDMEMBER language_rank
"Rust"
127.0.0.1:6379> ZRANGE language_rank 0 2
1) "Java"
2) "Python"
3) "Rust"
127.0.0.1:6379> ZRANGE language_rank 0 2 withscores
1) "Java"
2) "88"
3) "Python"
4) "95"
5) "Rust"
6) "97"
127.0.0.1:6379> ZINCRBY language_rank 1 "Python"
"96"
127.0.0.1:6379> ZRANGE language_rank 0 2 withscores
1) "Java"
2) "88"
3) "Python"
4) "96"
5) "Rust"
6) "97"
127.0.0.1:6379>

Scan 根據(jù)前綴查詢 Key

package main

import (
	"context"
	"fmt"
	"github.com/redis/go-redis/v9"
	"time"
)

// 聲明一個(gè)全局的 rdb 變量
var rdb *redis.Client

// 初始化連接
func initRedisClient() (err error) {
	// NewClient將客戶端返回給Options指定的Redis Server。
	// Options保留設(shè)置以建立redis連接。
	rdb = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // 沒有密碼,默認(rèn)值
		DB:       0,  // 默認(rèn)DB 0 連接到服務(wù)器后要選擇的數(shù)據(jù)庫。
		PoolSize: 20, // 最大套接字連接數(shù)。 默認(rèn)情況下,每個(gè)可用CPU有10個(gè)連接,由runtime.GOMAXPROCS報(bào)告。
	})

	// Background返回一個(gè)非空的Context。它永遠(yuǎn)不會被取消,沒有值,也沒有截止日期。
	// 它通常由main函數(shù)、初始化和測試使用,并作為傳入請求的頂級上下文
	ctx := context.Background()

	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		return err
	}
	return nil
}

func scanKeyDemo(match string) {
	// WithTimeout返回WithDeadline(parent, time.Now(). add (timeout))。
	ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
	defer cancel()
	// 根據(jù)前綴查詢 Key
	iter := rdb.Scan(ctx, 0, match, 0).Iterator()

	for iter.Next(ctx) {
		fmt.Printf("key value: %v\n", iter.Val())
	}

	if err := iter.Err(); err != nil {
		fmt.Printf("rdb scan failed, err: %v\n", err)
		return
	}
}

func main() {
	if err := initRedisClient(); err != nil {
		fmt.Printf("initRedisClient failed: %v\n", err)
		return
	}
	fmt.Println("initRedisClient started successfully")
	defer rdb.Close() // Close 關(guān)閉客戶端,釋放所有打開的資源。關(guān)閉客戶端是很少見的,因?yàn)榭蛻舳耸情L期存在的,并在許多例程之間共享。

	scanKeyDemo("l*")
}

運(yùn)行文章來源地址http://www.zghlxwxcb.cn/news/detail-486204.html

Code/go/redis_demo via ?? v1.20.3 via ?? base 
? go run main.go
initRedisClient started successfully
key value: language_rank

Code/go/redis_demo via ?? v1.20.3 via ?? base 
? 

到了這里,關(guān)于Go語言之 go-redis 基本使用的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Go 基礎(chǔ)篇】Go語言結(jié)構(gòu)體基本使用

    【Go 基礎(chǔ)篇】Go語言結(jié)構(gòu)體基本使用

    在Go語言中,結(jié)構(gòu)體是一種重要的數(shù)據(jù)類型,用于定義和組織一組不同類型的數(shù)據(jù)字段。結(jié)構(gòu)體允許開發(fā)者創(chuàng)建自定義的復(fù)合數(shù)據(jù)類型,類似于其他編程語言中的類。本文將深入探討Go語言中結(jié)構(gòu)體的定義、初始化、嵌套、方法以及與其他語言的對比,以便全面了解如何在Go中

    2024年02月10日
    瀏覽(26)
  • 【go語言開發(fā)】redis簡單使用

    【go語言開發(fā)】redis簡單使用

    本文主要介紹redis安裝和使用。首先安裝redis依賴庫,這里是v8版本;然后連接redis,完成基本配置;最后測試封裝的工具類 歡迎大家訪問個(gè)人博客網(wǎng)址:https://www.maogeshuo.com,博主努力更新中… 參考文件: Yaml文件配置,Config使用 Log日志封裝 常用工具類封裝 命令行安裝redis

    2024年03月12日
    瀏覽(25)
  • 十、go語言Array(數(shù)組)基本使用方法

    Go 語言提供了數(shù)組類型的數(shù)據(jù)結(jié)構(gòu)。 數(shù)組是具有相同唯一類型的一組已編號且長度固定的數(shù)據(jù)項(xiàng)序列,這種類型可以是任意的原始類型例如整形、字符串或者自定義類型。 數(shù)組元素可以通過索引(位置)來讀?。ɑ蛘咝薷模?,索引從0開始,第一個(gè)元素索引為 0,第二個(gè)索引

    2024年02月08日
    瀏覽(24)
  • 【30天熟悉Go語言】5 Go 基本數(shù)據(jù)類型

    【30天熟悉Go語言】5 Go 基本數(shù)據(jù)類型

    Go系列文章: GO開篇:手握J(rèn)ava走進(jìn)Golang的世界 2 Go開發(fā)環(huán)境搭建、Hello World程序運(yùn)行 3 Go編程規(guī)約和API包 4 Go的變量、常量、運(yùn)算符 Go專欄傳送鏈接:https://blog.csdn.net/saintmm/category_12326997.html 基本數(shù)據(jù)類型大體來看有四種:數(shù)值型、字符型、布爾型、字符串。數(shù)值型又分為整數(shù)類

    2024年02月10日
    瀏覽(23)
  • Go 語言基本數(shù)據(jù)類型

    Go 語言基本數(shù)據(jù)類型

    Go 語言中數(shù)據(jù)類型分為:基本數(shù)據(jù)類型和復(fù)合數(shù)據(jù)類型 基本數(shù)據(jù)類型有: 整型、浮點(diǎn)型、布爾型、字符串 復(fù)合數(shù)據(jù)類型有: 數(shù)組、切片、結(jié)構(gòu)體、函數(shù)、map、通道(channel)、接口等。 整型分為以下兩個(gè)大類: 有符號整型按長度分為:int8、int16、int32、int64 對應(yīng)的無符號整

    2024年01月22日
    瀏覽(27)
  • go語言基本操作---三

    go語言基本操作---三

    指針是一個(gè)代表著某個(gè)內(nèi)存地址的值。這個(gè)內(nèi)存地址往往是在內(nèi)存中存儲的另一個(gè)變量的值的起始位置。Go語言對指針的支持介于java語言和C/C+語言之間,它即沒有想Java語言那樣取消了代碼對指針的直接操作的能力,也避免了C/C+語言中由于對指針的濫用而造成的安全和可靠性

    2024年02月09日
    瀏覽(25)
  • go語言基本操作---五

    go語言基本操作---五

    Go語言引入了一個(gè)關(guān)于錯(cuò)誤處理的標(biāo)準(zhǔn)模式,即error接口,它是Go語言內(nèi)建的接口類型 error接口的應(yīng)用 比如數(shù)組越界,空指針引用等等。 Go語言為我們提供了專用于\\\"攔截\\\"運(yùn)行時(shí)panic的內(nèi)建函數(shù)–recover。它可以是當(dāng)前的程序從運(yùn)行時(shí)panic的狀態(tài)中恢復(fù)并重新獲得流程控制權(quán). fu

    2024年02月09日
    瀏覽(20)
  • go語言基本操作--四

    go語言基本操作--四

    對于面向?qū)ο缶幊痰闹С謌o語言設(shè)計(jì)得非常簡潔而優(yōu)雅。因?yàn)?,Go語言并沒有沿襲面向?qū)ο缶幊讨兄T多概念,比如繼承(不支持繼承,盡管匿名字段的內(nèi)存布局和行為類似繼承,但它并不是繼承)、虛函數(shù)、構(gòu)造函數(shù)和析構(gòu)函數(shù)、隱藏的this指針等. 盡管go語言中沒有封裝,繼承,

    2024年02月10日
    瀏覽(16)
  • Go語言的基本概念與語法

    每個(gè) Go 程序都是由包組成的. 程序從 main 包開始運(yùn)行. 本程序通過導(dǎo)入路徑 \\\"fmt\\\" and \\\"math/rand\\\" 來使用這兩個(gè)包. 按照約定,包名與導(dǎo)入路徑的最后一個(gè)元素相同。例如, \\\"math/rand\\\" 包中的源碼均以 package rand` 語句開始. 注意: 執(zhí)行這些程序的環(huán)境是確定性的 所以每次運(yùn)行示例程序

    2024年02月11日
    瀏覽(18)
  • Go語言編程教程-基本數(shù)據(jù)類型

    了解布爾類型 了解整數(shù)類型 了解浮點(diǎn)數(shù)類型 了解復(fù)數(shù)類型 了解字符串類型 了解字符類型 類型 名稱 取值范圍 說明 bool 布爾類型 true 或 false 默認(rèn)值為 false 類型 名稱 取值范圍 說明 uint8 8位無符號整型 0 ~ 255 uint16 16位無符號整型 0 ~ 65535 uint32 32位無符號整型 0 ~ 4294967295 uint6

    2024年02月04日
    瀏覽(906)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包