一、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()
}