Golang與Redis


在這裏插入圖片描述

1. 知識儲備

  • 知道Redis是個啥?
  • 知道Redis的基礎命令怎麼操作
  • 測試的環境中安裝了Redis的服務端(無論是win還Linux環境)
  • Go語言基礎知識

Redis命令參考

2. 安裝redis客戶端

Go語言的Redi客戶端包很多,我們只取最常見的Redis包.

如下我們列出Redis常見的包,這些包在github都可以查詢到,如下列出的兩個包更新較快,功能齊全

包名 github地址 參考文檔
go-redis/redis https://github.com/go-redis/redis https://godoc.org/github.com/go-redis/redis
gomodule/redigo https://github.com/gomodule/redigo https://godoc.org/github.com/gomodule/redigo/redis

我們選擇安裝其中一個包即可,此處選擇是go-redis這個包

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

3. 常見的全局命令

全局命令是對任意類型的鍵都有效果的

代碼中展示的只是部分命令的使用

package main

import (
	"fmt"
	"github.com/go-redis/redis"
	"time"
)
// 定義一組常量
const (
	REDIS_IP   = "127.0.0.1"
	REDIS_PORT = "6379"
	REDIS_PWD  = ""
	REDIS_DB   = 0
)
// 定義一個redis.client類型的變量
var client *redis.Client
// 初始化函數
func init() {
	// 實例化一個redis客戶端
	client = redis.NewClient(&redis.Options{
        Addr:     REDIS_IP + ":" + REDIS_PORT, // ip:port
		Password: REDIS_PWD,				   // redis連接密碼
		DB:       REDIS_DB,					   // 選擇的redis庫
		PoolSize: 20,						   // 設置連接數,默認是10個連接
	})
}
func main() {
	// redis 全局命令
	// 獲取redis所有的鍵,返回包含所有鍵的slice
	keys := client.Keys("*").Val()
	fmt.Println(keys)
	// 獲取redis中的有多少個鍵,返回整數
	size := client.DbSize().Val()
	fmt.Println(size)
	// 判斷一個鍵是否存在,有一個存在返回整數1,有兩個存在返回整數2...
	exist := client.Exists("age","name").Val()
	fmt.Println(exist)
	// 刪除鍵,刪除成功返回刪除的數,刪除失敗返回0
	del := client.Del("unknownKey").Val()
	fmt.Println(del)
	// 查看鍵的有效時間
	ttl := client.TTL("age").Val()
	fmt.Println(ttl)
	// 給鍵設置有效時間,設置成功返回true,失敗返回false
	expire := client.Expire("age",time.Second*86400).Val()
	fmt.Println(expire)
	// 查看鍵的類型(string,hash,list,set,zset...)
	Rtype := client.Type("store:finish:bill:list").Val()
	fmt.Println(Rtype)
	// 給鍵重命令,成功返回true,失敗false
	Rname := client.RenameNX("age","newAge").Val()
	fmt.Println(Rname)
	// 從redis中隨機返回一個鍵
	key := client.RandomKey().Val()
	fmt.Println(key)

}

4. Redis的string類型操作

package main

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

// 定義一組常量
const (
	REDIS_IP   = "127.0.0.1"
	REDIS_PORT = "6379"
	REDIS_PWD  = ""
	REDIS_DB   = 0
)

// 定義一個redis.client類型的變量
var client *redis.Client

// 初始化函數
func init() {
	// 實例化一個redis客戶端
	client = redis.NewClient(&redis.Options{
		Addr:     REDIS_IP + ":" + REDIS_PORT, // ip_port
		Password: REDIS_PWD,                   // redis連接密碼
		DB:       REDIS_DB,                    // 選擇的redis庫
		PoolSize: 20,                          // 設置連接數,默認是10個連接
	})
}
func main() {
	defer client.Close()
	defer func() {
		if err := recover(); err != nil {
			fmt.Println(err)
		}
	}()
	// 設置一組鍵值對,並社會有效期
	set1 := client.Set("age", 10, time.Hour*24).Val()
	fmt.Println(set1) // OK
	//設置一組鍵值對,設置的鍵不存在的時候才能設置成功
	set2 := client.SetNX("age", "20", time.Hour*12).Val()
	fmt.Println(set2) // false
	//設置一組鍵值對,設置的鍵必須存在的時候才能設置成功
	set3 := client.SetXX("age", "30", time.Second*86400).Val()
	fmt.Println(set3) // true
	// 批量設置
	set4 := client.MSet("age1", "40", "age2", "50").Val()
	fmt.Println(set4) // OK
	// 獲取一個鍵的值
	get1 := client.Get("age2").Val()
	fmt.Println(get1) // 50
	// 批量獲取,獲取成功返回slice類型的結果數據
	get2 := client.MGet("age", "age1", "age2").Val()
	fmt.Println(get2) // [30 40 50]
	// 對指定的鍵進行自增操作
	incr1 := client.Incr("age").Val()
	fmt.Println(incr1) // 31
	// 對指定鍵進行自減操作
	decr1 := client.Decr("age1").Val()
	fmt.Println(decr1) //39
	// 自增指定的值
	incr2 := client.IncrBy("age", 10).Val()
	fmt.Println(incr2) // 41
	// 自減指定的值
	decr2 := client.DecrBy("age1", 10).Val()
	fmt.Println(decr2) // 29
	// 在key後面追加指定的值,返回字符串的長度
	append1 := client.Append("age2", "abcd").Val()
	fmt.Println(append1) // 6
	// 獲取一個鍵的值得長度
	strlen1 := client.StrLen("age2").Val()
	fmt.Println(strlen1) //6
	// 設置一個鍵的值,並返回原有的值
	getset1 := client.GetSet("age2", "hello golang").Val()
	fmt.Println(getset1) // 50abcd
	// 設置鍵的值,在指定的位置
	_ = client.SetRange("age2", 0, "H")
	fmt.Println(client.Get("age2").Val()) // Hello golang
	// 截取一個鍵的值的部分,返回截取的部分
	newStr := client.GetRange("age2", 6, 11).Val()
	fmt.Println(newStr) //golang
}

5. Redis的hash類型操作

package main

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

// 定義一組常量
const (
	REDIS_IP   = "127.0.0.1"
	REDIS_PORT = "6379"
	REDIS_PWD  = ""
	REDIS_DB   = 0
)

// 定義一個redis.client類型的變量
var client *redis.Client

// 初始化函數
func init() {
	// 實例化一個redis客戶端
	client = redis.NewClient(&redis.Options{
		Addr:     REDIS_IP + ":" + REDIS_PORT, // ip_port
		Password: REDIS_PWD,                   // redis連接密碼
		DB:       REDIS_DB,                    // 選擇的redis庫
		PoolSize: 20,                          // 設置連接數,默認是10個連接
	})
}
func main() {
	defer client.Close()
	defer func() {
		if err := recover(); err != nil {
			fmt.Println(err)
		}
	}()
	key := "account"
	field1 := "name"
	fields := map[string]interface{}{
		"addr":"beijing",
		"age":99,
		"skills":"golang",
		"demo1":"aaa",
		"demo2":"bbb",
	}
	//hash 設置一個鍵的field
	_ = client.HSet(key,field1,"zhangsan")
	// hash 批量設置 ,第二個參數是map類型
	status := client.HMSet(key,fields).Val()
	fmt.Println(status) //ok
	// hash 刪除鍵的field,返回刪除field的個數
	 _ = client.HDel(key,"demo2").Val()
	 //hash 獲取field的值
	name := client.HGet(key,"name").Val()
	fmt.Println(name) //zhangsan
	//hash 獲取多個field值,返回slice
	values := client.HMGet(key,"name","age").Val()
	fmt.Println(values)//[zhangsan 99]
	//hash 獲取所有的值 返回map
	valueAll := client.HGetAll(key).Val()
	fmt.Println(valueAll) //map[addr:beijing age:99 demo1:aaa name:zhangsan skills:golang]
	// hash 獲取所有field 返回slice
	fs := client.HKeys(key).Val()
	fmt.Println(fs) //[name addr age skills demo1]
	// hash 獲取所有filed的值 返回slice
	vs := client.HVals(key).Val()
	fmt.Println(vs) //[zhangsan beijing 99 golang aaa]
	// 判斷一個filed是否存在 返回bool
	e := client.HExists(key,"skills").Val()
	fmt.Println(e) //true
	// hash field自增
	n := client.HIncrBy(key,"age",1).Val()
	fmt.Println(n) //100
}

6. Redis的list類型操作

package main

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

// 定義一組常量
const (
	REDIS_IP   = "127.0.0.1"
	REDIS_PORT = "6379"
	REDIS_PWD  = ""
	REDIS_DB   = 0
)

// 定義一個redis.client類型的變量
var client *redis.Client

// 初始化函數
func init() {
	// 實例化一個redis客戶端
	client = redis.NewClient(&redis.Options{
		Addr:     REDIS_IP + ":" + REDIS_PORT, // ip_port
		Password: REDIS_PWD,                   // redis連接密碼
		DB:       REDIS_DB,                    // 選擇的redis庫
		PoolSize: 20,                          // 設置連接數,默認是10個連接
	})
}
func main() {
	defer client.Close()
	defer func() {
		if err := recover(); err != nil {
			fmt.Println(err)
		}
	}()
	key := "demo"
	client.Del(key)
	for i := 0; i < 5; i++ {
		client.LPush(key, "e-"+strconv.Itoa(i))
	}
	// 獲取list 長度
	length := client.LLen(key).Val()
	fmt.Println(length) //5
	// 獲取指定下標元素
	value1 := client.LIndex(key, 0).Val()
	fmt.Println(value1) //e-4
	// 獲取所有元素
	vs := client.LRange(key, 0, -1).Val()
	fmt.Println(vs) //[e-4 e-3 e-2 e-1 e-0]
	// 修改指定下標的元素值
	status := client.LSet(key, 0, "golang").Val()
	fmt.Println(status) //ok
	// 從右邊插入元素
	client.RPush(key, "e-right")
	// 從左邊插入元素
	client.LPush(key, "e-left")
	// 從list最右邊彈出元素
	v1 := client.RPop(key).Val()
	fmt.Println(v1) // e-right
	// 從list最左邊彈出元素
	v2 := client.LPop(key).Val()
	fmt.Println(v2) // e-left
	// 刪除指定元素
	n := client.LRem(key, 0, "e-3").Val()
	fmt.Println(n) //1
	status1 := client.LTrim(key, 0, 1).Val()
	fmt.Println(status1) //ok

}

7. Redis的set類型操作

package main

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

// 定義一組常量
const (
	REDIS_IP   = "127.0.0.1"
	REDIS_PORT = "6379"
	REDIS_PWD  = ""
	REDIS_DB   = 0
)

// 定義一個redis.client類型的變量
var client *redis.Client

// 初始化函數
func init() {
	// 實例化一個redis客戶端
	client = redis.NewClient(&redis.Options{
		Addr:     REDIS_IP + ":" + REDIS_PORT, // ip_port
		Password: REDIS_PWD,                   // redis連接密碼
		DB:       REDIS_DB,                    // 選擇的redis庫
		PoolSize: 20,                          // 設置連接數,默認是10個連接
	})
}
func main() {
	defer client.Close()
	defer func() {
		if err := recover(); err != nil {
			fmt.Println(err)
		}
	}()
	key := "sdemo"
	key1 := "sdemo1"
	client.Del(key)
	client.Del(key1)
	for i := 0; i < 6; i++ {
		// set 類型添加元素
		client.SAdd(key, "ele-"+strconv.Itoa(i))
	}
	for i := 3; i < 9; i++ {
		// set 類型添加元素
		client.SAdd(key1, "ele-"+strconv.Itoa(i))
	}
	// 計算key中的元素個數
	n1 := client.SCard(key).Val()
	fmt.Println(n1) //5
	// 判斷元素是否在集合中
	e1 := client.SIsMember(key, "ele-0").Val()
	fmt.Println(e1) // true
	// 隨機從集合中返回一個元素
	v1 := client.SRandMember(key).Val()
	fmt.Println(v1)
	// 隨機返回指定個數的元素,返回包含元素的slice
	v2 := client.SRandMemberN(key, 3).Val()
	fmt.Println(v2)
	// 獲取集合中的所有元素,無序的slice
	v3 := client.SMembers(key).Val()
	fmt.Println(v3) //[ele-1 ele-0 ele-3 ele-2 ele-4]
	// 從集合中隨機彈出一個元素
	v4 := client.SPop(key).Val()
	fmt.Println(v4)
	// 從集合中刪除元素
	n2 := client.SRem(key, "ele-5").Val()
	fmt.Println(n2) //1
	// 求多個集合的交集
	s1 := client.SInter(key, key1).Val()
	fmt.Println(s1) // [ele-3 ele-4]
	//求多個集合的並集
	s2 := client.SUnion(key, key1).Val()
	fmt.Println(s2) // [ele-3 ele-5 ele-1 ele-2 ele-4 ele-8 ele-6 ele-0 ele-7]
	// 求多個集合的差集
	s3 := client.SDiff(key, key1).Val()
	fmt.Println(s3) // [ele-0 ele-1]
	// 將多個交集結果存爲一個新的集合
	s4 := client.SInterStore("sdemo2", key, key1).Val()
	fmt.Println(s4)                              //2
	fmt.Println(client.SMembers("sdemo2").Val()) // [ele-4 ele-3]
	// 將多個交集的並集結果存爲新的集合
	s5 := client.SUnionStore("sdemo3", key, key1).Val()
	fmt.Println(s5)                              //8
	fmt.Println(client.SMembers("sdemo3").Val()) // [ele-3 ele-5 ele-1 ele-4 ele-7 ele-8 ele-6 ele-0]
	// 將多個差集的結果存爲新的集合
	s6 := client.SDiffStore("sdemo4", key, key1).Val()
	fmt.Println(s6)                              //2
	fmt.Println(client.SMembers("sdemo4").Val()) // [ele-0 ele-1]
}

8. Redis的zset類型操作

package main

import (
	"fmt"
	"github.com/go-redis/redis"
	"math/rand"
	"strconv"
)

// 定義一組常量
const (
	REDIS_IP   = "127.0.0.1"
	REDIS_PORT = "6379"
	REDIS_PWD  = ""
	REDIS_DB   = 0
)

// 定義一個redis.client類型的變量
var client *redis.Client

// 初始化函數
func init() {
	// 實例化一個redis客戶端
	client = redis.NewClient(&redis.Options{
		Addr:     REDIS_IP + ":" + REDIS_PORT, // ip_port
		Password: REDIS_PWD,                   // redis連接密碼
		DB:       REDIS_DB,                    // 選擇的redis庫
		PoolSize: 20,                          // 設置連接數,默認是10個連接
	})
}
func randString(n int) string {
	s := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
	b := make([]byte, n)
	for i := range b {
		b[i] = s[rand.Intn(len(s))]
	}
	return string(b)
}
func main() {
	defer client.Close()
	defer func() {
		if err := recover(); err != nil {
			fmt.Println(err)
		}
	}()
	key := "zdemo"
	key1 := "zdemo1"
	client.Del(key)
	client.Del(key1)
	for i := 0; i < 10; i++ {
		score := float64(rand.Intn(100) - 50)
		member := "golang-" + strconv.Itoa(i)
		data := &redis.Z{
			score,
			member,
		}
		// 向有序集合中添加成員
		client.ZAdd(key, data).Val()
	}
	for i := 0; i < 5; i++ {
		score := float64(rand.Intn(100) - 50)
		member := "golang-" + strconv.Itoa(i)
		data := &redis.Z{
			score,
			member,
		}
		// 向有序集合中添加成員
		client.ZAdd(key1, data).Val()
	}
	// 計算成員個數
	n1 := client.ZCard(key).Val()
	fmt.Println(n1) //10
	// 獲取成員分數
	s1 := client.ZScore(key, "golang-6").Val()
	fmt.Println(s1) // -25
	// 修改成員分數
	v1 := client.ZIncrBy(key, 60.00, "golang-6").Val()
	fmt.Println(v1)
	// 從低到高返回排名
	s2 := client.ZRank(key, "golang-6").Val()
	fmt.Println(s2) //8
	// 從高到低返回排名
	s3 := client.ZRevRank(key, "golang-6").Val()
	fmt.Println(s3) //1
	// 獲取指定範圍的成員排名,從低到高排名
	s4 := client.ZRange(key, 0, n1-5).Val()
	fmt.Println(s4) //[golang-9 golang-5 golang-7 golang-2 golang-8 golang-3]
	// 獲取指定範圍的成員排名,從高到低排名
	s5 := client.ZRevRange(key, 0, n1-5).Val()
	fmt.Println(s5) //[golang-1 golang-6 golang-4 golang-0 golang-3 golang-8]
	// 刪除成員
	v2 := client.ZRem(key, "golang-6").Val()
	fmt.Println(v2) //1
	// 計算兩個有序集合的交集
	key2 := "zdemo2"
	kslice := []string{key, key1}
	wslice := []float64{1.00, 1.00}
	z := &redis.ZStore{
		kslice,
		wslice,
		"SUM",
	}
	r1 := client.ZInterStore(key2, z).Val()
	fmt.Println(r1) //5
	// 計算兩個有序集合的並集
	key3 := "zdemo3"
	r2 := client.ZUnionStore(key3,z).Val()
	fmt.Println(r2) // 9

}

9. Redis簡單的訂閱/發佈

訂閱多頻道的demo

subscription.go

package main

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

// 定義一組常量
const (
	REDIS_IP   = "127.0.0.1"
	REDIS_PORT = "6379"
	REDIS_PWD  = ""
	REDIS_DB   = 0
)

// 定義一個redis.client類型的變量
var client *redis.Client

// 初始化函數
func init() {
	// 實例化一個redis客戶端
	client = redis.NewClient(&redis.Options{
		Addr:     REDIS_IP + ":" + REDIS_PORT, // ip_port
		Password: REDIS_PWD,                   // redis連接密碼
		DB:       REDIS_DB,                    // 選擇的redis庫
		PoolSize: 20,                          // 設置連接數,默認是10個連接
	})
}
func main() {
	defer client.Close()
	defer func() {
		if err := recover(); err != nil {
			fmt.Println(err)
		}
	}()
	// 訂閱多個頻道
	sub := client.PSubscribe("news", "it", "sports", "shopping")
	_, err := sub.Receive()
	if err != nil {
		fmt.Println(err)
	}
	// 消息通道
	ch := sub.Channel()
	//  從通道中讀取消息
	for message := range ch {
		fmt.Println(message.Channel, message.Payload)
	}
}

go run subscription.go

發佈信息到不同頻道的demo

publish.go

package main

import (
	"fmt"
	"github.com/go-redis/redis"
	"math/rand"
)

// 定義一組常量
const (
	REDIS_IP   = "127.0.0.1"
	REDIS_PORT = "6379"
	REDIS_PWD  = ""
	REDIS_DB   = 0
)

// 定義一個redis.client類型的變量
var client *redis.Client

// 初始化函數
func init() {
	// 實例化一個redis客戶端
	client = redis.NewClient(&redis.Options{
		Addr:     REDIS_IP + ":" + REDIS_PORT, // ip_port
		Password: REDIS_PWD,                   // redis連接密碼
		DB:       REDIS_DB,                    // 選擇的redis庫
		PoolSize: 20,                          // 設置連接數,默認是10個連接
	})
}

// 生成指定長度的隨機字符串
func randString(n int) string {
	s := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
	b := make([]byte, n)
	for i := range b {
		b[i] = s[rand.Intn(len(s))]
	}
	return string(b)
}
func main() {
	defer client.Close()
	defer func() {
		if err := recover(); err != nil {
			fmt.Println(err)
		}
	}()
	var data string
	var channels []string = []string{"news", "it", "sports", "shopping"}
	for {
		fmt.Printf("please input some data:")
		fmt.Scanln(&data)
		// 退出
		if data == "quit" {
			break
		}
		channel := channels[rand.Intn(4)]
		// 向一個頻道發佈消息
		result := client.Publish(channel, data+randString(10)).Val()
		if result == 1 {
			fmt.Println("send info to", channel,"success")
		}
	}
}

go run publish.go

測試

在發佈消息的代碼執行窗口,輸入任意的消息

please input some data:asjdasd
send info to it success
please input some data:asdasd
send info to shopping success
please input some data:iii
send info to news success

在訂閱代碼的執行窗口接收消息

it asdasdpLnfgDsc3W
it asjdasdpLnfgDsc3W
shopping asdasd9F3qNfHK6a
news iii5jjJkwzDkh
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章