Redis
Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库,并提供多种语言的 API。
Redis 通常被称为数据结构服务器,因为值(value)可以是字符串(String)、哈希(Hash)、列表(list)、集合(sets)和有序集合(sorted sets)等类型。
优势
- 性能极高
- 丰富的数据类型 —— Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作
- 原子 —— Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
- 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
Redis与其他key-value存储有什么不同?
- Redis有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。
- Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。
基础
数据类型
string(字符串)
- 最基本类型
- 二进制安全,可以包含任何数据,如 jpg 图片或序列化的对象
- 最大存储 512MB
SET firstKey "Hello World"
GET firstKey
# output: "Hello World"
# 可以通过 DEL firstKey 来删除
hash(哈希)
- 键值对集合
- string 类型的 field 和 value 的映射表
- 适合用于存储对象
- 每个 hash 可以存储 232-1 键值对
HMSET firstHM field1 "Hello World" field2 "Hello Redis"
HGET firstHM field1
# output: "Hello World"
HGET firstHM field2
# output: "Hello Redis"
list(列表)
- 简单的字符串列表,按照插入顺序排序
- 可以添加一个元素到列表头部或尾部
- 列表最多可存储 232-1 个元素
# 插入
lpush firstLS h # 返回下一个 index (integer)1
lpush firstLS e
lpush firstLS l
#查询
lrange firstLS 0 10
# output:
# "h"
# "e"
# "l"
set(集合)
- string 类型的无序集合,不允许有重复的成员
- 集合是通过哈希表实现的,所以添加、删除、查找的复杂度是 O(1)
sadd key member
- 集合最多可存储 232-1 个成员
sadd firstSet hello
sadd firstSet world
sadd firstSet redis
sadd firstSet redis # 元素具有唯一性,第二次插入会被忽略
smembers firstSet
# output:
# "hello"
# "world"
# "redis"
zset(sorted set:有序集合)
- 和 set 一样是 string 类型元素的集合,不允许有重复的成员
- 每个元素会关联一个 double 类型的分数,redis 通过分数来为集合中的成员从小到大排序
- 成员是唯一的,但是分数(score)可以重复
zadd key score member
zadd firstZSet 0 hello
zadd firstZSet 0 world
zadd firstZSet 0 redis
zrangebyscore firstZSet 0 1000
# output:
# "hello"
# "world"
# "redis"
配置
配置文件redis.conf
(windows 为 redis.windows.conf
)
- 查看配置
# CONFIG GET CONFIG_SETTING_NAME
redis 127.0.0.1:6379> CONFIG GET loglevel
# output:
# "loglevel"
# "notice"
redis 127.0.0.1:6379> CONFIG GET * # 获取所有
- 编辑配置
# CONFIG SET CONFIG_SETTING_NAME NEW_CONFIG_VALUE
redis 127.0.0.1:6379> CONFIG SET loglevel "notice"
- 参数说明
redis.config
配置项 | 说明 | |
---|---|---|
daemonize no |
是否已守护进程方式运行,yes | no |
pidfile /var/run/redis.pid |
以守护进程方式运行时,会把 pid 写入 /var/run/redis.pid 文件,可以通过 pidfile 指定 |
|
port 6379 |
指定 Redis 监听端口,默认 6379 | |
bind 127.0.0.1 |
绑定主机地址 | |
timeout 300 |
当客户端闲置多久关闭连接,如果设为 0 ,表关闭该功能 | |
loglevel notice |
日志级别,支持 debug,verbose,notice(默认),warning | |
logfile stdout |
日志记录方式,默认为标准输出 如果以守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志会发送给 /dev/null |
|
databases 16 |
设置数据库数量,默认数据库为 0,可以使用 SELECT 命令在连接上指定数据库 id | |
save <seconds> <changes> |
指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合,如 save 900 1 900秒内有一个更改 |
|
rdbcompression yes |
存储到本地数据库时是否压缩数据,默认为 yes,Redis 采用 LZF 压缩,如果为了节省 CPU 时间,可以关闭该选项,但会使数据库文件变大 | |
dbfilename dump.rdb |
指定本地数据库文件名,默认值为 dump.rdb |
|
dir ./ |
指定本地数据库存放目录 | |
slaveof <masterip> <masterport> |
设置当本机为 slave 服务时,设置 master 服务的 IP 地址及端口,在 Redis 启动时,会自动从 master 进行数据同步 | |
masterauth <master-password> |
当 master 服务设置了密码保护时, slave 服务连接 master 的密码 | |
requirepass foobared |
设置 redis 连接密码 | |
maxclients 128 |
设置同一时间最大客户端连接数,默认无限制,Redis 可以同时打开的客户端连接数为 Redis 进程可以打开的最大文件描述符数 | |
maxmemory <bytes> |
指定 Redis 最大内存限制,redis 在启动时会将数据加载到内存中,达到最大内存后,Redis 会先尝试清除已到期或即将到期的 Key,如果该操作处理后仍达到最大是,就进入只能读不能写状态 | |
appendonly no |
指定是否在每次更新操作后进行日志记录,Redis 默认是异步将数据写入磁盘,如果不开启,可能会在断点时导致一段时间内的数据丢失。默认为 no | |
appendfilename appendonly.aof |
指定更新日志文件名 | |
appendfsync everysec |
指定更新日志条件: no: 表示等操作系统进行数据缓存同步到磁盘(快) always:表示每次更新操作后手动调用 fsync() 将数据写到磁盘(慢,安全) everysec:表示每秒同步一次(折中,默认值) |
|
vm-enabled no |
指定是否启用虚拟内存机制,默认 no | |
vm-swap-file /tmp/redis.swap |
虚拟内存文件路径,默认 /tmp/redis.swap ,不可多个 Redis 实例共享 |
|
vm-max-memory 0 |
将多有大于 vm-max-memory 的数据存入虚拟内存,无论 vm-max-memory 设置多小,所有索引数据都是内存存储的(redis 的索引数据就是 keys) | |
vm-page-size 32 |
Redis swap 文件分成了很多的 page,一个对象可以保存在多个 page 上面,但一个 page 上不能被多个对象共享 | |
vm-pages 134217728 |
设置 swap 文件中的 page 数量 | |
vm-max-threads 4 |
设置访问 swap 文件的线程数,最好不要超过机器的核数,如果设置为 0,那么所有对 swap | |
glueoutputbuf yes |
设置在向客户端应答时,是否把较小的包合并为一个包发送,默认为开启 | |
hash-max-zipmap-entries 64 hash-max-zipmap-value 512 |
指定在超过一定的数量或者最大元素超过某一临界时,采用一种特殊的 hash 算法 | |
aciverehashing yes |
是否激活重置 hash, 默认为开启 | |
include /path/to/local.conf |
指定包含其他的配置文件,可以在同一主机上多个 Redis 实例之间使用同一份配置文件,而同时各个实例拥有自己的特定配置文件 |
Redis 命令
redis-cli
# 连接服务端
redis-cli -h 127.0.0.1 -p 6379 -a password
Redis 键(key)
用于管理 redis 的键
命令 | 描述 |
---|---|
DEL key |
在 key 存在时删除 key |
DUMP key |
序列化给定的 key,并返回被序列化的值 |
EXISTS key |
检查给定 key 是否存在 |
EXPIRE key seconds |
为指定 key 设置过期时间,以秒计 |
EXPIREAT key timestamp |
使用 UNIX 时间戳设置过期时间 |
PEXPIRE key milliseconds |
设置 key 过期时间,以毫秒计 |
PEXPIREAT key milliseconds-timestamp |
设置过期时间戳,以毫秒计 |
KEYS pattern |
查找所有符合给定模式(pattern)的key |
MOVE key db |
将当前数据库中的 key 移动到给定数据库 db 当中 |
PERSIST key |
移除 key 的过期时间,将 key 持久保持 |
PTTL key |
以毫秒为单位返回 key 的剩余过期时间 |
TTL key |
以秒为单位返回 key 的剩余过期时间 |
RANDOMKEY |
从当前数据库中随机返回一个 key |
RENAME key newkey |
修改 key 的名称 |
RENAMENX key newkey |
仅当 newKey 不存在时,将 key 改名为 newkey |
SCAN cursor [MATCH pattern] [COUNT count] |
迭代数据库中的数据库键 |
TYPE key |
返回 key 所存储的值的类型 |
Redis 字符串(String)
命令 | 含义 |
---|---|
SET key value |
设置指定 key 的值 |
GET key |
获取 key 的值 |
GETRANGE key start end |
获取 key 中字符串值的子字符(截取子串) |
GETSET key value |
将给定 key 的值设置为 value,并返回 key 的旧值 |
GETBIT key offset |
对 key 所存储的字符串值,获取指定偏移量上的位(bit) |
MGET key1 [key2 ...] |
获取所有(一个或多个)给定 key 的值 |
SETBIT key offset value |
对 key 所存储的字符串值,设置或清除指定偏移量上的位(bit) |
SETEX key seconds value |
将值 value 关联到 key,并将 key 的过期时间设为 seconds (单位 s) |
SETNX key value |
只有在 key 不存在时设置 key 的值 |
SETRANGE key offset value |
用 value 参数覆写给定 key 所存储的字符串值,从偏移量 offset 开始 |
STRLEN key |
返回 key 所存储的字符串值的长度 |
MSET key value [key value ...] |
同时设置一个或多个 k-v 对,当且仅当所有给定的 key 都不存在 |
PSETEX key milliseconds value |
与 SETEX 一样,但是以毫秒为单位 |
INCR key |
将 key 中存储的数字值增 1 |
INCRBY key increment |
将 key 所存储的值加上给定的增量(increment) |
INCRBYFLOAT key increment |
将 key 所储存的值加上给定的增量值(increment) |
DECR key |
将 key 中储存的数字值减一 |
DECRBY key decrement |
key 所存储的值减去给定的减量值(decrement) |
APPEND key value |
如果 key 已经存在并且是一个字符串,APPEND 命令将指定的 value 追加到该 key 原来值(value)的末尾 |
Redis 哈希(Hash)
命令 | 描述 |
---|---|
HDEL key field1 [field2] |
删除一个或多个字段 |
HEXISTS key field |
判断 key 表中是否存在指定字段 |
HGET key field |
获取存储指定字段的值 |
HGETALL key |
获取表中所有字段和值 |
HINCRBY key field increment |
为 key 表中的指定字段的整数值加上增量 increment |
HINCRBYFLOAT key field increment |
为哈希表 key 中的指定字段的浮点数值加上增量 increment |
HKEYS key |
获取所有哈希表中的字段 |
HLEN key |
获取哈希表中字段的数量 |
HMGET key field1 [field2] |
获取所有给定字段的值 |
HMSET key field1 value1 [field2 value2 ] |
同时将多个 field-value (域-值)对设置到哈希表 key 中 |
HSETNX key field value |
只有在字段 field 不存在时,设置哈希表字段的值 |
HVALS key |
获取哈希表中所有值 |
HSCAN key cursor [MATCH pattern] [COUNT count] |
迭代哈希表中的键值对 |
Redis 列表(List)
命令 | 描述 | |
---|---|---|
BLPOP key1 [key2 ] timeout |
移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止 | |
BRPOP key1 [key2 ] timeout |
移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止 | |
BRPOPLPUSH source destination timeout |
从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止 |
|
LINDEX key index |
通过索引获取列表中的元素 | |
`LINSERT key BEFORE | AFTER pivot value` | 在列表的元素前或者后插入元素 |
LLEN key |
获取列表长度 | |
LPOP key |
移出并获取列表的第一个元素 | |
LPUSH key value1 [value2] |
将一个或多个值插入到列表头部 | |
LPUSHX key value |
将一个值插入到已存在的列表头部 | |
LRANGE key start stop |
获取列表指定范围内的元素 | |
LREM key count value |
移除列表元素 | |
LSET key index value |
通过索引设置列表元素的值 | |
LTRIM key start stop |
对一个列表进行修剪(trim),让列表只保留指定区间内的元素 | |
RPOP key |
移除列表的最后一个元素,返回值为移除的元素 | |
RPOPLPUSH source destination |
移除列表的最后一个元素,并将该元素添加到另一个列表并返回 | |
RPUSH key value1 [value2] |
在列表中添加一个或多个值 | |
RPUSHX key value |
为已存在的列表添加值 |
Redis 集合(Set)
命令 | 描述 |
---|---|
SADD key member1 [member2] |
向集合添加一个或多个成员 |
SCARD key |
获取集合的成员数 |
SDIFF key1 [key2] |
返回第一个集合与其他集合之间的差异 |
SDIFFSTORE destination key1 [key2] |
返回给定所有集合的差集并存储在 destination 中 |
SINTER key1 [key2] |
返回给定所有集合的交集 |
SINTERSTORE destination key1 [key2] |
返回给定所有集合的交集并存储在 destination 中 |
SISMEMBER key member |
判断 member 元素是否是集合 key 的成员 |
SMEMBERS key |
返回集合中的所有成员 |
SMOVE source destination member |
将 member 元素从 source 集合移动到 destination 集合 |
SPOP key |
移除并返回集合中的一个随机元素 |
SRANDMEMBER key [count] |
返回集合中一个或多个随机数 |
SREM key member1 [member2] |
移除集合中一个或多个成员 |
SUNION key1 [key2] |
返回所有给定集合的并集 |
SUNIONSTORE destination key1 [key2] |
所有给定集合的并集存储在 destination 集合中 |
SSCAN key cursor [MATCH pattern] [COUNT count] |
迭代集合中的元素 |
Redis 有序集合(sorted set)
命令 | 描述 |
---|---|
ZADD key score1 member1 [score2 member2] |
向有序集合添加一个或多个成员,或者更新已存在成员的分数 |
ZCARD key |
获取有序集合的成员数 |
ZCOUNT key min max |
计算在有序集合中指定区间分数的成员数 |
ZINCRBY key increment member |
有序集合中对指定成员的分数加上增量 increment |
ZINTERSTORE destination numkeys key [key ...] |
计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 destination 中 |
ZLEXCOUNT key min max |
在有序集合中计算指定字典区间内成员数量 |
ZRANGE key start stop [WITHSCORES] |
通过索引区间返回有序集合指定区间内的成员 |
ZRANGEBYLEX key min max [LIMIT offset count] |
通过字典区间返回有序集合的成员 |
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT] |
通过分数返回有序集合指定区间内的成员 |
ZRANK key member |
返回有序集合中指定成员的索引 |
ZREM key member [member ...] |
移除有序集合中的一个或多个成员 |
ZREMRANGEBYLEX key min max |
移除有序集合中给定的字典区间的所有成员 |
ZREMRANGEBYRANK key start stop |
移除有序集合中给定的排名区间的所有成员 |
ZREMRANGEBYSCORE key min max |
移除有序集合中给定的分数区间的所有成员 |
ZREVRANGE key start stop [WITHSCORES] |
返回有序集中指定区间内的成员,通过索引,分数从高到低 |
ZREVRANGEBYSCORE key max min [WITHSCORES] |
返回有序集中指定分数区间内的成员,分数从高到低排序 |
ZREVRANK key member |
返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序 |
ZSCORE key member |
返回有序集中,成员的分数值 |
ZUNIONSTORE destination numkeys key [key ...] |
计算给定的一个或多个有序集的并集,并存储在新的 key 中 |
ZSCAN key cursor [MATCH pattern] [COUNT count] |
迭代有序集合中的元素(包括元素成员和元素分值) |
Redis HyperLogLog
用来做基数统计的算法,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 264 个不同元素的基数。
优点:在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的
基数:数据集 {1, 3, 5, 7, 5, 7, 8} 的基数集为 {1, 3, 5 ,7, 8}, 基数(不重复元素)为 5。
基数估计:在误差可接受的范围内,快速计算基数。
命令 | 描述 |
---|---|
PFADD key element [element ...] |
添加指定元素到 HyperLogLog 中 |
PFCOUNT key [key ...] |
返回给定 HyperLogLog 的基数估算值 |
PFMERGE destkey sourcekey [sourcekey ...] |
将多个 HyperLogLog 合并为一个 HyperLogLog |
Redis 发布订阅
Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。
命令 | 描述 |
---|---|
PSUBSCRIBE pattern [pattern ...] |
订阅一个或多个符合给定模式的频道 |
PUBSUB subcommand [argument [argument ...]] |
查看订阅与发布系统状态 |
PUBLISH channel message |
将信息发送到指定的频道 |
PUNSUBSCRIBE [pattern [pattern ...]] |
退订所有给定模式的频道 |
SUBSCRIBE channel [channel ...] |
订阅给定的一个或多个频道的信息 |
UNSUBSCRIBE [channel [channel ...]] |
指退订给定的频道 |
Redis 事务
Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:
- 批量操作在发送 EXEC 命令前被放入队列缓存
- 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行
- 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中
一个事务从开始到执行会经历以下三个阶段:
- 开始事务
- 命令入队
- 执行事务
单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。
事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。
命令 | 描述 |
---|---|
DISCARD |
取消事务,放弃执行事务块内的所有命令 |
EXEC |
执行所有事务块内的命令 |
MULTI |
标记一个事务块的开始 |
UNWATCH |
取消 WATCH 命令对所有 key 的监视 |
WATCH key [key ...] |
监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断 |
Redis 脚本
Redis 脚本使用 Lua 解释器来执行脚本。执行脚本的常用命令为 EVAL
。
命令 | 描述 |
---|---|
EVAL script numkeys key [key ...] arg [arg ...] |
执行 Lua 脚本 |
EVALSHA sha1 numkeys key [key ...] arg [arg ...] |
执行 Lua 脚本 |
SCRIPT EXISTS script [script ...] |
查看指定的脚本是否已经被保存在缓存当中 |
SCRIPT FLUSH |
从脚本缓存中移除所有脚本 |
SCRIPT KILL |
杀死当前正在运行的 Lua 脚本 |
SCRIPT LOAD script |
将脚本 script 添加到脚本缓存中,但并不立即执行这个脚本 |
Redis 连接
命令 | 描述 |
---|---|
AUTH password |
验证密码是否正确 |
ECHO message |
打印字符串 |
PING |
查看服务是否运行 |
QUIT |
关闭当前连接 |
SELECT index |
切换到指定的数据库 |
Redis 服务器
命令 | 描述 |
---|---|
BGREWRITEAOF |
异步执行一个 AOF(AppendOnly File) 文件重写操作 |
BGSAVE |
在后台异步保存当前数据库的数据到磁盘 |
CLIENT KILL [ip:port] [ID client-id] |
关闭客户端连接 |
CLIENT LIST |
获取连接到服务器的客户端连接列表 |
CLIENT GETNAME |
获取连接的名称 |
CLIENT PAUSE timeout |
在指定时间内终止运行来自客户端的命令 |
CLIENT SETNAME connection-name |
设置当前连接的名称 |
CLUSTER SLOTS |
获取集群节点的映射数组 |
COMMAND |
获取 Redis 命令详情数组 |
COMMAND COUNT |
获取 Redis 命令总数 |
COMMAND GETKEYS |
获取给定命令的所有键 |
TIME |
返回当前服务器时间 |
COMMAND INFO command-name [command-name ...] |
获取指定 Redis 命令描述的数组 |
CONFIG GET parameter |
获取指定配置参数的值 |
CONFIG REWRITE |
对启动 Redis 服务器时所指定的 redis.conf 配置文件进行改写 |
CONFIG SET parameter value |
修改 redis 配置参数,无需重启 |
CONFIG RESETSTAT |
重置 INFO 命令中的某些统计数据 |
DBSIZE |
返回当前数据库的 key 的数量 |
DEBUG OBJECT key |
获取 key 的调试信息 |
DEBUG SEGFAULT |
让 Redis 服务崩溃 |
FLUSHALL |
删除所有数据库的所有key |
FLUSHDB |
删除当前数据库的所有key |
INFO [section] |
获取 Redis 服务器的各种信息和统计数值 |
LASTSAVE |
返回最近一次 Redis 成功将数据保存到磁盘上的时间,以 UNIX 时间戳格式表示 |
MONITOR |
实时打印出 Redis 服务器接收到的命令,调试用 |
ROLE |
返回主从实例所属的角色 |
SAVE |
同步保存数据到硬盘 |
SHUTDOWN [NOSAVE] [SAVE] |
异步保存数据到硬盘,并关闭服务器 |
SLAVEOF host port |
将当前服务器转变为指定服务器的从属服务器(slave server) |
SLOWLOG subcommand [argument] |
管理 redis 的慢日志 |
SYNC |
用于复制功能(replication)的内部命令 |
Redis Geo
Redis Stream
Redis Stream 是 Redis 5.0 版本新增加的数据结构。
Redis Stream 主要用于消息队列(MQ,Message Queue),Redis 本身是有一个 Redis 发布订阅 (pub/sub) 来实现消息队列的功能,但它有个缺点就是消息无法持久化,如果出现网络断开、Redis 宕机等,消息就会被丢弃。
简单来说发布订阅 (pub/sub) 可以分发消息,但无法记录历史消息。
而 Redis Stream 提供了消息的持久化和主备复制功能,可以让任何客户端访问任何时刻的数据,并且能记住每一个客户端的访问位置,还能保证消息不丢失。
Redis Stream 的结构如下所示,它有一个消息链表,将所有加入的消息都串起来,每个消息都有一个唯一的 ID 和对应的内容:
每个 Stream 都有唯一的名称,它就是 Redis 的 key,在我们首次使用 xadd 指令追加消息时自动创建。
- Consumer Group :消费组,使用
XGROUP CREATE
命令创建,一个消费组有多个消费者(Consumer) - last_delivered_id :游标,每个消费组会有个游标 last_delivered_id,任意一个消费者读取了消息都会使游标 last_delivered_id 往前移动
- pending_ids :消费者(Consumer)的状态变量,作用是维护消费者的未确认的 id。 pending_ids 记录了当前已经被客户端读取的消息,但是还没有 ack (Acknowledge character:确认字符)
消息队列相关命令
XADD
添加消息到末尾
# key 队列名称
# id 消息 id,使用 * 表示由 redis 生成,可以自定义,需要自己维护递增
# field value 记录
# XADD key ID field value [field value ...]
XTRIM
对流进行修剪,限制长度
# key 队列名称
# MAXLEN 长度
# count 数量
# XTRIM key MAXLEN [~] count
XDEL
删除消息
# XDEL key ID [ID ...]
# key 队列名称
# ID 消息 ID
XLEN
获取流包含的元素数量,即消息长度
# XLEN key
# key 队列名称
XRANGE
获取消息列表,会自动过滤已经删除的消息
# XRANGE key start end [COUNT count]
# key 队列名称
# start 开始值 - 表示最小值
# end 结束值 + 表示最大值
# count 数量
XREVRANGE
反向获取消息列表,ID 从大到小
# XREVRANGE key end start [COUNT count]
XREAD
以阻塞或非阻塞方式获取消息列表
# XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] id [id ...]
# milliseconds 可选 阻塞毫秒数,没有设置就是非阻塞模式
消费者组相关命令
XGROUP CREATE
创建消费者组XREADGROUP GROUP
读取消费者组中的消息XACK
将消息标记为“已处理”XGROUP SETID
为消费者组设置新的最后递送消息 IDXGROUP DELCONSUMER
删除消费者XGROUP DESTROY
删除消费者组XPENDING
显示待处理消息的相关信息XCLAIM
转移消息的归属权XINFO
查看流和消费者组相关信息XINFO GROUPS
打印消费者组的信息XINFO STREAM
打印流信息
Redis 高级用法
Redis 数据备份与恢复
- 创建当前数据的备份
# 在 redis 安装目录中创建 dump.rdb 文件
SAVE
# 后台执行备份
BGSAVE
- 恢复数据
只需将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可
# 获取 redis 目录
CONFIG GET dir
Redis 安全
# 查看是否设置了密码
CONFIG GET requirepass
# output:
# "requirepass"
# "" # 默认参数为空,即无需密码验证就可以连接到 redis 服务
# 修改
CONFIG SET requirepass "cellpwd"
# output:
# OK
# 密码验证
AUTH "cellpwd"
Redis 性能测试
通过同时执行多个命令实现 redis-benchmark [option] [option value]
# 同时执行 10000 个请求
redis-benchmark -n 10000 -q
可选参数
选项 | 说明 | 默认值 |
---|---|---|
-h | 指定服务器主机名 | 127.0.0.1 |
-p | 指定服务器端口 | 6379 |
-s | 指定服务器 socket | |
-c | 指定并发连接数 | 50 |
-n | 指定请求数 | 10000 |
-d | 以字节的形式指定 SET/GET 值的数据大小 | 2 |
-k | 1=keep alive 0=reconnect | 1 |
-r | SET/GET/INCR 使用随机 key, SADD 使用随机值 | |
-P | 通过管道传输 <numreq> 请求 |
|
-q | 强制退出 redis。仅显示 query/sec 值 | |
--csv | 以 CSV 格式输出 | |
-l | 生成循环,永久执行测试 | |
-t | 仅运行以逗号分隔的测试命令列表 | |
-I | Idle 模式。仅打开 N 个 idle 连接并等待 |
Redis 客户端连接
Redis 通过监听一个 TCP 端口或者 Unix socket 的方式来接收来自客户端的连接,当一个连接建立后,Redis 内部会进行以下一些操作:
- 首先,客户端 socket 会被设置为非阻塞模式,因为 Redis 在网络事件处理上采用的是非阻塞多路复用模型
- 然后为这个 socket 设置 TCP_NODELAY 属性,禁用 Nagle 算法
- 然后创建一个可读的文件事件用于监听这个客户端 socket 的数据发送
客户端命令
命令 | 描述 |
---|---|
CLIENT LIST | 返回连接到 redis 服务的客户端列表 |
CLIENT SETNAME | 设置当前连接的名称 |
CLIENT GETNAME | 获取通过 CLIENT SETNAME 命令设置的服务名称 |
CLIENT PAUSE | 挂起客户端连接,指定挂起的时间以毫秒计 |
CLIENT KILL | 关闭客户端连接 |
Redis 管道技术
Redis 是一种基于客户端-服务端模型以及请求/响应协议的 TCP 服务。一个请求会遵循以下步骤:
- 客户端向服务端发送一个查询请求,并监听Socket返回,通常是以阻塞模式,等待服务端响应
- 服务端处理命令,并将结果返回给客户端
Redis 管道技术可以在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应。
管道技术最显著的优势是提高了 redis 服务的性能。
$(echo -en "PING\r\n SET mykey redis\r\nGET mykey\r\nINCR visitor\r\nINCR visitor\r\nINCR visitor\r\n"; sleep 10) | nc localhost 6379
# 使用 PING 命令查看redis服务是否可用
# 设置 mykey 的值为 redis
# 获取 mykey 的值并使得 visitor 自增 3 次
# 上面命令一次性向 redis 服务提交,并最终一次性读取所有服务端的响应
Redis 分区
分区是分割数据到多个Redis实例的处理过程,因此每个实例只保存key的一个子集。
优势:
- 通过利用多台计算机内存的和值,允许构造更大的数据库
- 通过多核和多台计算机,允许扩展计算能力
- 通过多台计算机和网络适配器,允许扩展网络带宽
不足:
- 涉及多个 key 的操作通常是不被支持的(当两个 set 映射到不同的 redis 实例上时,就不能对这两个 set 执行交集操作)
- 涉及多个 key 的 redis 事务不能使用
- 当使用分区时,数据处理较为复杂,比如需要处理多个 rdb/aof 文件,并且从多个实例和主机备份持久化文件
增加或删除容量也比较复杂
- redis 集群大多数支持在运行时增加、删除节点的透明数据平衡的能力
- 但是类似于客户端分区、代理等其他系统则不支持这项特性
- 可以使用 在线扩容(Pre-Sharding)解决
分区类型:
- 范围分区:映射一定范围的对象到特定的 Redis 实例,需要维护分区范围映射表
- 哈希分区:用一个 hash 函数将 key 转换为一个数字,对这个整数取模,如将其转化为0-3之间的数字,就可以将这个整数映射到 4 个 Redis 实例中的一个了