使用redis首先要部署redis,载个安装包,部署下便可,本文不赘述了。redis官网:https://redis.io/git
接着要下载golang的redis资源包,golang官方推荐的有redisgo和go-reids,我的认为go-redis的封装更加人性化,redisgo的调用是基于命令的,go-redis是基于方法的,因此本文先来介绍go-redis的使用。github
2行代码来比较下2种资源包的调用方式:
redisgo: client.Do("SET", "mykey", "我是数据", "EX", "3600")
go-redis:client.Set("mykey", "我是数据", time.Hour)
一样是存储一个1小时后过时的数据,go-redis的调用方式明显更友好。golang
github地址:https://github.com/go-redis/redis
文档地址:https://godoc.org/github.com/go-redis/redis
golang下载资源包至关方便,打开命令行,输入命令:go get -u github.com/go-redis/redis
(使用git命令下载资源包,须要先安装git,没安装git的同窗能够手动下载后放入src目录下)。redis
下载完成会在GOPATH下的src里多了资源包json
导入包:测试
import ( "github.com/go-redis/redis" )
client := redis.NewClient(&redis.Options{ Addr: "127.0.0.1:6379", Password: "123456", DB: 0, }) //延迟到程序结束关闭连接 defer client.Close() //ping pong, err := client.Ping().Result() if err != nil { fmt.Println("ping error", err.Error()) return } fmt.Println("ping result:", pong)
解析:Addr
是redis服务的地址,若是部署的reids没有密码,那Password
就写""
,DB
是对应reids 0-15的db
测试redis连接:pong, err := client.Ping().Result()
spa
//string------------------------------------------------------------------------ key := "go2key" //过时时间1小时 err = client.Set(key, "我是值", time.Hour).Err() if err != nil { fmt.Println("set err", err) return } //获取 value, err := client.Get(key).Result() if err != nil { fmt.Println("Get err", err) return } fmt.Printf("key:%v 值:%~~~~v \n", key, value)
存储命令:Set,过时时间若是是3分钟则写成 3*timt.Minute
client.Set(key, "我是值", time.Hour)
读取命令:Getvalue, err := client.Get(key).Result()
命令行
//json--------------------------------- //存储结构 doctor := Doctor{1, "钟南山", 83, 1, time.Now()} doctorJson, _ := json.Marshal(doctor) client.Set("doctor2", doctorJson, time.Hour) //读取结构 doctorResult, _ := client.Get("doctor2").Result() var doctor2 Doctor //反序列化 json.Unmarshal([]byte(doctorResult), &doctor2) fmt.Println("doctor2", doctor2)
解析:
存储结构其实也是存储string,只是把struc序列化成json,等读取的时候再反序列化成struc
序列化:doctorJson, _ := json.Marshal(doctor)
反序列化:json.Unmarshal([]byte(doctorResult), &doctor2)
code
list是简单的字符串列表,按照插入顺序排序。你能够添加一个元素到列表的头部(左边)或者尾部(右边)。对象
//list---------------------------------------------------- //通道列表 list listKey := "go2list" client.RPush(listKey, "str1", 10, "str2", 15, "str3", 20).Err() //lpop 取出并移除左边第一个元素 first, _ := client.LPop(listKey).Result() fmt.Printf("列表第一个元素 key:%v value:%v \n", first[0], first[1]) //Blpop 取出并移除左边第一个元素, 若是列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 first2, _ := client.BLPop(time.Second*60, listKey).Result() fmt.Printf("列表第一个元素 key:%v value:%v \n", first2[0], first2[1]) //数据长度 listLen, _ := client.LLen(listKey).Result() fmt.Println("list length", listLen) //获取列表 listGet, _ := client.LRange(listKey, 1, 2).Result() fmt.Println("索引1-2的2个元素元素", listGet)
解析:
存储"str1", 10, "str2", 15, "str3", 20
这6个元素到"go2list"
中,使用RPush命令往队列右边加入。
从左边取出第一个元素,取出后,这个元素将会从list里移除,这就很像咱们的消息队列了。first, _ := client.LPop(listKey).Result()
BLPop获取左边第一个元素,若是不存在元素,则会一直堵塞,直到time.Second*60
60秒内有数据加入,被取出为止。first2, _ := client.BLPop(time.Second*60, listKey).Result()
获取整个列表数据,这是不会移除数据的listGet, _ := client.LRange(listKey, 1, 2).Result()
关于list的命令还有不少,例如LPush、Rpop、BRpop、LLen等等
hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。能够不用直接获取和更新对象的某个属性。
//hash------------------------------------------- hashKey := "userkey_1" //set hash 适合存储结构 client.HSet(hashKey, "name", "叶子") client.HSet(hashKey, "age", 18) //get hash hashGet, _ := client.HGet(hashKey, "name").Result() fmt.Println("HGet name", hashGet) //获取全部hash 返回map hashGetAll, _ := client.HGetAll(hashKey).Result() fmt.Println("HGetAll", hashGetAll)
解析:
存储name属性为叶子,age属性为18的对象到userkey_1中client.HSet(hashKey, "name", "叶子")
获取某个属性hashGet, _ := client.HGet(hashKey, "name").Result()
获取userkey_1全部的属性,返回的是一个map对象hashGetAll, _ := client.HGetAll(hashKey).Result()
set 是 string 类型的无序集合。
//set-------------------------------------------- setKey := "go2set" client.SAdd(setKey, "set1") client.SAdd(setKey, "set2") client.SAdd(setKey, "set3") client.SAdd(setKey, "set4") //获取集合的全部成员 setList, _ := client.SMembers(setKey).Result() fmt.Println("GetSet", setList) //移除集合里的set1 client.SRem(setKey, "set1") //移除并返回set的一个随机元素 setFirst, _ := client.SPop(setKey).Result() fmt.Println("setFirst", setFirst)
解析:
往集合里添加数据client.SAdd(setKey, "set1")
获取集合的全部的元素setList, _ := client.SMembers(setKey).Result()
移除并返回set的一个随机元素,由于set是无序的setFirst, _ := client.SPop(setKey).Result()
set是有序的,适合作排行榜业务,咱们来模拟一个医生热度排行
//zset------------------------------------------------ zsetKey := "go2zset" ranking := []*redis.Z{ &redis.Z{Score: 100.0, Member: "钟南山"}, &redis.Z{Score: 80.0, Member: "林医生"}, &redis.Z{Score: 70.0, Member: "王医生"}, &redis.Z{Score: 75.0, Member: "张医生"}, &redis.Z{Score: 59.0, Member: "叶医生"}, } client.ZAdd(zsetKey, ranking...) //golang+5分 newScore, err := client.ZIncrBy(zsetKey, 5.0, "钟南山").Result() fmt.Println("钟南山加5分后的最新分数", newScore) //取zset里的前2名热度的医生 zsetList2, _ := client.ZRevRangeWithScores(zsetKey, 0, 1).Result() fmt.Println("zset前2名热度的医生", zsetList2)
解析:
往zset里加入集合数据,数据是[]*redis.Z
类型,里面包含Score
和Member
2个属性client.ZAdd(zsetKey, ranking...)
给钟南山加上5分,返回钟南山的最新热度分值newScore, err := client.ZIncrBy(zsetKey, 5.0, "钟南山").Result()
获取前2名热度的医生,前2名,因此索引是从0到1。zsetList2, _ := client.ZRevRangeWithScores(zsetKey, 0, 1).Result()
操做string数据的时候,能够在方法里直接传入过时时间。但list、hash、set、zset都没有直接提供相应参数,但redis能够额外设置key的过时时间
//Expire------------------------------------------ //设置过时时间 30秒后过时 client.Expire(hashKey, time.Second*30) client.ExpireAt(hashKey, time.Now().Add(time.Second*30)) //删除key //client.Del("go2key", "go2list") //ttl 获取key的生存时间 duration, err := client.TTL(key).Result() if err != nil { fmt.Println("TTL err", err) return } fmt.Printf("key%v的有效时间,%v,%v \n", key, duration.String(), duration.Seconds())
package main import ( "encoding/json" "fmt" "github.com/go-redis/redis" "time" ) type Doctor struct { ID int64 Name string Age int Sex int AddTime time.Time } func main() { client := redis.NewClient(&redis.Options{ Addr: "127.0.0.1:6379", Password: "123456", DB: 0, }) //延迟到程序结束关闭连接 defer client.Close() //ping pong, err := client.Ping().Result() if err != nil { fmt.Println("ping error", err.Error()) return } fmt.Println("ping result:", pong) //string------------------------------------------------------------------------ key := "go2key" //过时时间1小时 err = client.Set(key, "我是值", time.Hour).Err() if err != nil { fmt.Println("set err", err) return } //获取 value, err := client.Get(key).Result() if err != nil { fmt.Println("Get err", err) return } fmt.Printf("key:%v 值:%v \n", key, value) //list------------------------------------------------------------------------ //通道列表 list listKey := "go2list" client.RPush(listKey, "str1", 10, "str2", 15, "str3", 20).Err() //lpop 取出并移除左边第一个元素 first, _ := client.LPop(listKey).Result() fmt.Printf("列表第一个元素 key:%v value:%v \n", first[0], first[1]) //Blpop 取出并移除左边第一个元素, 若是列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 first2, _ := client.BLPop(time.Second*60, listKey).Result() fmt.Printf("列表第一个元素 key:%v value:%v \n", first2[0], first2[1]) //数据长度 listLen, _ := client.LLen(listKey).Result() fmt.Println("list length", listLen) //获取列表 listGet, _ := client.LRange(listKey, 1, 2).Result() fmt.Println("索引1-2的2个元素元素", listGet) //json------------------------------------------------------------------------ //存储结构 doctor := Doctor{1, "钟南山", 83, 1, time.Now()} doctorJson, _ := json.Marshal(doctor) client.Set("doctor2", doctorJson, time.Hour) //读取结构 doctorResult, _ := client.Get("doctor2").Result() var doctor2 Doctor //反序列化 json.Unmarshal([]byte(doctorResult), &doctor2) fmt.Println("doctor2", doctor2) //hash------------------------------------------------------------------------ hashKey := "gohash" //set hash 适合存储结构 client.HSet(hashKey, "name", "叶子") client.HSet(hashKey, "age", 18) //get hash hashGet, _ := client.HGet(hashKey, "name").Result() fmt.Println("HGet name", hashGet) //获取全部hash 返回map hashGetAll, _ := client.HGetAll(hashKey).Result() fmt.Println("HGetAll", hashGetAll) //set------------------------------------------------------------------------ setKey := "go2set" client.SAdd(setKey, "set1") client.SAdd(setKey, "set2") client.SAdd(setKey, "set3") client.SAdd(setKey, "set4") //获取集合的全部成员 setList, _ := client.SMembers(setKey).Result() fmt.Println("GetSet", setList) //移除集合里的set1 client.SRem(setKey, "set1") //移除并返回set的一个随机元素 setFirst, _ := client.SPop(setKey).Result() fmt.Println("set的随机元素", setFirst) //zset------------------------------------------------------------------------ zsetKey := "go2zset" ranking := []*redis.Z{ &redis.Z{Score: 100.0, Member: "钟南山"}, &redis.Z{Score: 80.0, Member: "林医生"}, &redis.Z{Score: 70.0, Member: "王医生"}, &redis.Z{Score: 75.0, Member: "张医生"}, &redis.Z{Score: 59.0, Member: "叶医生"}, } client.ZAdd(zsetKey, ranking...) //golang+5分 newScore, err := client.ZIncrBy(zsetKey, 5.0, "钟南山").Result() fmt.Println("钟南山加5分后的最新分数", newScore) //取zset里的前2名热度的医生 zsetList2, _ := client.ZRevRangeWithScores(zsetKey, 0, 1).Result() fmt.Println("zset前2名热度的医生", zsetList2) //Expire------------------------------------------------------------------------ //设置过时时间 30秒后过时 client.Expire(hashKey, time.Second*30) client.ExpireAt(hashKey, time.Now().Add(time.Second*30)) //删除key //client.Del("go2key", "go2list") //ttl 获取key的生存时间 duration, err := client.TTL(key).Result() if err != nil { fmt.Println("TTL err", err) return } fmt.Printf("key%v的有效时间,%v,%v \n", key, duration.String(), duration.Seconds()) }
以上就是redis经常使用的方法示例,go-redis的封装很是的友好,全部的方法名与redis本身的命令都是相对应的,很是易于理解,即使不看文档,只要你熟悉redis命令,使用起来也是很顺畅的。