Go-Redis | 青训营笔记

104 阅读4分钟

这是我参与【第五届青训营】伴学笔记创作活动的第15天

Go-Redis

1.redis基本介绍

  • Redis,英文全称是 Remote Dictionary Server(远程字典服务),是一个基于 C 语言开发的开源数据库(BSD 许可),支持网络、可基于内存、也可持久化的日志型、 Key-Value 数据库,并提供多种语言的 API。
  • 简单来说,Redis就是一款数据库,不过与传统关系型数据库不同的是, Redis 的数据是存在内存中的(内存数据库),读写速度非常快,每秒可以处理超过 10 万次读写操作。
  • 并且,Redis 还支持事务 、持久化、Lua 脚本、主从复制、哨兵、分片 等多种开箱即用的集群方案(Redis Sentinel、Redis Cluster),是目前应用非常广泛的nosql数据库。

2.redis的数据结构

  • 5 种基础数据结构 :String(字符串)、List(列表)、Set(集合)、Hash(散列)、Zset(或SortedSet,有序集合)。
  • 3 种特殊数据结构 :HyperLogLogs(基数统计)、Bitmap (位存储)、Geospatial (地理位置)。
  • 为消息队列设计的数据结构:Stream

3.go使用redis

连接

Conn接口是与Redis 协作的主要接口,可以使用Dial,DialWithTimeout或者NewConn函数来创建连接,当任务完成时,应用程序必须调用Close函数来完成操作

package main
import(
"github.com/garyburd/redigo/redis"
"fmt"
)
 
func main(){
    //相关代码
    conn, err = redis.Dial("tcp", "127.0.0.1:6379")
    if err != nil {
        fmt.Println("connect redis error", err)
        return     
    }
    defer conn.Close()
}

连接池

1).事先初始化一定数量的链接,放入到链接池

2).当go需要操作redis时,直接从redis链接池取出链接即可

3).这样可以节省临时获取redis链接的时间,从而提高效率

package main
 
import (
    "fmt"
    "github.com/garyburd/redigo/redis" //引入redis包
)
 
​
var pool *redis.Pool
​
func init()  {
    pool = &redis.Pool{
        MaxIdle: 8, //最大空闲连接数
        MaxActive: 0, //表示和数据库的最大连接数, 0 表示没有限制
        IdleTimeout: 100, //最大空闲时间
        Dial: func () (redis.Conn, error)  { 
            return redis.Dial("tcp", "127.0.0.1:6379")
        },
    }
}
func main() {
    //从pool取出一个连接
    conn := pool.Get()
    defer conn.Close()
    
    _, err := conn.Do("Set", "name", "wangwu")
    if err != nil {
        fmt.Printf("conn.do set err = %v\n", err)
        return
    }
​
    res, err := conn.Do("Get", "name")
    if err != nil {
        fmt.Printf("conn.do get err = %v\n", err)
        return
    }
    fmt.Printf("conn.do get result = %v\n", res)
}

get,set

package main
 
import (
    "fmt"
    "github.com/garyburd/redigo/redis" //引入redis包
)
 
func main()  {
    //通过go向redis写入数据和读取数据
    //1.连接redis
    conn, err := redis.Dial("tcp", "127.0.0.1:6379")
    if err != nil {
        fmt.Printf("redis Dial err = %v\n", err)
        return
    }
    defer conn.Close() //延时conn
    //2.通过go向redis写入数据string(key-value)
    _, err = conn.Do("Set", "name", "张三")
    if err != nil {
        fmt.Printf("redis set err = %v\n", err)
        return
    }
    //3.通过go向redis读取数据string(key-value)
    res, err := redis.String(conn.Do("Get", "name"))
    if err != nil {
        fmt.Printf("redis set err = %v\n", err)
        return
    }
    fmt.Printf("success %v\n", res)
}

list

    //通过go向redis写入数据和读取数据
    //1.连接redis
    conn, err := redis.Dial("tcp", "127.0.0.1:6379")
    if err != nil {
        fmt.Printf("redis Dial err = %v\n", err)
        return
    }
    defer conn.Close() //延时conn
 
    //list
    _, err = conn.Do("LPush", "list1", "a1", "a2", "a3")
    if err != nil {
        fmt.Printf("redis LPush err = %v\n", err)
        return
    }
    res, err := redis.String(conn.Do("LPop", "list1"))
    if err != nil {
        fmt.Printf("redis LPop err = %v\n", err)
        return
    } else {
        res_type := reflect.TypeOf(res)
        fmt.Printf("res type : %s\n", res_type) 
        fmt.Printf("mget name: %s\n", res) 
    }

hash(哈希)

package main
​
import (
    "fmt"
    "github.com/garyburd/redigo/redis" //引入redis包
)
​
func main()  {
    //通过go向redis写入数据和读取数据
    //1.连接redis
    conn, err := redis.Dial("tcp", "127.0.0.1:6379")
    if err != nil {
        fmt.Printf("redis Dial err = %v\n", err)
        return
    }
    defer conn.Close() //延时conn
    //hset方式单个写入
    //2.通过go向redis写入数据hash 
    _, err = conn.Do("HSet", "user1", "name", "张三")
    if err != nil {
        fmt.Printf("redis hset err = %v\n", err)
        return
    }
    _, err = conn.Do("HSet", "user1", "age", 22)
    if err != nil {
        fmt.Printf("redis hset err = %v\n", err)
        return
    }
    //hget方式单个获取
    //3.通过go向redis读取数据hash
    resName, err := redis.String(conn.Do("HGet", "user1", "name"))
    if err != nil {
        fmt.Printf("redis hset err = %v\n", err)
        return
    }
    resAge, err := redis.Int(conn.Do("HGet", "user1", "age"))
    if err != nil {
        fmt.Printf("redis hset err = %v\n", err)
        return
    }
    fmt.Printf("success user1 name=%v, age=%v\n", resName, resAge)
    //hmset批量方式多个写入
    _, err = conn.Do("HMSet", "user2", "name", "李四", "age", 99)
    if err != nil {
        fmt.Printf("redis hmset err = %v\n", err)
        return
    }
    //hmget批量方式多个获取
    res, err := redis.Strings(conn.Do("HMGet", "user2", "name", "age"))
    if err != nil {
        fmt.Printf("redis hmset err = %v\n", err)
        return
    }
    for i, v := range res {
        fmt.Printf("res[%v] = %v\n", i, v)
    }
}

string

package main
 
import(
    "fmt"
    "strconv"
    "github.com/garyburd/redigo/redis" //引入redis包
)
 
func main()  {
    //连接redis
    conn, err := redis.Dial("tcp", "127.0.0.1:6379")
    if err != nil {
        fmt.Printf("redis Dial err = %v\n", err)
        return
    }
    defer conn.Close() //延时conn
    
    //遍历所有monster信息,并显示到终端
    for i := 1; i <= 3; i++ {
        fmt.Printf("第%d个monster信息:\n", i)
        var name string
        var age int
        var skill string
        fmt.Printf("请输入第%d个monster的姓名:", i)
        fmt.Scanln(&name)
        fmt.Printf("请输入第%d个monster的年龄:", i)
        fmt.Scanln(&age)
        fmt.Printf("请输入第%d个monster的技能:", i)
        fmt.Scanln(&skill)
 
        //hmset方式批量写入
        //通过go向redis写入数据hash 
        _, err = conn.Do("HMSet", "monster" + strconv.Itoa(i), "name", name, "age", age, "skill", skill)
        if err != nil {
            fmt.Printf("redis hmset err = %v\n", err)
            return
        }
    }
 
    //先获取所有keys
    keys, err := redis.Strings(conn.Do("Keys", "monster*"))
    if err != nil {
        fmt.Printf("redis keys err = %v\n", err)
        return
    }
    //遍历keys
    for index, monster := range keys {
        //hmget批量方式多个获取
        res, err := redis.Strings(conn.Do("HMGet", monster, "name", "age", "skill"))
        if err != nil {
            fmt.Printf("redis hmGet err = %v\n", err)
            return
        }
        //遍历单个monster 的hash
        for i, v := range res {
            fmt.Printf("第%d个monster结果: res[%v] = %v\n", index, i, v)
        }
    }
}