一、redis介绍

REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的一个完全开源免费的,遵守BSD协议的高性能key-value数据库。

Redis 的特点有:

  • Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
  • Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
  • Redis支持数据的备份,即master-slave模式的数据备份。
  • 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
  • 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
  • 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
  • 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

 

二、go语言操作redis

2.1、redis里增、删、改、查字符串类型的键值对操作

redis里一个键最大能存储512MB数据

package main

import (
    "fmt"
    "github.com/garyburd/redigo/redis"    // 连接redis的包
)

func main() {
    // 连接redis
    c, err := redis.Dial("tcp", "localhost:6379")
    if err != nil {
        fmt.Println("conn redis failed,", err)
        return
    }
    // 定义defer关闭连接
    defer c.Close()

    // redis里set key,不设置过期时间
    _, err = c.Do("Set", "abc", 100)
    if err != nil {
        fmt.Println(err)
        return
    }
    // redis里set key并设置过期时间为10秒
    _, err = c.Do("Set", "bcd", 200, "ex", "10")
    if err != nil {
        fmt.Println(err)
        return
    }

    // redis里get key
    r, err := redis.Int(c.Do("Get", "abc"))
    if err != nil {
        fmt.Println("get abc failed,", err)
        return
    }
    // 打印get结果
    fmt.Println(r)     // 结果:100

    // 修改key的值
    _, err = c.Do("Set", "abc", 300)
    if err != nil {
        fmt.Println(err)
        return
    }

    // redis里get key
    r, err = redis.Int(c.Do("Get", "abc"))
    if err != nil {
        fmt.Println("get abc failed,", err)
        return
    }
    // 打印get结果
    fmt.Println(r)     // 结果:300

    // 往key的值里追加内容
    _, err = c.Do("Append", "abc", 12)
    if err != nil {
        fmt.Println(err)
        return
    }
    // redis里get key
    r, err = redis.Int(c.Do("Get", "abc"))
    if err != nil {
        fmt.Println("get abc failed,", err)
        return
    }
    // 打印get结果
    fmt.Println(r)     // 结果:30012

    // 获取key对应值得长度
    r, err = redis.Int(c.Do("Strlen", "abc"))
    if err != nil {
        fmt.Println("get abc failed,", err)
        return
    }
    fmt.Println("redis values len is:", r)    // 结果为:redis values len is: 5

    // 删除key
    _, err = c.Do("Del", "abc")
    if err != nil {
        fmt.Println(err)
        return
    }
    // redis里get key
    _, err = redis.Int(c.Do("Get", "abc"))
    if err != nil {
        fmt.Println("get abc failed,", err)   // 这里报错了:get abc failed, redigo: nil returned
        return
    }
}

 

2.2、Mset/Mget设置多个键值对得操作

package main

import (
    "fmt"

    "github.com/garyburd/redigo/redis"      // 连接redis的包
)

func main() {
    c, err := redis.Dial("tcp", "localhost:6379")
    if err != nil {
        fmt.Println("conn redis failed,", err)
        return
    }

    defer c.Close()
    _, err = c.Do("MSet", "abc", 100, "efg", 300)
    if err != nil {
        fmt.Println(err)
        return
    }

    r, err := redis.Ints(c.Do("MGet", "abc", "efg"))
    if err != nil {
        fmt.Println("get abc failed,", err)
        return
    }

    for _, v := range r {
        fmt.Println(v)
    }
}
/*
结果为:
    100
    300
*/

 

2.3、hash表操作:Hset/Hget

package main

import (
    "fmt"

    "github.com/garyburd/redigo/redis"
)

func main() {
    // redis连接信息
    c, err := redis.Dial("tcp", "localhost:6379")
    if err != nil {
        fmt.Println("conn redis failed,", err)
        return
    }
    // 设置defer关闭redis连接
    defer c.Close()

    // Hset操作
    _, err = c.Do("HSet", "books", "abc", 100)
    if err != nil {
        fmt.Println(err)
        return
    }

    // Hget操作
    r, err := redis.Int(c.Do("HGet", "books", "abc"))
    if err != nil {
        fmt.Println("get abc failed,", err)
        return
    }
    fmt.Println(r)     // 打印Hget结果,结果为:100

    // Hdel删除key
    _, err = c.Do("HDel", "books", "abc")
    if err != nil {
        fmt.Println(err)
        return
    }
    
    // Hget操作
    _, err = redis.Int(c.Do("HGet", "books", "abc"))
    if err != nil {
        fmt.Println("get abc failed,", err)       // 结果为:get abc failed, redigo: nil returned
        return
    }
}

 

2.4、列表操作

package main

import (
    "fmt"

    "github.com/garyburd/redigo/redis"    // 连接redis的包
)

func main() {
    // redis连接信息与定义defer关闭redis
    c, err := redis.Dial("tcp", "localhost:6379")
    if err != nil {
        fmt.Println("conn redis failed,", err)
        return
    }
    defer c.Close()

    // lpush:从头部写入,从头部往book_list key里写入三个数据
    _, err = c.Do("lpush", "book_list", "abc", "ceg", 300)
    if err != nil {
        fmt.Println(err)
        return
    }

    // rpush:从尾部写入:从尾部往book_list key里写入两个数据
    _, err = c.Do("rpush", "book_list", "bcd", 200)
    if err != nil {
        fmt.Println(err)
        return
    }

    // 获取列表字符串长度
    r, err := redis.Int(c.Do("llen", "book_list"))
    if err != nil {
        fmt.Println("len book_list failed", err)
        return
    }
    fmt.Println("book_list len is:", r)    // 结果为:book_list len is: 5

    // 查看指定位置的数据(-1表示最后的字符串)
    r, err = redis.Int(c.Do("lindex", "book_list", "-1"))
    if err != nil {
        fmt.Println("lindex data", err)
        return
    }
    fmt.Println("lindex data is:", r)     // 结果为:lrange data is: 200

    // 从列表头部获取数据,获取数据后列表里就没有这个数据了
    r, err = redis.Int(c.Do("lpop", "book_list"))
    if err != nil {
        fmt.Println("get abc failed,", err)
        return
    }
    fmt.Println(r)      // 结果为:300
}

2.5、redis连接池使用

package main

import (
    "fmt"

    "github.com/garyburd/redigo/redis"     // 连接redis的包
)

var pool *redis.Pool

func init() {
    pool = &redis.Pool{
        MaxIdle:     16,      // 最大空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连接将被标记为不可用,然后被释放。设为0表示无限制。
        MaxActive:   128,     // 连接池的最大数据库连接数。设为0表示无限制。
        IdleTimeout: 300,     // 超时时间
        Dial: func() (redis.Conn, error) {
            return redis.Dial("tcp", "localhost:6379")
        },
    }
}

func main() {
    // 获取redis连接池并设置defer关闭redis连接
    c := pool.Get()
    defer c.Close()

    // redis set操作
    _, err := c.Do("Set", "abc", 100)
    if err != nil {
        fmt.Println(err)
        return
    }

    // redis get操作
    r, err := redis.Int(c.Do("Get", "abc"))
    if err != nil {
        fmt.Println("get abc failed,", err)
        return
    }

    // 打印get结果
    fmt.Println(r)
    // 关闭连接池
    pool.Close()
}