Go-连接Redis-学习go-redis包详解编程语言

Redis介绍

Redis是一个开源的内存数据结构存储,常用作数据库、缓存和消息代理。目前它支持的数据结构有诸如string、hash、list、set、zset、bitmap、hyperloglog、geospatial index和stream。Redis内置了复制、Lua脚本、LRU清除、事务和不同级别的磁盘持久性,并通过Redis Sentinel提供高可用性,通过Redis Cluster自动分区。

go-redis库

安装

区别于另一个比较常用的Go语言redis client库:redigo,我们这里采用https://github.com/go-redis/redis连接Redis数据库并进行操作,因为go-redis支持连接哨兵及集群模式的Redis。

使用以下命令下载并安装:

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

连接

普通连接
// 声明一个全局的rdb变量 
var rdb *redis.Client 
 
// 初始化连接 
func initClient() (err error) { 
        // 通过 redis.NewClient 函数即可创建一个 redis 客户端, 这个方法接收一个 redis.Options 对象参数, 通过这个参数, 我们可以配置 redis 相关的属性, 例如 redis 服务器地址, 数据库名, 数据库密码等。 
	rdb = redis.NewClient(&redis.Options{ 
		Addr:     "localhost:6379", 
		Password: "", // no password set 
		DB:       0,  // use default DB 
	}) 
        // 通过 cient.Ping() 来检查是否成功连接到了 redis 服务器 
	_, err = rdb.Ping().Result() 
	if err != nil { 
		return err 
	} 
	return nil 
} 
连接Redis哨兵模式
func initClient()(err error){ 
	rdb := redis.NewFailoverClient(&redis.FailoverOptions{ 
		MasterName:    "master", 
		SentinelAddrs: []string{"x.x.x.x:26379", "xx.xx.xx.xx:26379", "xxx.xxx.xxx.xxx:26379"}, 
	}) 
	_, err = rdb.Ping().Result() 
	if err != nil { 
		return err 
	} 
	return nil 
} 
连接Redis集群
func initClient()(err error){ 
	rdb := redis.NewClusterClient(&redis.ClusterOptions{ 
		Addrs: []string{":7000", ":7001", ":7002", ":7003", ":7004", ":7005"}, 
	}) 
	_, err = rdb.Ping().Result() 
	if err != nil { 
		return err 
	} 
	return nil 
} 

连接池

go-redis 已经实现了 redis 的连接池管理, 因此我们不需要自己手动管理 redis 的连接。
默认情况下,连接池大小是10, 可以通过 redis.Options 的 PoolSize 属性, 我们设置了 redis 连接池的大小为5。

func GetRedisClientPool() *Client{ 
    redisdb := NewClient(&Options{ 
        Addr: "127.0.0.1:6379", 
        Password: "", 
        DB: 0, 
        PoolSize: 5,}) 
 
    pong, err := redisdb.Ping().Result() 
    if err != nil { 
        fmt.Println(pong, err) 
    } 
    return redisdb 
} 
 
// 连接池测试 
func connectPoolTest() { 
    fmt.Println("-----------------------welcome to connect Pool Test-----------------------") 
    client :=GetRedisClientPool() 
    wg := sync.WaitGroup{} 
    wg.Add(10) 
 
    for i := 0; i < 10; i++ { 
        go func() { 
            defer wg.Done() 
 
            for j := 0; j < 1000; j++ { 
                client.Set(fmt.Sprintf("name%d", j), fmt.Sprintf("xys%d", j), 0).Err() 
                client.Get(fmt.Sprintf("name%d", j)).Result() 
            } 
 
            fmt.Printf("PoolStats, TotalConns: %d, IdleConns: %d/n", client.PoolStats().TotalConns, client.PoolStats().IdleConns); 
        }() 
    } 
 
    wg.Wait() 
} 

基本使用

String 操作
  • Set(key, value):给数据库中名称为key的string赋予值valueget(key):返回数据库中名称为key的string的value
  • GetSet(key, value):给名称为key的string赋予上一次的value
  • MGet(key1, key2,…, key N):返回库中多个string的value
  • SetNX(key, value):添加string,名称为key,值为value
  • SetXX(key, time, value):向库中添加string,设定过期时间time
  • MSet(key N, value N):批量设置多个string的值
  • MSetNX(key N, value N):如果所有名称为key i的string都不存在
  • Incr(key):名称为key的string增1操作
  • Incrby(key, integer):名称为key的string增加integer
  • Decr(key):名称为key的string减1操作
  • Decrby(key, integer):名称为key的string减少integer
  • Append(key, value):名称为key的string的值附加valuesubstr(key, start, end):返回名称为key的string的value的子串
     
func redisExample() { 
	err := rdb.Set("score", 100, 0).Err() 
	if err != nil { 
		fmt.Printf("set score failed, err:%v/n", err) 
		return 
	} 
 
	val, err := rdb.Get("score").Result() 
	if err != nil { 
		fmt.Printf("get score failed, err:%v/n", err) 
		return 
	} 
	fmt.Println("score", val) 
 
	val2, err := rdb.Get("name").Result() 
	if err == redis.Nil { 
		fmt.Println("name does not exist") 
	} else if err != nil { 
		fmt.Printf("get name failed, err:%v/n", err) 
		return 
	} else { 
		fmt.Println("name", val2) 
	} 
} 
func StringDemo() { 
    fmt.Println("-----------------------welcome to StringDemo-----------------------") 
    redisClient:=GetRedisClient() 
    if redisClient ==nil{ 
        fmt.Errorf("StringDemo redisClient is nil") 
        return 
    } 
 
    name := "张三" 
    key :="name:zhangsan" 
    redisClient.Set(key , name,1 * time.Second) 
    val := redisClient.Get(key) 
    if val == nil { 
        fmt.Errorf("StringDemo get error") 
    } 
    fmt.Println("name", val) 
} 
List 操作
  • RPush(key, value):在名称为key的list尾添加一个值为value的元素
  • LPush(key, value):在名称为key的list头添加一个值为value的元素
  • LLen(key):返回名称为key的list的长度
  • LRange(key, start, end):返回名称为key的list中start至end之间的元素
  • LTrim(key, start, end):截取名称为key的list
  • LIndex(key, index):返回名称为key的list中index位置的元素
  • LSet(key, index, value):给名称为key的list中index位置的元素赋值
  • LRem(key, count, value):删除count个key的list中值为value的元素
  • LPop(key):返回并删除名称为key的list中的首元素
  • RPop(key):返回并删除名称为key的list中的尾元素
  • BLPop(key1, key2,… key N, timeout):lpop命令的block版本。
  • BRPop(key1, key2,… key N, timeout):rpop的block版本。
  • RPopLPush(srckey, dstkey):返回并删除名称为srckey的list的尾元素,并将该元素添加到名称为dstkey的list的头部
func ListDemo(){ 
    fmt.Println("-----------------------welcome to ListDemo-----------------------") 
    redisClient:=GetRedisClient() 
    if redisClient == nil { 
        fmt.Errorf("ListDemo redisClient is nil") 
        return 
    } 
    articleKey := "article" 
    result,err:=redisClient.RPush(articleKey, "a","b","c").Result() // 
    if err!=nil { 
        fmt.Println(err) 
        return 
    } 
    fmt.Println("result:",result) 
 
    result,err = redisClient.LPush(articleKey, "d").Result() // 
    if err!=nil { 
        fmt.Println(err) 
        return 
    } 
    fmt.Println("result:",result) 
 
    length, err := redisClient.LLen(articleKey).Result() 
    if err != nil { 
        fmt.Println("ListDemo LLen is nil") 
    } 
    fmt.Println("length: ", length) // 长度 
 
    mapOut,err1:=redisClient.LRange(articleKey,0,100).Result() 
    if err1!=nil { 
        fmt.Println(err1) 
        return 
    } 
    for inx, item := range mapOut { 
        fmt.Printf("/n %s:%s", inx, item) 
    } 
} 
Hash操作
  • HSet(key, field, value):向名称为key的hash中添加元素field
  • HGet(key, field):返回名称为key的hash中field对应的value
  • HMget(key, (fields)):返回名称为key的hash中field i对应的value
  • HMset(key, (fields)):向名称为key的hash中添加元素field
  • HIncrby(key, field, integer):将名称为key的hash中field的value增加integer
  • HExists(key, field):名称为key的hash中是否存在键为field的域
  • HDel(key, field):删除名称为key的hash中键为field的域
  • HLen(key):返回名称为key的hash中元素个数
  • HKeys(key):返回名称为key的hash中所有键
  • HVals(key):返回名称为key的hash中所有键对应的value
  • HGetall(key):返回名称为key的hash中所有的键(field)及其对应的value
func HashDemo() { 
    fmt.Println("-----------------------welcome to HashDemo-----------------------") 
    redisClient := GetRedisClient() 
    if redisClient == nil { 
        fmt.Errorf("HashDemo redisClient is nil") 
        return 
    } 
    article := Article{18, "测试文章内容22222", "测试文章内容22222测试文章内容22222测试文章内容22222", 10, 0} 
    articleKey := "article:18" 
  
    redisClient.HMSet(articleKey, ToStringDictionary(&article)) 
    mapOut := redisClient.HGetAll(articleKey).Val() 
    for inx, item := range mapOut { 
        fmt.Printf("/n %s:%s", inx, item) 
    } 
    fmt.Print("/n") 
  
    redisClient.HSet(articleKey, "Content", "测试文章内容") 
    mapOut = redisClient.HGetAll(articleKey).Val() 
    for inx, item := range mapOut { 
        fmt.Printf("/n %s:%s", inx, item) 
    } 
    fmt.Print("/n") 
  
    view, err := redisClient.HIncrBy(articleKey, "Views", 1).Result() 
    if err != nil { 
        fmt.Printf("/n HIncrBy error=%s ", err) 
    } else { 
        fmt.Printf("/n HIncrBy Views=%d ", view) 
    } 
    fmt.Print("/n") 
  
    mapOut = redisClient.HGetAll(articleKey).Val() 
    for inx, item := range mapOut { 
        fmt.Printf("/n %s:%s", inx, item) 
    } 
    fmt.Print("/n") 
} 
zset示例
func redisExample2() { 
	zsetKey := "language_rank" 
	languages := []*redis.Z{ 
		&redis.Z{Score: 90.0, Member: "Golang"}, 
		&redis.Z{Score: 98.0, Member: "Java"}, 
		&redis.Z{Score: 95.0, Member: "Python"}, 
		&redis.Z{Score: 97.0, Member: "JavaScript"}, 
		&redis.Z{Score: 99.0, Member: "C/C++"}, 
	} 
	// ZADD 
	num, err := rdb.ZAdd(zsetKey, languages...).Result() 
	if err != nil { 
		fmt.Printf("zadd failed, err:%v/n", err) 
		return 
	} 
	fmt.Printf("zadd %d succ./n", num) 
 
	// 把Golang的分数加10 
	newScore, err := rdb.ZIncrBy(zsetKey, 10.0, "Golang").Result() 
	if err != nil { 
		fmt.Printf("zincrby failed, err:%v/n", err) 
		return 
	} 
	fmt.Printf("Golang's score is %f now./n", newScore) 
 
	// 取分数最高的3个 
	ret, err := rdb.ZRevRangeWithScores(zsetKey, 0, 2).Result() 
	if err != nil { 
		fmt.Printf("zrevrange failed, err:%v/n", err) 
		return 
	} 
	for _, z := range ret { 
		fmt.Println(z.Member, z.Score) 
	} 
 
	// 取95~100分的 
	op := &redis.ZRangeBy{ 
		Min: "95", 
		Max: "100", 
	} 
	ret, err = rdb.ZRangeByScoreWithScores(zsetKey, op).Result() 
	if err != nil { 
		fmt.Printf("zrangebyscore failed, err:%v/n", err) 
		return 
	} 
	for _, z := range ret { 
		fmt.Println(z.Member, z.Score) 
	} 
} 
 
// 输出结果如下: 
$ ./06redis_demo  
zadd 0 succ. 
Golang's score is 100.000000 now. 
Golang 100 
C/C++ 99 
Java 98 
JavaScript 97 
Java 98 
C/C++ 99 
Golang 100 

完整代码

package main 
 
import ( 
    "fmt" 
    . "github.com/go-redis/redis" 
    . "redisDemo/models" 
    "time" 
    "sync" 
) 
 
func main() { 
    fmt.Println("-----------------------welcome to redisdemo-----------------------") 
    //StringDemo() 
    //ListDemo() 
    //HashDemo() 
    connectPoolTest() 
} 
 
func StringDemo() { 
    fmt.Println("-----------------------welcome to StringDemo-----------------------") 
    redisClient:=GetRedisClient() 
    if redisClient ==nil{ 
        fmt.Errorf("StringDemo redisClient is nil") 
        return 
    } 
 
    name := "张三" 
    key :="name:zhangsan" 
    redisClient.Set(key , name,1 * time.Second) 
    val := redisClient.Get(key) 
    if val == nil { 
        fmt.Errorf("StringDemo get error") 
    } 
    fmt.Println("name", val) 
} 
 
func ListDemo(){ 
    fmt.Println("-----------------------welcome to ListDemo-----------------------") 
    redisClient:=GetRedisClient() 
    if redisClient == nil { 
        fmt.Errorf("ListDemo redisClient is nil") 
        return 
    } 
    articleKey := "article" 
    result,err:=redisClient.RPush(articleKey, "a","b","c").Result() //在名称为 key 的list尾添加一个值为value的元素 
    if err!=nil { 
        fmt.Println(err) 
        return 
    } 
    fmt.Println("result:",result) 
 
    result,err = redisClient.LPush(articleKey, "d").Result() //在名称为 key 的list头添加一个值为value的元素 
    if err!=nil { 
        fmt.Println(err) 
        return 
    } 
    fmt.Println("result:",result) 
 
    length, err := redisClient.LLen(articleKey).Result() 
    if err != nil { 
        fmt.Println("ListDemo LLen is nil") 
    } 
    fmt.Println("length: ", length) // 长度 
 
    mapOut,err1:=redisClient.LRange(articleKey,0,100).Result() 
    if err1!=nil { 
        fmt.Println(err1) 
        return 
    } 
    for inx, item := range mapOut { 
        fmt.Printf("/n %s:%s", inx, item) 
    } 
} 
 
func HashDemo() { 
    fmt.Println("-----------------------welcome to HashDemo-----------------------") 
    redisClient := GetRedisClient() 
    if redisClient == nil { 
        fmt.Errorf("HashDemo redisClient is nil") 
        return 
    } 
    article := Article{18, "测试文章内容22222", "测试文章内容22222测试文章内容22222测试文章内容22222", 10, 0} 
    articleKey := "article:18" 
 
    redisClient.HMSet(articleKey, ToStringDictionary(&article)) 
    mapOut := redisClient.HGetAll(articleKey).Val() 
    for inx, item := range mapOut { 
        fmt.Printf("/n %s:%s", inx, item) 
    } 
    fmt.Print("/n") 
 
    redisClient.HSet(articleKey, "Content", "测试文章内容") 
    mapOut = redisClient.HGetAll(articleKey).Val() 
    for inx, item := range mapOut { 
        fmt.Printf("/n %s:%s", inx, item) 
    } 
    fmt.Print("/n") 
 
    view, err := redisClient.HIncrBy(articleKey, "Views", 1).Result() 
    if err != nil { 
        fmt.Printf("/n HIncrBy error=%s ", err) 
    } else { 
        fmt.Printf("/n HIncrBy Views=%d ", view) 
    } 
    fmt.Print("/n") 
 
    mapOut = redisClient.HGetAll(articleKey).Val() 
    for inx, item := range mapOut { 
        fmt.Printf("/n %s:%s", inx, item) 
    } 
    fmt.Print("/n") 
 
} 
 
func GetRedisClient() *Client { 
    redisdb := NewClient(&Options{ 
        Addr:     "127.0.0.1:6379", 
        Password: "", // no password set 
        DB:       0,                 // use default DB 
    }) 
 
    pong, err := redisdb.Ping().Result() 
    if err != nil { 
        fmt.Println(pong, err) 
    } 
    return redisdb 
} 
 
func GetRedisClientPool() *Client{ 
    redisdb := NewClient(&Options{ 
        Addr: "127.0.0.1:6379", 
        Password: "", 
        DB: 0, 
        PoolSize: 5,}) 
 
    pong, err := redisdb.Ping().Result() 
    if err != nil { 
        fmt.Println(pong, err) 
    } 
    return redisdb 
} 
 
// 连接池测试 
func connectPoolTest() { 
    fmt.Println("-----------------------welcome to connect Pool Test-----------------------") 
    client :=GetRedisClientPool() 
    wg := sync.WaitGroup{} 
    wg.Add(10) 
 
    for i := 0; i < 10; i++ { 
        go func() { 
            defer wg.Done() 
 
            for j := 0; j < 1000; j++ { 
                client.Set(fmt.Sprintf("name%d", j), fmt.Sprintf("xys%d", j), 0).Err() 
                client.Get(fmt.Sprintf("name%d", j)).Result() 
            } 
 
            fmt.Printf("PoolStats, TotalConns: %d, IdleConns: %d/n", client.PoolStats().TotalConns, client.PoolStats().IdleConns); 
        }() 
    } 
    wg.Wait() 
} 

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/18125.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论