2 Go 数据库IO(二):Redis操作

一、Redis概述

Redis是一个内存数据结构存储系统。它主要有以下特点:

  • 与其他数据库不同,它的数据主要存储在内存中,当然为了数据安全它也有磁盘存储备份。由于内存存储,所以它性能非常高。
  • 与其他K-V缓存系统不同,它提供多种数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) ,甚至提供Sub/Pub机制,你可以以此构建简单的消息队列。

Redis中文网提供了完整的Redis命令文档,你可以进入学习相关的常用命令。

二、Go 使用Redis

Go中对redis的支持一般都使用第三方包,这里我们使用redigo,其github star 6k,有较高的使用或支持率,维护比较稳定,不用担心有大坑。

安装:

go get -u github.com/gomodule/redigo/redis

1.redigo的简单使用
import (
    "fmt"
    "github.com/garyburd/redigo/redis"
    "strconv"
    "time"
)

func BaseRedis() {
    //go 连接Redis操作,类似拨号连接tcp,其端口号默认6379
    conn, err := redis.Dial("tcp", "localhost:6379")
    ErrorHandler(err, "redis.Dial")
    defer conn.Close()

    //执行一项操作时如果知道值返回类型可用以下写法
    //一般Set类的设置值操作成功都返回"OK"
    //Get类操作返回Int、String、Strings、Bool、Bytes、ByteSlices,Int等等,可先输出调试再用特定类型接收

    //Set结果的原始类型string,值为OK
    reply1, err := redis.String(conn.Do("Set", "name", "fun"))
    ErrorHandler(err, "conn.Do:Set")

    //Get结果的原始类型[]uint8,值为fun
    reply2, err := redis.String(conn.Do("Get", "name"))
    ErrorHandler(err, "conn.Do:Get")

    //setex结果的原始类型string,值为OK
    reply3, err := conn.Do("setex", "myname", "60", "bill")
    ErrorHandler(err, "conn.Do:setex")

    reply4, err := conn.Do("persist", "myname")
    ErrorHandler(err, "conn.Do:persist")

    reply5, err := conn.Do("mset", "age", "60", "gender", "male")
    ErrorHandler(err, "conn.Do:mset")
    
    reply6, err := conn.Do("hmset", "bangzhu", "name", "jobs", "age", 10000)
    ErrorHandler(err, "conn.Do:hmset")
    
    reply7, err := conn.Do("hgetall", "bangzhu")
    ErrorHandler(err, "conn.Do:hgetall")
    
    reply8, err := conn.Do("rpush", "mydearlist", 11, 22, 33)
    ErrorHandler(err, "conn.Do:rpush")
    
    reply9, err := conn.Do("lrange", "fucklist", 0, -1)
    ErrorHandler(err, "conn.Do:lrange")
    
    reply10, err := conn.Do("sadd", "mydearset", 1, 2, 3)
    ErrorHandler(err, "conn.Do:sadd")
    
    reply11, err := conn.Do("smembers", "mydearset")
    ErrorHandler(err, "conn.Do:smembers")
    
    reply12, err := conn.Do("zadd", "mz", 10, "bill", 9, "bangzhu", 8, "zuckberg")
    ErrorHandler(err, "conn.Do:zadd")

    reply13, err := conn.Do("zrange", "mz", 0, -1)
    ErrorHandler(err, "conn.Do:zrange")
    
    //输出执行结果
    fmt.Printf("Set结果的原始类型%T,值为%v\n", reply1, reply1)
    fmt.Printf("Get结果的原始类型%T,值为%v\n", reply2, reply2)
    fmt.Printf("Setex结果的原始类型%T,值为%v\n", reply3, reply3)
    fmt.Printf("persist结果的原始类型%T,值为%v\n", reply4, reply4)
    fmt.Printf("mset结果的原始类型%T,值为%v\n", reply5, reply5)
    fmt.Printf("hmset结果的原始类型%T,值为%v\n", reply6, reply6)
    fmt.Printf("hgetall结果的原始类型%T,值为%s\n", reply7, reply7)
    fmt.Printf("rpush结果的原始类型%T,值为%v\n", reply8, reply8)
    fmt.Printf("lrange结果的原始类型%T,值为%v\n", reply9, reply9)
    fmt.Printf("sadd结果的原始类型%T,值为%v\n", reply10, reply10)
    fmt.Printf("smembers结果的原始类型%T,值为%s\n", reply11, reply11)
    fmt.Printf("zadd结果的原始类型%T,值为%v\n", reply12, reply12)
    fmt.Printf("zrange结果的原始类型%T,值为%s\n", reply13, reply13)


    //输出执行结果
    //Set结果的原始类型string,值为OK
    //Get结果的原始类型string,值为fun
    //Setex结果的原始类型string,值为OK
    //persist结果的原始类型int64,值为1
    //mset结果的原始类型string,值为OK
    //hmset结果的原始类型string,值为OK
    //hgetall结果的原始类型[]interface {},值为[name jobs age 10000]
    //rpush结果的原始类型int64,值为21
    //lrange结果的原始类型[]interface {},值为[]
    //sadd结果的原始类型int64,值为0
    //smembers结果的原始类型[]interface {},值为[1 2 3]
    //zadd结果的原始类型int64,值为0
    //zrange结果的原始类型[]interface {},值为[zuckberg bangzhu bill]
    //zrange结果的原始类型[]interface {},值为[zuckberg bangzhu bill]
    
}

redigo内置连接池的实现:以下示例演示开启一个连接池最高活动连接数为50,最大闲置连接数为20。开启100个协程从连接池获取连接并执行命令。

//go redis 连接池
func BaseRedisPoll() {

    //配置并获得一个连接池对象的指针
    poolPtr := &redis.Pool{
        //最大活动链接数。0为无限
        MaxActive: 50,

        //最大闲置链接数,0为无限
        MaxIdle: 20,

        //闲置链接超时时间
        IdleTimeout: time.Second * 100,

        Dial: func() (redis.Conn, error) {
            conn, e := redis.Dial("tcp", "localhost:6379")
            return conn, e
        }}

    defer poolPtr.Close()

    for i := 1; i <= 100; i++ {
        //并发100写入redis
        go func(pool *redis.Pool, n int) {
            //从连接池中获取一个连接
            conn := poolPtr.Get()
            //协程执行完成后释放连接
            defer conn.Close()

            key := "name" + strconv.Itoa(n)
            fmt.Println(key)
            _, err := redis.String(conn.Do("Set", key, n))
            ErrorHandler(err, "conn.Do")
            //fmt.Println(res)

        }(poolPtr, i)
    }

    //为了让协程有足够时间执行,保持主协程存活,
    //Tips:主协程死亡后协程也不存在!
    time.Sleep(3 * time.Second)

    fmt.Println("并发连接池执行完成!")

}

至此Redis的基本使用到此结束,更多使用方式会在实战篇展开。Redis常被用作数据层之上的缓存层,搭建redis缓存层可缓解数据库IO阻塞,从而加大系统地访问性能。另一个使用场景Redis也可以被设计成简单的Sub/Pub消息队列,以达到业务异步IO的功能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值