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 

连接

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

连接池

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

1func GetRedisClientPool() *Client{ 2 redisdb := NewClient(&Options{ 3 Addr: "127.0.0.1:6379", 4 Password: "", 5 DB: 0, 6 PoolSize: 5,}) 7 8 pong, err := redisdb.Ping().Result() 9 if err != nil { 10 fmt.Println(pong, err) 11 } 12 return redisdb 13} 14 15// 连接池测试 16func connectPoolTest() { 17 fmt.Println("-----------------------welcome to connect Pool Test-----------------------") 18 client :=GetRedisClientPool() 19 wg := sync.WaitGroup{} 20 wg.Add(10) 21 22 for i := 0; i < 10; i++ { 23 go func() { 24 defer wg.Done() 25 26 for j := 0; j < 1000; j++ { 27 client.Set(fmt.Sprintf("name%d", j), fmt.Sprintf("xys%d", j), 0).Err() 28 client.Get(fmt.Sprintf("name%d", j)).Result() 29 } 30 31 fmt.Printf("PoolStats, TotalConns: %d, IdleConns: %d\n", client.PoolStats().TotalConns, client.PoolStats().IdleConns); 32 }() 33 } 34 35 wg.Wait() 36}

基本使用

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的子串
     
1func redisExample() { 2 err := rdb.Set("score", 100, 0).Err() 3 if err != nil { 4 fmt.Printf("set score failed, err:%v\n", err) 5 return 6 } 7 8 val, err := rdb.Get("score").Result() 9 if err != nil { 10 fmt.Printf("get score failed, err:%v\n", err) 11 return 12 } 13 fmt.Println("score", val) 14 15 val2, err := rdb.Get("name").Result() 16 if err == redis.Nil { 17 fmt.Println("name does not exist") 18 } else if err != nil { 19 fmt.Printf("get name failed, err:%v\n", err) 20 return 21 } else { 22 fmt.Println("name", val2) 23 } 24}
1func StringDemo() { 2 fmt.Println("-----------------------welcome to StringDemo-----------------------") 3 redisClient:=GetRedisClient() 4 if redisClient ==nil{ 5 fmt.Errorf("StringDemo redisClient is nil") 6 return 7 } 8 9 name := "张三" 10 key :="name:zhangsan" 11 redisClient.Set(key , name,1 * time.Second) 12 val := redisClient.Get(key) 13 if val == nil { 14 fmt.Errorf("StringDemo get error") 15 } 16 fmt.Println("name", val) 17}
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的头部
1func ListDemo(){ 2 fmt.Println("-----------------------welcome to ListDemo-----------------------") 3 redisClient:=GetRedisClient() 4 if redisClient == nil { 5 fmt.Errorf("ListDemo redisClient is nil") 6 return 7 } 8 articleKey := "article" 9 result,err:=redisClient.RPush(articleKey, "a","b","c").Result() // 10 if err!=nil { 11 fmt.Println(err) 12 return 13 } 14 fmt.Println("result:",result) 15 16 result,err = redisClient.LPush(articleKey, "d").Result() // 17 if err!=nil { 18 fmt.Println(err) 19 return 20 } 21 fmt.Println("result:",result) 22 23 length, err := redisClient.LLen(articleKey).Result() 24 if err != nil { 25 fmt.Println("ListDemo LLen is nil") 26 } 27 fmt.Println("length: ", length) // 长度 28 29 mapOut,err1:=redisClient.LRange(articleKey,0,100).Result() 30 if err1!=nil { 31 fmt.Println(err1) 32 return 33 } 34 for inx, item := range mapOut { 35 fmt.Printf("\n %s:%s", inx, item) 36 } 37}
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
1func HashDemo() { 2 fmt.Println("-----------------------welcome to HashDemo-----------------------") 3 redisClient := GetRedisClient() 4 if redisClient == nil { 5 fmt.Errorf("HashDemo redisClient is nil") 6 return 7 } 8 article := Article{18, "测试文章内容22222", "测试文章内容22222测试文章内容22222测试文章内容22222", 10, 0} 9 articleKey := "article:18" 10 11 redisClient.HMSet(articleKey, ToStringDictionary(&article)) 12 mapOut := redisClient.HGetAll(articleKey).Val() 13 for inx, item := range mapOut { 14 fmt.Printf("\n %s:%s", inx, item) 15 } 16 fmt.Print("\n") 17 18 redisClient.HSet(articleKey, "Content", "测试文章内容") 19 mapOut = redisClient.HGetAll(articleKey).Val() 20 for inx, item := range mapOut { 21 fmt.Printf("\n %s:%s", inx, item) 22 } 23 fmt.Print("\n") 24 25 view, err := redisClient.HIncrBy(articleKey, "Views", 1).Result() 26 if err != nil { 27 fmt.Printf("\n HIncrBy error=%s ", err) 28 } else { 29 fmt.Printf("\n HIncrBy Views=%d ", view) 30 } 31 fmt.Print("\n") 32 33 mapOut = redisClient.HGetAll(articleKey).Val() 34 for inx, item := range mapOut { 35 fmt.Printf("\n %s:%s", inx, item) 36 } 37 fmt.Print("\n") 38}
zset示例
1func redisExample2() { 2 zsetKey := "language_rank" 3 languages := []*redis.Z{ 4 &redis.Z{Score: 90.0, Member: "Golang"}, 5 &redis.Z{Score: 98.0, Member: "Java"}, 6 &redis.Z{Score: 95.0, Member: "Python"}, 7 &redis.Z{Score: 97.0, Member: "JavaScript"}, 8 &redis.Z{Score: 99.0, Member: "C/C++"}, 9 } 10 // ZADD 11 num, err := rdb.ZAdd(zsetKey, languages...).Result() 12 if err != nil { 13 fmt.Printf("zadd failed, err:%v\n", err) 14 return 15 } 16 fmt.Printf("zadd %d succ.\n", num) 17 18 // 把Golang的分数加10 19 newScore, err := rdb.ZIncrBy(zsetKey, 10.0, "Golang").Result() 20 if err != nil { 21 fmt.Printf("zincrby failed, err:%v\n", err) 22 return 23 } 24 fmt.Printf("Golang's score is %f now.\n", newScore) 25 26 // 取分数最高的3个 27 ret, err := rdb.ZRevRangeWithScores(zsetKey, 0, 2).Result() 28 if err != nil { 29 fmt.Printf("zrevrange failed, err:%v\n", err) 30 return 31 } 32 for _, z := range ret { 33 fmt.Println(z.Member, z.Score) 34 } 35 36 // 取95~100分的 37 op := &redis.ZRangeBy{ 38 Min: "95", 39 Max: "100", 40 } 41 ret, err = rdb.ZRangeByScoreWithScores(zsetKey, op).Result() 42 if err != nil { 43 fmt.Printf("zrangebyscore failed, err:%v\n", err) 44 return 45 } 46 for _, z := range ret { 47 fmt.Println(z.Member, z.Score) 48 } 49} 50 51// 输出结果如下: 52$ ./06redis_demo 53zadd 0 succ. 54Golang's score is 100.000000 now. 55Golang 100 56C/C++ 99 57Java 98 58JavaScript 97 59Java 98 60C/C++ 99 61Golang 100

完整代码

1package main 2 3import ( 4 "fmt" 5 . "github.com/go-redis/redis" 6 . "redisDemo/models" 7 "time" 8 "sync" 9) 10 11func main() { 12 fmt.Println("-----------------------welcome to redisdemo-----------------------") 13 //StringDemo() 14 //ListDemo() 15 //HashDemo() 16 connectPoolTest() 17} 18 19func StringDemo() { 20 fmt.Println("-----------------------welcome to StringDemo-----------------------") 21 redisClient:=GetRedisClient() 22 if redisClient ==nil{ 23 fmt.Errorf("StringDemo redisClient is nil") 24 return 25 } 26 27 name := "张三" 28 key :="name:zhangsan" 29 redisClient.Set(key , name,1 * time.Second) 30 val := redisClient.Get(key) 31 if val == nil { 32 fmt.Errorf("StringDemo get error") 33 } 34 fmt.Println("name", val) 35} 36 37func ListDemo(){ 38 fmt.Println("-----------------------welcome to ListDemo-----------------------") 39 redisClient:=GetRedisClient() 40 if redisClient == nil { 41 fmt.Errorf("ListDemo redisClient is nil") 42 return 43 } 44 articleKey := "article" 45 result,err:=redisClient.RPush(articleKey, "a","b","c").Result() //在名称为 key 的list尾添加一个值为value的元素 46 if err!=nil { 47 fmt.Println(err) 48 return 49 } 50 fmt.Println("result:",result) 51 52 result,err = redisClient.LPush(articleKey, "d").Result() //在名称为 key 的list头添加一个值为value的元素 53 if err!=nil { 54 fmt.Println(err) 55 return 56 } 57 fmt.Println("result:",result) 58 59 length, err := redisClient.LLen(articleKey).Result() 60 if err != nil { 61 fmt.Println("ListDemo LLen is nil") 62 } 63 fmt.Println("length: ", length) // 长度 64 65 mapOut,err1:=redisClient.LRange(articleKey,0,100).Result() 66 if err1!=nil { 67 fmt.Println(err1) 68 return 69 } 70 for inx, item := range mapOut { 71 fmt.Printf("\n %s:%s", inx, item) 72 } 73} 74 75func HashDemo() { 76 fmt.Println("-----------------------welcome to HashDemo-----------------------") 77 redisClient := GetRedisClient() 78 if redisClient == nil { 79 fmt.Errorf("HashDemo redisClient is nil") 80 return 81 } 82 article := Article{18, "测试文章内容22222", "测试文章内容22222测试文章内容22222测试文章内容22222", 10, 0} 83 articleKey := "article:18" 84 85 redisClient.HMSet(articleKey, ToStringDictionary(&article)) 86 mapOut := redisClient.HGetAll(articleKey).Val() 87 for inx, item := range mapOut { 88 fmt.Printf("\n %s:%s", inx, item) 89 } 90 fmt.Print("\n") 91 92 redisClient.HSet(articleKey, "Content", "测试文章内容") 93 mapOut = redisClient.HGetAll(articleKey).Val() 94 for inx, item := range mapOut { 95 fmt.Printf("\n %s:%s", inx, item) 96 } 97 fmt.Print("\n") 98 99 view, err := redisClient.HIncrBy(articleKey, "Views", 1).Result() 100 if err != nil { 101 fmt.Printf("\n HIncrBy error=%s ", err) 102 } else { 103 fmt.Printf("\n HIncrBy Views=%d ", view) 104 } 105 fmt.Print("\n") 106 107 mapOut = redisClient.HGetAll(articleKey).Val() 108 for inx, item := range mapOut { 109 fmt.Printf("\n %s:%s", inx, item) 110 } 111 fmt.Print("\n") 112 113} 114 115func GetRedisClient() *Client { 116 redisdb := NewClient(&Options{ 117 Addr: "127.0.0.1:6379", 118 Password: "", // no password set 119 DB: 0, // use default DB 120 }) 121 122 pong, err := redisdb.Ping().Result() 123 if err != nil { 124 fmt.Println(pong, err) 125 } 126 return redisdb 127} 128 129func GetRedisClientPool() *Client{ 130 redisdb := NewClient(&Options{ 131 Addr: "127.0.0.1:6379", 132 Password: "", 133 DB: 0, 134 PoolSize: 5,}) 135 136 pong, err := redisdb.Ping().Result() 137 if err != nil { 138 fmt.Println(pong, err) 139 } 140 return redisdb 141} 142 143// 连接池测试 144func connectPoolTest() { 145 fmt.Println("-----------------------welcome to connect Pool Test-----------------------") 146 client :=GetRedisClientPool() 147 wg := sync.WaitGroup{} 148 wg.Add(10) 149 150 for i := 0; i < 10; i++ { 151 go func() { 152 defer wg.Done() 153 154 for j := 0; j < 1000; j++ { 155 client.Set(fmt.Sprintf("name%d", j), fmt.Sprintf("xys%d", j), 0).Err() 156 client.Get(fmt.Sprintf("name%d", j)).Result() 157 } 158 159 fmt.Printf("PoolStats, TotalConns: %d, IdleConns: %d\n", client.PoolStats().TotalConns, client.PoolStats().IdleConns); 160 }() 161 } 162 wg.Wait() 163}
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )