1. 安装
version: '3'
services:
redis:
image: redis:alpine
container_name: redis
volumes:
- ~/volumes/redis/data/:/data
command: redis-server --appendonly yes
network_mode: host
2. 数据结构
2.1. string
2.1.1. 命令
-
set key value [EX seconds] [PX milliseconds] [NX|XX]
-
set a 1
-
set a 1 PX 10000
-
set a 1 NX
NX: 只有key不存在的时候才设置值.
-
set a 1 XX
XX: 只有key存在的时候才设置值.
-
-
get key
-
get a
-
-
mset key1 value1 [key2 value2 …]
批量set.
-
mset a 1 b 2 c 3
-
-
mget key [key1 key2 key3 …]
-
mget a b c
批量get.
-
-
msetnx key1 value1 [key2 value2 …]
批量set, 但是只有所有key不存在时才能设置.
-
msetnx a 1 b 2
-
-
strlen key
返回key的长度.
-
strlen a
-
-
append key chars
在key后面追加字符串.
-
append a world
-
-
getset key value
设置并返回值.
-
getset a 1
-
-
getrange key start end
截取key从start到end的字符串, 闭区间.
-
getrange demo 0 -1
-
-
setrange key start substitute
key从start位置开始替换值.
-
setrange demo 5 Redis
Hello World → HelloRedisd
-
-
incr key
将key的值加1
-
incr a
-
-
incrbyfloat key increment
加上浮点数. 最多保留小数后17位.
-
incrbyfloat demo 1.23
-
2.1.2. 内部编码
可以使用 object encoding KEY 查看内部编码方式.
|
-
int
: 8个字节的长整型. -
embstr
: 小于等于39个字节的字符串. -
raw
: 大于39个字节的字符串.
当字符串长度小于1MB时, 扩容都是加倍现有的空间. 如果长度大于1MB, 扩容时只会增加1MB的空间. 字符串长度最大为512MB.
2.1.3. 使用场景
-
缓存
setex, get
-
计数
incr
-
session共享
setex, get
-
限速
setnx, decr
2.2. hash
2.2.1. 命令
-
hset key field value
为hash的指定field设置值.
-
hset k a 1
-
-
hsetnx key field value
当field不存在时为field设置值.
-
hsetnx k a 1
-
-
hget key field
获取hash的指定field的值.
-
hget k a
-
-
hincrby key field increment
给指定field增加值
-
hincrby k a 111
-
-
hstrlen key field
获取field值的长度
-
hstrlen k a
-
-
hlen key
获取hash字段数量
-
hlen k
-
-
hdel key field [field …]
删除hash内字段.
-
hdel k a b c
-
-
hmset key value [key1 value1 …]
批量设置hash field的值
-
hmset k a 1 b 2 c 3
-
-
hmget key [key1 key2 …]
批量获取hash field的值
-
hmget k a b c
-
-
hexists key field
field是否存在
-
hexists k a
-
-
hkeys key
获取所有的field
-
hkeys k
-
-
hvals key
获取所有的value
-
hvals k
-
-
hgetall key
获取hash内所有的field-value
-
hgetall k
-
2.2.2. 内部编码
-
ziplist
: 当哈希元素个数小于hash-max-ziplist-entries(512)
同时所有值的大小都小于hash-max-ziplist-value(64B)
时, Redis内部使用ziplist
作为hash的实现, 结构紧凑, 节省内存. -
hashtable
: 元素数量过多会导致ziplist
读写效率下降, 此时使用hashtable
作为hash的内部实现.
2.2.3. 使用场景
-
缓存
hmset, hgetall
-
存储稀疏图
hset, hgetall
2.3. list
2.3.1. 命令
-
lpush key value [value1 value2 …]
从左向右push.
-
lpush k 1 2 3
-
-
rpush key value [value1 value2 …]
从右向左push.
-
rpush k 3 2 1
-
-
lpushx key value
当key存在时才后插入值, 一次只能插入一个值
-
lpushx dummy val
-
-
linsert key before|after pivot value
插入值到指定元素前/后.
-
linsert k before 1 0
-
-
lpop key
从左边取出第一个值.
-
rpop key
从右边取出第一个值.
-
rpoplpush source target
从source右端弹出元素, 并将其推入target左端. 如果source为空则执行失败.
-
rpoplpush l1 l2
-
-
lrem key count value
删除值为value的元素.
-
lrem k 0 1
删除所有值为1的元素.
-
lrem k 1 1
从左向右删除1个值为1的元素.
-
lrem k -1 1
从右向左删除1个值为1的元素.
-
-
ltrim key start end
保留索引从start到end的元素, 索引从0到N-1.
-
ltrim k 1 3
保留索引从1到3的元素.
-
-
blpop|brpop key [key1 key2 …] timeout
从多个列表中取出左/右边第一个元素
-
blop k k1 k2 0
-
-
lset key index value
将索引为index的元素值修改为value.
-
lset k 1 111
-
-
lrange key start end
取出列表中从left到end的元素(左右都是闭区间). list从左到右索引下标为0到N-1, 从右向左索引下标为-1到-N.
-
lrange k 0 -1
取出列表所有元素.
-
-
lindex key index
查看index处的值.
-
lindex k 3
-
-
llen key
获取列表长度.
2.3.2. 内部编码
-
ziplist
: 当列表元素个数小于hash-max-ziplist-entries(512)
同时每个元素大小都小于hash-max-ziplist-value(64B)
时, Redis内部使用ziplist
作为list的实现, 结构紧凑, 节省内存. -
linkedlist
: 元素过多或过大时使用linkedlist
作为list的实现. -
quicklist
2.3.3. 使用场景
-
消息队列
lpush, brpop
-
实体列表
lpush, lrange
-
有限集合
lpush, ltrim
-
优先级调度
lpush l1/l2/l3…, brpop l1 l2 l3 0
2.4. set
2.4.1. 命令
-
sadd key value [value1 value2 …]
-
srem key value [value1 value2 …]
删除set中元素.
-
scard key
获取set元素个数.
-
smove source target value
将value从source移动到target.
-
sismember key value
set中是否存在该元素.
-
sismember k 1
-
-
srandmember key [count]
随机获取set中元素.
-
srandmember k 10
-
-
spop key [count]
随机弹出set中元素.
-
sinter key [key1 key2 …]
取多个set的交集.
-
sinter a b c
-
-
sunion key [key1 key2 …]
取多个set的并集.
-
sunion a b c
-
-
sdiff key [key1 key2 …]
取多个set的差集(key-key1).
-
sdiff a b
-
-
sinterstore|sunionstore|sdiffstore key [key1 key2 …]
取key1,key2…的交/并/差集, 存到key中.
-
sdiff dest a b
-
2.4.2. 内部编码
-
intset
: 集合中的元素都是整数, 且元素个数小于set-max-intset-entries(512)
时使用intset作为集合的内部实现. -
hashtable
2.4.3. 使用场景
-
打tag
sinter
-
抽奖
spop, srandmember
-
社交关系
sadd, spop, srem, smembers
-
共同关注
sinter
2.5. zset
2.5.1. 命令
-
zadd key [NX|XX|INCR|CH] score member [score1 member1 …]
-
zadd k 1 a 2 b
-
zadd k NX 1 a 2 b
NX表示member不存在才添加.
-
zadd k XX 11 a 2 c
XX表示member存在才更新.
-
zadd k INCR 123 a
INCR表示加分数.
-
zadd k CH 123 a 1000 b
CH表示修改的成员数量.
-
-
zcard key
:获取member数量.
-
zrem key member
:删除某个member.
-
zscore key member
:获取member的分数.
-
zrank key member
:分数从低到高获取member名次.
-
zrevrank key member
:分数从高到低获取member名次.
-
zincrby key increment member
:给某个member加score.
-
zincrby k 10 a
-
-
zrange|zrevrange key start end [withscores]
从低到高/从高到低获取排行start到end的member[和它的分数].
-
zrange k 0 2 withscores
-
-
zrangebyscore key min max [withscores] [limit offset count]
根据分数范围列出member.
-
zrangebyscore k 10 11 withscores limit 0 1
-
zrangebyscore k (10 11
-
zrangebyscore k -inf 11
-
-
zcount key min max
获取分数从min到max的member数量.
-
zcount k 10 11
-
zcount k 10 (11
-
zcount k -inf +inf
-
-
zremrangebyrank key start end
删除排行从start到end的member.
-
zremrangebyscore key min max
删除分数从min到max的member.
-
zinterstore|zunionstore destination numKeys key [key1 …] [weights weight] [aggregate SUM|MIN|MAX]
将numKeys个zset成员乘以按照各自的权重进行SUM/MIN/MAX操作, 存放到destination中.
-
zinterstore dest 2 k1 k2 weights 1 0.5 aggregate sum
-
-
zrangebylex key min max
按照字典顺序过滤成员.
-
zlexcount key min max
按照字典顺序过滤成员, 再获取数量.
-
zremrangebylex key min max
删除字典顺序内成员.
-
zpopmax
移除分最高的成员.
-
zpopmin
移除分最低的成员.
2.5.2. 内部编码
-
ziplist
: 有序集合的元素个数小于zset-max-ziplist-entries(128)
, 同时每个成员的大小小于zset-max-ziplist-value(64B)
时用ziplist
实现zset. -
skiplist
2.5.3. 使用场景
-
排行榜
2.6. HyperLogLog
2.6.1. 命令
-
pfadd key element [element …]
添加元素.
-
pfcount key [key2 key3 …]
获取集合的近似基数.
-
pfmerge destKey sourceKey1 [sourceKey2 …]
将其他HyperLogLog合并到destKey.
2.6.2. 使用场景
-
统计uv
2.7. bitmap
2.7.1. 命令
-
setbit key index value
设置指定位置上的值
-
getbit key index
获取指定位置上的值.
-
bitcount key [start, end]
统计从start到end的1. (字节为单位偏移量, 1字节等于8位.)
-
bitpos key {0|1} [start, end]
获取第一个指定值的位置.
-
在一个全为0的位图里找1, 返回-1
-
在一个全为1的位图里找0, 返回下一个位置的索引
-
-
bitop [AND|OR|XOR|NOT] result_key bitmap1 [bitmap2 …]
对多个bitmap进行算术操作.
-
处理不同长度的bitmap时, 空的位置会视作0.
-
-
bitfield key [SET|GET|INCRBY|OVERFLOW] type offset value
``
3. key管理
-
rename/renamenx key newKey
重命名/newKey不存在时才重命名成功.
-
randomkey
随机返回一个key.
-
dbsize
获取key的数量.
-
expire key seconds
让key在seconds秒后过期.
-
expireat key epochSecond
让key在epochSecond时过期.
-
pexpire key millseconds
让key在millseconds毫秒后过期.
-
persist key
取消key的过期时间.
-
ttl key
获取key的过期时间.
set 命令会使key的失效时间消失.
|
-
keys pattern
根据pattern正则列出key.
-
scan cursor [match pattern] [count number]
使用游标遍历键.
-
scan 0
-
scan 0 match k* count 1
-
-
move key db_idx
将key移动到db_idx数据库里.
-
dump + restore
dump指定key再restore
-
select 0
-
set hello world
-
dump hello
-
select 1
-
restore hello 0 "\x00\x05hello\x09\x00\xB3\x80\x8E\xBA1\xB2C\xBB"
-
get hello
-
-
migrate host ip key|"" destination_db_idx timeout [auth password] [COPY] [REPLACE] [KEYS k1 k2 …]
批量迁移key到host:ip:destination_db_idx里, 如果key为"",则按KEYS后的key列表迁移.
-
migrate 192.168.0.227 6379 "" 1 1000 COPY REPLACE KEYS k1 k2 k3
-
migrate 命令不能在同一Redis实例上执行.
|
4. 慢查询
-
slowlog-log-slower-than(微秒)
: 慢查询执行阈值, 默认10000微秒, 负数时不记录慢查询. 建议设置为1000. -
slowlog-max-len
: 慢查询日志最多存储多少条. 建议设置为1000以上. -
slowlog get [n]
: 获取前n条慢查询. -
slowlog len
: 获取慢查询数量. -
slowlog reset
: 重置慢查询.
5. Redis Shell
5.1. redis-cli
-
-r n
: 将命令重复执行n次. -
-i n
: 每隔几秒执行一次. -
-a password
: 密码认证. -
--scan --pattern
: scan key名. -
--rdb filename
: dump数据到rdb文件中. -
--bigkeys
: 找到内存占比比较大的key. -
--latency
: 测试延迟. -
--stat
: 获取Redis统计信息.
5.2. redis-benchmark
-
-c
: 客户端的并发数量, 默认50. -
-n
: 客户端的请求总数, 默认100K. -
-q
: 每秒请求数. -
-r
: 插入随机键, 10000表示对后四位处理. -
-t
: 对指定命令进行基准测试. -
--csv
: 结果按csv格式输出.
6. 事务
6.1. 原子性
-
multi
-
commands …
-
discard/exec
|
6.2. 隔离性
-
watch
-
multi
-
commands …
-
discard/exec
watch某一个key期间, 如果 exec
后返回null, 则表示这期间key其他client修改过, 直接回滚.
6.3. 原子性
-
script load <lua content>
: load lua脚本到redis server中, 返回一个SHA1值, 以后可以直接用SHA1值调用lua脚本. -
script flush
: 删除所有被加载过的lua脚本. -
script kill
: 取消正在执行读操作的lua脚本. -
script exists <SHA1>
: 返回相关lua脚本的SHA1是否被加载过.
-
eval <script> numberKeys key args
-
evalsha <SHA1> numberKeys key args
7. bitmap
-
setbit <bitmap_key> <offset> 1|0
: 设置offset为1/0. -
getbit <bitmap_key> <offset>
: 获取offset处是1还是0. -
bitcount [<bitmap_key> start end]
: 获取start到end的1的个数. -
bitop and|or|not|nor <destination_key> key [key1 key2 …]
: 对多个bitmap key执行逻辑操作. -
bitpos <bitmap_key> 1|0 [start end]
: 获取第一个值为1/0的偏移量.
8. HyperLogLog
-
pfadd key element [element …]
: 添加元素. -
pfcount key
: 计数. -
pfmerge <destination_key> key [key1 key2 …]
: 求多个key的并集, 插入到destination_key中.
9. Publish/Subscribe
-
publish <channel> <message>
: 向channel的每个订阅者发送message. -
subscribe <channel>
: 订阅channel. -
pubsub channels
: 查看当前活跃的channel. -
psubscribe/punsubscribe <pattern>
: 批量订阅channel. -
pubsub numsub <channel>
: 查看channel的订阅数. -
pubsub numpat
: 查看按模式订阅数.
10. Redis Serialization Protocol
10.1. Request
*<参数数量> CRLF
$<参数1的字节数> CRLF
<参数1> CRLF
$<参数2的字节数> CRLF
<参数2> CRLF
...
10.2. Response
-
状态回复:
+
-
错误回复:
-
-
整数回复:
:
-
字符串回复:
$
-
多条字符串回复:
*
11. 持久化
11.1. RDB
RDB持久化是把当前进程的数据生成快照保存到硬盘里.
11.1.1. 手动触发
-
save
: 阻塞redis server直到RDB过程完成为止. -
bgsave
: fork出子进程, 让子进程持久化.
11.1.2. 自动触发
-
save <m> <n>
: 表示m秒内数据存在n次修改时, 自动触发bgsave. -
如果从节点执行全量复制操作, 主节点自动执行bgsave生成RDB文件发送给从节点.
-
debug reload
-
shutdown
: 如果没有开启AOF持久化功能则自动执行bgsave
.
11.1.3. 问题
-
bgsave 属于全量复制, 每次执行都要创建子进程, 频繁操作执行成本太高.
-
RDB使用特定二进制格式保存, 可能会出现不兼容的问题.
11.2. AOF
所有的写入命令追加到aof_buf中, aof_buf会根据相应的策略向磁盘做同步操作.
-
bgrewriteaof
-
根据
auto-aof-rewrite-min-size
和auto-aof-rewrite-percentage
参数确定自动触发时机.aof_current_size > auto-aof-rewrite-min-size && (aof_current_size - aof_base_size) / aof_base_size >= auto-aof-rewrite-percentage
-
auto-aof-rewrite-min-size
: AOF文件重写时文件最小体积. -
auto-aof-rewrite-percentage
: 当前aof文件体积和上一次重写后aof文件体积比值.
-
11.3. 持久化文件加载流程
-
appendonly开启时优先加载aof文件, aof不存在时加载rdb文件
-
appendonly未开启时加载rdb文件
-
加载aof/rdb文件成功后, redis启动成功.
-
aof/rdb文件存在错误时, redis启动失败并打印错误信息. (可以使用redis-check-aof --fix命令修复)
12. 主从复制
12.1. 从节点开启方式
-
redis-server replicaof <host> <port>
. -
配置文件添加
replicaof <host> <port>
. -
直接运行命令
replicaof <host> <port>
.
12.2. 从节点断开
replicaof no one
.
12.3. 数据同步方式
-
全量复制: 用于初次复制场景. 把主节点全部数据一次性地发送给从节点.
-
部分复制: 补发丢失数据给从节点.
13. Sentinel
Redis Sentinel 负责监控redis主从节点, 主节点故障时自动切换从节点为主节点.
13.1. 安装
version: '3.7'
services:
redis-master:
image: redis:alpine
container_name: redis-master
volumes:
- ./master.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis
ports:
- 6379:6379
redis-replica1:
image: redis:alpine
container_name: redis-replica1
volumes:
- ./replica1.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis
ports:
- 6380:6379
depends_on:
- redis-master
redis-replica2:
image: redis:alpine
container_name: redis-replica2
volumes:
- ./replica2.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis
ports:
- 6381:6379
depends_on:
- redis-master
redis-sentinel1:
image: redis:alpine
container_name: redis-sentinel1
volumes:
- ./sentinel1.conf:/usr/local/etc/redis/redis.conf
command: redis-sentinel /usr/local/etc/redis/redis.conf
networks:
- redis
ports:
- 16379:6379
depends_on:
- redis-master
redis-sentinel2:
image: redis:alpine
container_name: redis-sentinel2
volumes:
- ./sentinel2.conf:/usr/local/etc/redis/redis.conf
command: redis-sentinel /usr/local/etc/redis/redis.conf
networks:
- redis
ports:
- 16380:6379
depends_on:
- redis-master
redis-sentinel3:
image: redis:alpine
container_name: redis-sentinel3
volumes:
- ./sentinel3.conf:/usr/local/etc/redis/redis.conf
command: redis-sentinel /usr/local/etc/redis/redis.conf
networks:
- redis
ports:
- 16381:6379
depends_on:
- redis-master
networks:
redis:
appendonly yes
logfile "master.log"
dbfilename "dump-master.rdb"
appendonly yes
logfile "replica1.log"
dbfilename "dump-replica1.rdb"
replicaof redis-master 6379
appendonly yes
logfile "replica2.log"
dbfilename "dump-replica2.rdb"
replicaof redis-master 6379
logfile "sentinel.log"
sentinel monitor master redis-master 6379 2
sentinel down-after-milliseconds master 15000
sentinel parallel-syncs master 1