Head First Redis
This document is a very simple introduction to Redis, which is mainly used for personal learning and reference.
命令与配置
常用命令查询
主从设置
slaveof 10.4.44.71 3904
slaveof no one
# 设置从可写 /不可写
config set slave-read-only yes
config set slave-read-only no
内存回收策略
config get maxmemory-policy
当
maxmemory
限制到达的时候,redis
将采取的准确行为是由maxmemory-policy
配置指令配置的。以下策略可用:
noeviction
:当到达内存限制时返回错误。当客户端尝试执行命令时会导致更多内存占用(大多数写命令,除了DEL
和一些例外)。如果对数据非常敏感,不允许丢失数据,那么建议使用noeviction
策略。allkeys-lru
:回收最近最少使用(LRU
)的键,为新数据腾出空间。如果分为热数据与冷数据, 推荐使用allkeys-lru
策略volatile-lru
:回收最近最少使用(LRU
)的键,但是只回收有设置过期的键,为新数据腾出空间。allkeys-random
:回收随机的键,为新数据腾出空间。如果需要循环读写所有的key, 或者各个key的访问频率差不多, 可以使用allkeys-random
策略, 即读写所有元素的概率差不多volatile-random
:回收随机的键,但是只回收有设置过期的键,为新数据腾出空间。volatile-ttl
:回收有设置过期的键,尝试先回收离TTL最短时间的键,为新数据腾出空间。
复制 Replication
调整复制超时时间
config get repl-timeout
config set repl-timeout 1800
调整复制缓冲区大小
slave
后的两个参数分别表示硬限制和软限制: 硬限制到达就无法写入. 软限制标识连续60s
达到这个数值
config set client-output-buffer-limit "slave 2684354560 536870912 0"
设置复制积压缓冲区的大小
config get repl-backlog-size
config set repl-backlog-size xx
(unit: bytes)
持久化
设置重写的大小 80GB
config set auto-aof-rewrite-percentage 200
config set auto-aof-rewrite-min-size 80108864000
通过 aof 回放命令
tail -n +6 /opt/redis_dump/appendonly.aof | pv -L 10m | nc 10.13.56.15 3707 > ~/run.log
关闭 AOF
config set appendonly no
AOF 写满
aof
写满磁盘的问题 磁盘满了aof
写失败,而磁盘上没有别的空间可以释放 通过一下方式清空后再清空aof
文件再bgrewrite
>appendonly.aof
如果直接删除aof
文件,磁盘空间不会释放,因为文件句柄没有全部释放。这时候可以用以下命令来清空已经删除的文件
>/proc/${pid}/fd
集群
查看 cluster nodes 拓扑分布
redis-cli -h 10.3.23.27 -p 3920 cluster nodes
将一个新节点加入到现有集群中
选择原有集群中的任意一个节点10.3.23.35:3920
,加入新的节点10.3.20.213:3920
redis-cli -h 10.3.23.35 -p 3920 CLUSTER MEET 10.3.20.213 3920
设置从节点
设置10.3.20.213 3920
为node-id(fd276dc8e818f53239f988dc2bb3ec85504f9096)
的从节点:
redis-cli -h 10.3.20.213 -p 3920
CLUSTER REPLICATE fd276dc8e818f53239f988dc2bb3ec85504f9096
从集群中重置一个节点
首先从集群拓扑中删除该节点,然后清空重置该节点数据,最后再加入到集群中 eg: 要操作的节点为10.3.20.213:3920
,其node-id
为fd276dc8e818f53239f988dc2bb3ec85504f9096
# 对集群中所有节点发送forget 该节点的命令
redis-cli -h 10.3.1.1 -p 3920
CLUSTER FORGET fd276dc8e818f53239f988dc2bb3ec85504f9096
# 连接该节点,清空数据并重置
redis-cli -h 10.3.20.213 -p 3920
FLUSHALL
CLUSTER RESET
# 连接任意一个节点,将新节点加入:
redis-cli -h 10.3.1.1 -p 3920 CLUSTER MEET 10.3.20.213 3920
查看集群中指定 slot 中的key的数量
redis-cli -h 10.3.23.35 -p 3920 CLUSTER COUNTKEYSINSLOT 11587
设置 slot 在特定节点上
redis-cli -h 10.3.21.50 -p 3920 CLUSTER SETSLOT 11587 NODE f68aa3484f2340a9586632b2696f5a8fe0b30f40
设置集群的超时时间
系统默认为5s
config set cluster-node-timeout 30000
cluster rebalance
redis-cli --cluster rebalance ip:port
rebalance host:port
--cluster-weight <node1=w1...nodeN=wN>
--cluster-use-empty-masters
--cluster-timeout <arg>
--cluster-simulate
--cluster-pipeline <arg>
--cluster-threshold <arg>
--cluster-replace
cluster failover
主从都为存活状态,将slave
切换为master
slave-node-cli> CLUSTER FAILOVER
master
挂掉,将slave
切换为master
slave-node-cli> CLUSTER FAILOVER [FORCE|TAKEOVER]
FORCE
选项: 不与master握手,广播信息,与其集群其它master通信,获取授权投票成为新的masterTAKEOVER
选项:不与master握手,也不需获取其他master投票通过,直接提升为master (应用场景:数据中心切换时将大量的slave设置为master,但此时 大多数master都不可用,或者发生了脑裂)
注:
TAKEOVER
violates the last-failover-wins principle of Redis Cluster ref:https://redis.io/commands/cluster-failover
slot 迁移过程
1.设置目标节点为 importing state
CLUSTER SETSLOT <slot> IMPORTING <source-node-id>.
- 直接请求这个
slot
的key
,返回MOVED
转向 - 先发送
ASKING
命令,再请求这个slot
的key
,处理请求
2.设置源节点为 migrating state
CLUSTER SETSLOT <slot> MIGRATING <destination-node-id>.
- 请求已存在的
key
,和原有处理逻辑一致 - 请求不存在的
key
,给client
返回ask
转向,client
请求importing
的节点 - 请求包含多个
key
,部分存在部分不存在的时,返回TRYAGAIN
,直到所有的key
都被迁移
3.从源节点循环读取出key
, 然后将他们转移到目标节点
CLUSTER GETKEYSINSLOT
MIGRATE host port key "" destination-db timeout REPLACE KEYS key [key ...]]
4.设置slots
状态为正常:
CLUSTER SETSLOT <slot> NODE <destination-node-id>
# in the source and destination
CLUSTER SETSLOT <slot>
NODE <node-id>
,一般用于迁移slot完成之后,对迁移状态的两个实例发送该命令
作用:
- 对
slot
属主执行这条命令,返回错误 - 对
slot
处于migrating
的实例执行这条命令,清除migrating
状态 - 对
slot
处于importing
的实例执行这条命令,清除importing
状态,并检查epoch id
,如果epoch id
不是集群中最大的,生成一个新的最大id
(注意:此时并不和集群通信,手动重置为最大)
注:如果迁移过程中断,修改状态,对待修复的节点执行
redis-cli -h <host> -p <port> cluster setslot <slot> stable
注:just clear migrating / importing state
https://redis.io/commands/cluster-setslot
client 工具
查看当前的连接到服务器的客户端的列表
127.0.0.1:6379> client list
addr=127.0.0.1:52555 fd=5 name= age=855 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client
addr=127.0.0.1:52787 fd=6 name= age=6 idle=5 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=ping
每一行表示一个连接的各项信息:
addr
: 客户端的TCP
地址,包括IP
和端口fd
: 客户端连接socket
对应的文件描述符句柄号name
: 连接的名字,默认为空,可以通过CLIENT SETNAME
设置age
: 客户端存活的秒数idle
: 客户端空闲的秒数flags
: 客户端的类型 (N
表示普通客户端,更多类型见https://redis.io/commands/client-list
)omem
: 输出缓冲区的大小cmd
: 最后执行的命令名称
查看当前正在执行的命令
monitor
Big Keys
大key不仅会降低proxy的吞吐率,并且容易诱发阻塞,平响长尾也会变大,最好压缩后再存放。
查看
slowlog get {N}
memory usage KEY
debug object key
// serializedlength不代表真实的字节大小,它返回对象使用RDB编码序列化后的长度,值会偏小,但是对于排查bigkey有一定辅助作用
redis-cli --stat
redis-cli -h {ip} -p {port} bigkeys
redis-cli -h {ip} -p {port} --latency
不建议
string
类型的大小不超过10KBHASH
,SET
,ZSET
,LIST
元素不宜超过1000.- 不建议使用
hgetall
,lrange
,mget
,mset
一次性获取上千个元素 - 在元素过大、个数过多时,不建议全量查询元素,比如
zrange key 0 -1
命令会导致慢查询 - 不建议
pipeline
批次下key
数量超过500,最好控制在100以内
建议
string
类型建议1k之内,对于大于10k的json
串建议采用压缩方式存储- 建议打散过期时间,防止数据集中过期阻塞
redis
对于元素个数少和value小的数据有压缩算法,可以降低redis
本身的数据结构开销
类型 | 个数最大值 |
---|---|
Hash | 512 |
Set | 512 |
Zset | 128 |
List | 512 |
数据类型与实现
Best Practice
Reference
https://mp.weixin.qq.com/s/Fz1EbsmJP5k2Rh6ir_a1pQ
Disclaimer
- License under
CC BY-NC 4.0
- Copyright issue feedback
me#imzye.me
, replace # with @ - Not all the commands and scripts are tested in production environment, use at your own risk
- No privacy information is collected here