这是我参与【第五届青训营】伴学笔记创作活动的第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)
}
}
}