这是我参与「第三届青训营 -后端场」笔记创作活动的第5篇笔记
redis是一个key-value存储系统,数据存储在内存中。
它的优点主要如下:
-
响应快速
Redis 响应非常快,每秒可以执行大约 110 000 个写入操作,或者 81 000 个读操作,其速度远超数据库。如果存入一些常用的数据,就能有效提高系统的性能。
-
支持多种类型
它们是字符串、哈希结构、列表、集合、可排序集合和基数。
-
操作都是原子的
所有 Redis 的操作都是原子的,从而确保当两个客户同时访问 Redis 服务器时,得到的是更新后的值(最新值)。在需要高并发的场合可以考虑使用 Redis 的事务,处理一些需要锁的业务。
redis的缺点主要如下:
- 由于是内存数据库,所以,单台机器,存储的数据量,跟机器本身的内存大小。虽然redis本身有key过期策略,但是还是需要提前预估和节约内存。如果内存增长过快,需要定期删除数据。
- 如果进行完整重同步,由于需要生成rdb文件,并进行传输,会占用主机的CPU,并会消耗现网的带宽。不过redis2.8版本,已经有部分重同步的功能,但是还是有可能有完整重同步的。比如,新上线的备机。
- 修改配置文件,进行重启,将硬盘中的数据加载进内存,时间比较久。在这个过程中,redis不能提供服务。
安装配置redis:
下载:
go get -u github.com/garyburd/redigo/redis
操作set和get
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.Println("redis connect failed. err = ", err)
return
}
defer conn.Close() //关闭连接
// 2.通过go向redis写入数据
_, err = conn.Do("Set", "name", "tomjerry")
if err != nil {
fmt.Println("Set err = ", err)
return
}
// 3.从redis中读取数据
// 由于返回的r是一个interface{},故要转成字符串
r, err := redis.String(conn.Do("Get", "name"))
if err != nil {
fmt.Println("Get err = ", err)
return
}
fmt.Println("操作ok. name =", r) // 操作ok. name = tomjerry
}
设置过期时间
_, err = conn.Do("MSet", "name01", "RSQ", "name02", "Tom")
if err != nil {
fmt.Println("HMSet err = ", err)
return
}
// 设置超时时间
_, err = conn.Do("expire", "name01", 10)
if err != nil {
fmt.Println("Set Expire err = ", err)
return
}
redis连接池
package main
import (
"fmt"
"github.com/garyburd/redigo/redis"
)
// 定义一个全局的pool
var pool *redis.Pool
// 创建连接池
func init() {
pool = &redis.Pool{
MaxIdle: 8, // 表示最大空闲连接数
MaxActive: 0, // 表示和数据库的最大连接数,0表示没有限制
IdleTimeout: 100, // 最大空闲时间
Dial: func() (redis.Conn, error) { // 初始化连接的代码,连接哪个ip的redis
return redis.Dial("tcp", "localhost:6379")
},
}
}
func main() {
conn := pool.Get() // 从连接池中取出一个连接
defer conn.Close() // 关闭连接池,一旦关闭连接池,就不能从连接池再取出连接
_, err := conn.Do("set", "car", "BBB")
if err != nil {
fmt.Println("conn.Do err=", err)
return
}
r, err := redis.String(conn.Do("Get", "car"))
if err != nil {
fmt.Println("read Data err=", err)
return
}
fmt.Println("r=", r)
// 如果要从pool池中取出连接,一定要保证连接池是没有关闭的
}