赞
踩
Redis 是一个开源、使用 ANSI C 语言编写、遵循 BSD 协议、支持网络、可基于内存亦可持久化的日志型、Key-Value 型数据库并提供多种语言支持。
它通常被称为数据结构服务器,因为其中的值(Value)可以是字符串(String)、哈希(Hash)、列表(List)、集合(Set)和有序集合(Sorted Set)等类型,可用于缓存、事件发布或订阅、高速队列等场景。
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list
sudo apt-get update
sudo apt-get install redis -y
## 运行 redis
redis-server
## 内置客户端与 redis 交互
redis-cli
sudo snap install redis
## 运行 redis
redis-server
## 内置客户端与 redis 交互
redis-cli
wget https://download.redis.io/releases/redis-7.0.8.tar.gz
tar xvf redis-7.0.8.tar.gz
mv redis-7.0.8 redis
mv redis /usr/local/
cd /usr/local/redis/
## 编译生成二进制文件
make
## 安装
make PREFIX=/usr/local/redis install
## src 目录下运行 redis
src/redis-server
## 内置客户端与 redis 交互
src/redis-cli
在目录 /usr/local/redis
下存在一个 redis.conf
配置文件,这里列举下比较重要的配置项:
配置项名称 | 配置项值范围 | 说明 |
---|---|---|
daemonize | yes、no | yes 表示启用守护进程,默认是 no 即不以守护进程方式运行,其中 Windows 系统下不支持启用守护进程方式运行 |
port | 指定 Redis 监听端口,默认端口为 6379 | |
bind | 绑定的主机地址,如果需要设置远程访问则直接将这个属性备注下或者改为bind 即可,这个属性和下面的 protected-mode 控制了是否可以远程访问 | |
protected-mode | yes 、no | 保护模式,该模式控制外部网是否可以连接 Redis 服务,默认是 yes ,默认外网是无法访问的,如需外网连接 Redis 服务则需要将此属性改为 no |
timeout | 300 | 当客户端闲置多长时间后关闭连接,如果指定为 0 ,表示关闭该功能 |
loglevel | debug、verbose、notice、warning | 日志级别,默认为 notice |
databases | 16 | 设置数据库的数量,默认的数据库是 0 |
rdbcompression | yes、no | 指定存储至本地数据库时是否压缩数据,默认为 yes,Redis 采用 LZF 压缩,如果为了节省 CPU 时间,可以关闭该选项,但会导致数据库文件变的巨大 |
dbfilename | dump.rdb 指定本地数据库文件名,默认值为 dump.rdb | |
dir | 指定本地数据库存放目录 | |
requirepass | 设置 Redis 连接密码,如果配置了连接密码,客户端在连接 Redis 时需要通过 AUTH 命令提供密码,默认关闭 | |
maxclients | 0 | 设置同一时间最大客户端连接数,默认无限制,Redis 可以同时打开的客户端连接数为 Redis 进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis 会关闭新的连接并向客户端返回 max number of clients reached 错误信息 |
maxmemory | XXX | 指定 Redis 最大内存限制,Redis 在启动时会把数据加载到内存中,达到最大内存后,Redis 会先尝试清除已到期或即将到期的 Key ,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作,Redis 新的 vm 机制,会把 Key 存放内存,Value 会存放在 swap 区,配置项值范围列里 XXX 为数值 |
将 daemonize 改为 yes ,不然每次启动都得在 redis-server 命令后面加符号 & ,不这样操作则只要回到 Linux 控制台则 redis 服务会自动关闭,同时也将 bind 注释,将 protected-mode 设置为 no,启动后就可以在外网访问了。
字符串是 Redis 的基本数据结构之一,由 Key 和 Value 组成(可类比成编程语言的变量:Key 代表变量名,Value 代表变量值)。
(1)查看所有的 key ,输入如下命令:
keys *
(2)创建字符串,输入如下命令:
// 若 value 中有空格,则需要用 " " 将 value 包裹起来(如:set abc "a b c")
set key value
(3)读取字符串,输入如下命令:
// 读取 key,不存在则返回 nil
get key
(4)修改 key 中的值,输入如下命令:
// 不存在就创建,存在则修改 set key new_value // 不存在就创建,存在则返回 nil set key value NX // 不存在就创建,存在则拼接字符串,返回 len (拼接后字符串) append key value // key 为数字是修改(key 对应 value 非数字则报错) // 数字 value + 1 incr key // 数字 value - 1 decr key // 数字 value + n incrby key n // 数字 value - n decrby key n
(5)删除字符串,输入如下命令:
// 删除,存在返回 1 ,不存在返回 0
del key
Redis 中的哈希(Hash)是一个 string 类型的 field (字段)和 value (值)的映射表,特别适合用于存储对象,Redis 中每个哈希表可以存储 2^32 - 1 个键值对。
(1)添加数据,输入如下命令:
// 添加 1 个键值对
hset key field value
// 添加多个键值对
hmset key field1 value1 [field2 value2]
// 已存在字段则不修改
hsetnx key field value
(2)获取数据,输入如下命令:
// 获得 1 个字段值
hget key field
// 获得多个字段值
hmget key field1 [field2]
// 获得所有字段名和值
hgetall key
// 字段存在返回 1 ,不存在返回 0
HEXISTS key field
// 获得字段数量
hlen key
列表是一种特殊的结构(可类比水管),数据从一端进入,然后从另外一端出去。
(1)插入数据,输入如下命令:
// 从左边插入值
lpush key value
// 从右边插入值
rpush key value
(2)获取列表的长度,输入如下命令:
// 获得列表长度
llen key
(3)查看数据(不会删除数据),输入如下命令:
// 0 最左边数据,-1 最右边数据
lrange key 开始索引 结束索引
(4)弹出数据(会删除数据),输入如下命令:
// 弹出最左边数据
lpop key
// 弹出最右边数据
rpop key
该集合中的数据是无序的,不能重复。
(1)添加数据,输入如下命令:
// 添加 set 元素
sadd key value1 value2 ...
(2)获取集合中元素的数量,输入如下命令:
// 返回集合中元素数量
scard key
// 返回集合中所有元素
smembers key
该集合中的数据是有序的,有序集合会关联 double 类型分数,其中元素不能重复,分数可以重复。
(1)添加数据,输入如下命令:
// 添加数据,score 必须是 double 类型(若输入非 double 类型的数据则报错)
zadd key score1 member1 [score2 member2]
(2)修改数据,输入如下命令:
// 不存在则修改数据,存在则不修改(可添加 NX 参数)
zadd key NX score member
(3)获取数据,输入如下命令:
// 按分数值递增获取分数区间 [min max] 的数据
zrangebyscore key min max [WITHSCORES] [LIMIT offset count]
(4)获得排名,输入如下命令:
// 指定成员排名,分数递增
zrank key member
(5)获取一个值的评分,输入如下命令:
// 获取成员分数,不是成员或 key 不存在则返回 nil
zscore key member
(6)查看某个评分范围内的值有多少,输入如下命令:
// 获取指定分数区间,成员个数
zcount key min max
(1) 下载 redigo
包,输入如下命令:
go get -u github.com/gomodule/redigo
(2)通过调用 redigo
客户端包中的 redis.Dial()
函数来实现连接 Redis 服务器。
例如编写一个连接 Redis 服务器的程序,该程序的具体代码如下:
package main
import (
"fmt"
"github.com/gomodule/redigo/redis"
)
func main() {
conn, err := redis.Dial("tcp", "localhost:6379")
if err != nil {
fmt.Println("conn redis failed, err:", err)
return
}
defer conn.Close()
}
(1)通过调用 redigo
客户端包中的 Do()
方法(该方法直接支持 Redis 的 Set 、Get 、 MSet 、 MGet 、 HSet 、 HGet 等常用命令)来设置字符串。
(2)通过调用 redigo
客户端包中的 redis.String()
函数来获取字符串。
例如编写一个程序设置和获取字符串的程序,该程序的具体代码如下:
package main import ( "fmt" "github.com/gomodule/redigo/redis" ) func main() { conn, err := redis.Dial("tcp", "localhost:6379") if err != nil { fmt.Println("conn redis failed, err:", err) return } defer conn.Close() res, err := conn.Do("Set", "username", "jack"); if err != nil { fmt.Println(err) return } fmt.Println(res) res, err = redis.String(conn.Do("Get", "username")) if err != nil { fmt.Println(err) return } fmt.Println(res) }
(1)通过调用 redigo
客户端包中的 Do()
方法(该方法直接支持 Redis 的 Set 、Get 、 MSet 、 MGet 、 HSet 、 HGet 等常用命令)来批量设置字符串。
(2)通过调用 redigo
客户端包中的 redis.Strings()
函数来获取字符串。
例如编写一个设批量置和获取字符串的程序,该程序的具体代码如下:
package main import ( "fmt" "github.com/gomodule/redigo/redis" ) func main() { conn, err := redis.Dial("tcp", "localhost:6379") if err != nil { fmt.Println("conn redis failed, err:", err) return } defer conn.Close() res, err := conn.Do("MSet", "username", "jack", "phone", "123456789") if err != nil { fmt.Println(err) return } fmt.Println(res) res2, err := redis.Strings(conn.Do("MGet", "username", "phone")) if err != nil { fmt.Println(err) return } fmt.Printf("%T\n", res2) fmt.Println(res2) }
(1)通过调用 redigo
客户端包中的 Do()
方法来设置 hash 类型。
(2)通过调用 redigo
客户端包中的 Do()
函数获取 hash 类型。
例如编写一个设置和获取 hash 类型的程序,该程序的具体代码如下:
package main import ( "fmt" "github.com/gomodule/redigo/redis" ) func main() { conn, err := redis.Dial("tcp", "localhost:6379") if err != nil { fmt.Println("conn redis failed, err:", err) return } defer conn.Close() res, err := conn.Do("HSet", "names", "jim", "barry") if err != nil { fmt.Println(err) return } fmt.Println(res) res2, err := conn.Do("HGet", "names", "jim") // res2, err := redis.Strings(conn.Do("HGet", "names", "jim")) if err != nil { fmt.Println("hget error: ", err) return } fmt.Printf("%T\n", res2) fmt.Println(res2) fmt.Println(string(res2.([]uint8))) }
通过调用 redigo
客户端包中的 Do()
方法来设置过期时间。
例如编写一个设置过期时间的程序,该程序的关键代码部分如下:
res, err := conn.Do("expire", "names", 10)
if err != nil {
fmt.Println("expire error: ", err)
return
}
fmt.Println(res)
(1)通过调用 redigo
客户端包中的 Do()
方法来设置队列。
(2)通过调用 redigo
客户端包中的 redis.String()
函数来获取队列。
例如编写一个设置和获取队列的程序,该程序的具体代码如下:
package main import ( "fmt" "github.com/gomodule/redigo/redis" ) func main() { conn, err := redis.Dial("tcp", "localhost:6379") if err != nil { fmt.Println("conn redis failed, err:", err) return } defer conn.Close() res, err := conn.Do("lpush", "Queue", "jim", "barry", 9) if err != nil { fmt.Println("lpush error: ", err) return } fmt.Println(res) for { r, err := redis.String(conn.Do("lpop", "Queue")) if err != nil { fmt.Println("lpop error: ", err) break } fmt.Println(r) } res4, err := redis.Int(conn.Do("llen", "Queue")) if err != nil { fmt.Println("llen error: ", err) return } fmt.Println(res4) }
Redis 基于 C/S 模式(若需要使用,需显建立连接),建立网络连接耗时,连接池实现多个客户端与服务器连接且不释放,需要时获取已建立的连接,使用完后还给连接池。
通过调用 redigo
客户端包中的 Pool 对象可以建立连接池,使用 Pool 结构体初始化一个连接池的程序代码如下:
pool := &redis.Pool{
MaxIdle: 16, // 最大空闲连接数,表示即使没有 Redis 链接时,依然可以保持 n 个空闲的连接,随时处于待命到状态
MaxActive: 1024, // 最大激活连接数,表示可以同时最多有 n 个连接
IdleTimeout: 300, // 最大空闲连接等待时间,超过该时间后空闲的连接将被关闭
Dial: func() (redis.Conn, error) {
return redis.Dial("tcp", "localhost:6379")
},
}
例如编写一个实现 Redis 连接池的程序,该程序的具体代码如下:
package main import ( "fmt" "github.com/gomodule/redigo/redis" ) var pool *redis.Pool func init() { pool = &redis.Pool{ MaxIdle: 16, //最大空闲连接数 MaxActive: 1024, //最大激活连接数 IdleTimeout: 300, //最大空闲连接等待时间 Dial: func() (redis.Conn, error) { return redis.Dial("tcp", "localhost:6379") }, } } func main() { c := pool.Get() defer c.Close() _, err := c.Do("Set", "username", "jack") if err != nil { fmt.Println(err) return } r, err := redis.String(c.Do("Get", "username")) if err != nil { fmt.Println(err) return } fmt.Println(r) }
请求 / 响应服务可以实现持续处理新的请求,客户端可以发送多个命令到服务器端而无须等待响应,最后一次性读取多个响应。
Send()
、Flush()
、Recive()
方法支持管道化操作,Send()
方法用于向连接的输出缓冲写入命令;Flush()
方法用于将连接的缓冲清空并写入服务器端;Recive()
方法用于按照 FIFO 顺序依次读取服务端的响应。
例如编写一个实现 Redis 管道操作的程序,该程序的具体代码如下:
package main import ( "fmt" "github.com/gomodule/redigo/redis" ) func main() { c, err := redis.Dial("tcp", "localhost:6379") if err != nil { fmt.Println("conn redis failed, err:", err) return } defer c.Close() // 输出缓冲区写入命令 c.Send("SET", "username1", "jim") c.Send("SET", "username2", "jack") c.Flush() // 清空输出缓冲区,并写入服务器端 // FIFO 顺序读取服务器端响应 v, err := c.Receive() fmt.Printf("v:%v,err:%v\n", v, err) v, err = c.Receive() fmt.Printf("v:%v,err:%v\n", v, err) // 一直等待 v, err = c.Receive() fmt.Printf("v:%v,err:%v\n", v, err) }
Redis 管道可以使客户端能够 “无等待响应” 的方式来连续发送多条命令请求至 Redis 服务器端,然后服务器按照请求的顺序返回响应的结果,例如如下的形式:
client> set key1 value1
client> set key2 value2
client> set key3 value3
server> ok
server> ok
server> ok
Redis 管道的操作可以理解为并发操作,并通过 Send()
、Flush()
、Recive()
方法实现,客户端可以调用 Send()
方法一次性向服务器发送一个或多个命令,命令发送完后调用 Flush()
方法用于将缓冲区的命令一次性发送到服务器端,客户端再调用 Recive()
方法用于按照 FIFO 顺序依次读取所有命令的结果。
例如编写一个实现 Redis 并发的程序,该程序的具体代码如下:
package main import ( "fmt" "github.com/gomodule/redigo/redis" ) func main() { conn, err := redis.Dial("tcp", "localhost:6379") if err != nil { fmt.Println("connect redis error :", err) return } defer conn.Close() conn.Send("HSET", "students", "name", "jim", "age", "19") conn.Send("HSET", "students", "score", "100") conn.Send("HGET", "students", "age") conn.Flush() res1, err := conn.Receive() fmt.Printf("Receive res1:%v\n", res1) res2, err := conn.Receive() fmt.Printf("Receive res2:%v\n", res2) res3, err := conn.Receive() fmt.Printf("Receive res3:%s\n", res3) }
MUL TI 、EXEC 、 DISCARD 、 WATCH 方法是构成 Redis 事务基础,其方法的具体含义如下:
方法 | 说明 |
---|---|
MUL TI | 开启事务 |
EXEC | 执行事务 |
DISCARD | 取消事务 |
WATCH | 监视事务中的建变化,一旦改变则取消事务 |
例如编写一个实现 Redis 事务的程序,该程序的具体代码如下:
package main import ( "fmt" "github.com/gomodule/redigo/redis" ) func main() { conn, err := redis.Dial("tcp", "localhost:6379") if err != nil { fmt.Println("connect redis error :", err) return } defer conn.Close() conn.Send("MULTI") conn.Send("INCR", "foo") conn.Send("INCR", "bar") r, err := conn.Do("EXEC") if err != nil { conn.Send("DISCARD") // conn.Do("DISCARD") } fmt.Println(r) }
参考连接:Linux安装部署Redis(超级详细)
参考连接:Redis 官网
参考书籍:《Go Web 编程从入门到精通》(廖显东 著)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。