Go-连接Redis-学习go-redis包

peter 等级 751 0 0

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()
} 
收藏
评论区

相关推荐

Java连接redis的使用示例
Java连接redis的使用示例          Redis是开源的key-value存储工具,redis通常用来存储结构化的数据,因为redis的key可以包含String、hash、listset和sorted list。          Redisserver目前最稳定的版本是2.8.9,可以到官网[http://redis.io/downlo
05 redis(进阶)
redis ===== 阶段一、认识redis ----------- ##### 1、什么是redis Redis是由意大利人Salvatore Sanfilippo(网名:antirez)开发的一款内存高速缓存数据库。Redis全称为:RemoteDictionary Server,该软件使用C语言编写,Redis是一个key-value存储系统,
3 Redis 的常用五大数据类型
2016-12-21 14:54:20 * * * **该系列文章链接** NoSQL 数据库简介 Redis的安装及及一些杂项基础知识 [Redis 的常用五大数据类型(key,string,hash,list,set,zset)](https://www.oschina.net/action/GoToLink?url=https%3A%2
Django 之redis的应用
redis概述 ------- `redis`是一种`nosql`数据库,他的数据是保存在内存中,同时`redis`可以定时把内存数据同步到磁盘,即可以将数据持久化,并且他比`memcached`支持更多的数据结构(`string`,`list列表[队列和栈]`,`set[集合]`,`sorted set[有序集合]`,`hash(hash表)`) ##
Golang 返回&errorString,而不是errorString的原因
**Errors包** =========== 查看golang的errors包你会发现其源码是: func New(text string) error { return &errorString{text} } // errorString is a trivial implementation of er
Jmeter 实用技巧
**一、什么是redis** redis是一个支持持久化的内存数据库,是Key-Value数据库,存储的value类型有五种,包括string、list、set、zset和hash。如下图所示 ![](https://oscimg.oschina.net/oscnet/ae68818d63d0d8dd05177bed64e5dce080f.png)
NoSQL数据库Redis和MongoDB
redis简介 ------- 一些特点: * Redis的读写性能极高,并且有丰富的特性(发布/订阅、事务、通知等)。 * Redis支持数据的持久化(RDB和AOF两种方式),可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。 * Redis支持多种数据类型,包括:string、hash、list、set,zset、bitm
Redis 哈希(Hash)
Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。 Redis 中每个 hash 可以存储 2的32次方 - 1 键值对(40多亿)。 redis 127.0.0.1:6379> HMSET w3ckey name "redis tutorial" description "redis b
Redis 存储原理(1)
Redis现在基本也算是后台开发的基础服务,基本像Mysql一样普遍在应用中使用了。我第一次接触的Nosql是memcache用来解决夸服务session共享问题。后来因为memcache无法持久化问题改为使用Redis。这次主要针对Redis做一个整理。 ### Redis数据类型 类型 特点说明 String 类型是 Redis 最基本的数据类
Redis——基础数据结构
摘抄自《redis深度历险》。   Redis提供了5种基础数据结构,分别是String,list,set,hash和zset。 1、String --------   Redis所有的键都是String。Redis的String是动态字符串,内部结构类似Java的ArrayList和C++ STL中的Vector。内部分配的容量capacity一般高
Redis为什么这么快
Redis简介 ------- * Redis是一个开源的内存中的数据结构存储系统,它可以用作:**数据库、缓存和消息中间件** * 它支持多种类型的数据结构,如字符串(String),散列(Hash),列表(List),集合(Set),有序集合(Sorted Set或者是ZSet)与范围查询,Bitmaps,Hyperloglogs 和
Redis从入门到放弃系列(二) Hash
Redis从入门到放弃系列(二) Hash --------------------- > 本文例子基于:5.0.4 Hash是Redis中一种比较常见的数据结构,其实现为hashtable/ziplist,默认创建时为ziplist,当到达一定量级时,redis会将ziplist转化为hashtable [Redis从入门到放弃系列(一) String
Redis哈希(Hash)
个人学习笔记 Hash是一个string类型的field和value的映射表,hash适合存储对象。 插入Hash HMSET zxq name "redis tutorial" description "redis basic commands for caching" likes 20 visitors 23000 获取Hash
Redis常用命令
**Redis****常用命令** Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)等 [https://gitee.com/nmwork/RedisUtil](https://gitee.com/nmwork/RedisUtil) 1.   Redis数
Spring Boot Redis RedisTemplate 相关API介绍
Redis五大类型:字符串(String)、哈希/散列/字典(Hash)、列表(List)、集合(Set)、有序集合(sorted set)五种。 SpringBoot集成redis的RedisTemplate,也分别提供的对这些数据类型的操作。 主要有5大类: redisTemplate.opsForValue();//操作字符串 redis