Redis开发与运维
2019-07-08 11:34:14 8 举报
AI智能生成
登录查看完整内容
为你推荐
查看更多
Redis开发与运维
作者其他创作
大纲/内容
*<参数数量>CRLF$<参数1的字节数量>CRLF<参数1>CRLF...$<参数N的字节数量>CRLF<参数N> CRLF
发送命令格式
状态恢复:第一个字节为\"+\"
错误回复:第一个字节为\"-\"
整数回复:第一个字节为\":\"
字符串回复:第一个字节为\"$\"
多条字符串回复:第一个字节为\"*\"
返回结果格式
客户端通信协议RESP
jedis对象池参数
Java客户端Jedis
输入缓冲区最大为1G,且不能配置
输入缓冲区超过1G,客户端将会被关闭
输入缓冲区不受maxmemory控制
redis处理速度跟不上输入缓冲区的输入速度,并且输入缓存冲区中包含了大量的bigkey
redis发生阻塞,造成客户端输入的命令积压
输入缓冲区过大原因
输入缓冲区
输出缓冲区由固定缓冲区和动态缓冲区组成
输出缓冲区
注意点
client list
client setNmae 和 client getName
可以手动杀掉长时间idle的客户端(timeout设置为0)
手动处理异常客户端,如使用了monitor命令导致输出客户端缓存变大的客户端
杀掉制定ip和port的客户端 client kill ip:port
client pause 只对普通客户端和发布订阅客户端有效,对主从复制无效,所以可以 使用该命令来使主从一致
可以以一种可控的方式来使得客户端连接从一个redis节点切换到另一个redis节点
阻塞客户端timeout毫秒数 client pause timeout(毫秒)
客户端API
客户端管理
高并发下连接池设置过小,出现供不应求
没有正确使用连接池,比如没有释放
存在慢查询操作,导致连接归还速度比较慢,造成连接池满
服务端异常造成客户端命令执行过程阻塞
无法从连接池中获取到连接 could not get a resource from the pool
读写超时时间设置过短
命令本身比较慢
网络不正常
redis阻塞
客户端读写超时read time out
客户端连接超时connect timed out
输出缓存区满
长时间闲置连接被服务端主动断开
连接并发操作
客户端缓存区异常unexpected end of stream
执行lua脚本并且超过了lua-time-limit
lua脚本正在执行BUSY redis is busy running a script
redis正在加载持久化
redis使用的内存超过maxmemory配置
客户端连接数过大
客户端常见异常
客户端
复制
理解内存
mem_fragmentation_ratio >1 时,说明多出的部门内存没有用于数据存储,而是被内存碎片所消耗
mem_fragmentation_ratio <1 时,这种情况一般出现在操作系统把redis内存swap到硬盘所致
内存使用统计
自身内存
对象内存
输入缓冲区无法控制,最大为1G
输出缓冲区通过参数client-output-buffer-limit控制
客户端缓冲
可用于表面全量复制
复制积压缓冲区
保存redis在重写期间保存的最近的写入命令
AOF缓冲区
缓冲内存
频繁做更新操作
大量过期键删除
原因
数据对齐
安全重启
解决方案
内存碎片
内存消耗划分
子进程消耗主要指执行AOF/RDB重写时redis创建的子进程消耗
子进程内存消耗
内存消耗
用户缓存场景,超出内存上限时使用LRU等策略来释放空间
防止所用内存超过服务器物理内存
目的
maxmemory限制的是redis实际使用的内存量,也就是used_memory统计项对应的内存。由于内存碎片率的存在,实际消耗的内存可能会比maxmemory设置的更大
设置内存上限
config set maxmemory
动态调整内存上限
惰性删除
定时任务删除
删除过期键对象
noeviction:默认策略,不会删除任何数据,拒绝所有写入并返回客户端错误信息
volatile-lru:根据lru算法删除设置了超时属性的键,直到腾出足够空间。如果没有课删除的键对象,则回退到noeviction策略
allkeys-lru:根据lru算法删除键,不管数据有没有设置超时属性,直到腾出足够空间为止
allkeys-random:随机删除所有键,直到腾出足够空间为止
volatile-random:随机删除过期键,直到腾出足够空间为止
volatile-ttl:根据键对象的 ttl属性,删除最近将要过期数据,如果没有,则回退到noeviction策略
内存溢出控制策略(maxmemory-policy)
内存回收策略
内存管理
基于内存
c语言实现
单线程架构避免多线程竞争
Redis源代码精打细磨
速度快
基于键值对的数据结构服务器
功能丰富
简单稳定
客户端语言多
持久化
主从复制
高可用和分布式
Redis特性
缓存
排行榜系统
计数器应用
社交网络
消息队列系统
Redis使用场景
安装Redis
源代码安装
Linux下安装
#redis-server /opt/redis/redis.conf
启动
redis-cli -h {host} -p {port}
交互方式
redis-cli -h {host} -p {port} {command}
命令方式
默认host是本机,即127.0.0.1
默认端口号6379
命令行客户端
redis-cli shutdown nosave|save(是否生成持久化文件)
停止Redis服务
Redis基本操作
Redis安装
初识Redis
慢查询只统计命令执行的时间,不包括命令排队以及网络时间所以没有慢查询并不代表客户端没有超时
slowlog-log-slower-than
slowlog-max-len
慢查询的两个配置参数
slowlog get [n]
slowlog len
slowlog reset
命令
slowlog-max-len线上建议调大慢查询队列
slowlog-log-slower-than 高QPS场景下建议配置为毫秒
客户端超时,需要检查该时间点是否有对应的慢查询,从而分析出是否为慢查询导致的命令级联阻塞
定期执行slow get 命令将慢查询日志持久化
最佳实践
慢查询分析
-r 命令执行多次
-i 每隔几秒执行一次命令(单位为秒,但是数值可以为小数,可以做到每隔几毫秒执行命令)
-x 从标准输入读取数据作为redis-cli的最后一个参数
-c 防止moved和ask异常
-a 密码
--scan 和 --pattern 扫描指定模式的键
--slave 将当前客户端模拟成当前redis节点的从节点
--rdb 请求redis实例生成并发送RDB持久化文件保存在本地,可用于定期备份
--pipe
--bigkeys 使用scan命令对redis的键进行采样,从中找到内存占用比较的的键值
-eval 指定指定的lua脚本
--latency 测试客户端到目标redis的网络延迟
--latency-history 分时段的形式了解延迟信息可以通过 -i 参数来控制间隔时间
--latency-dist 以统计图表的形式从控制台输出延迟统计信息
--latency 检测网络延迟
--stat 获取redis的统计信息
--raw 和 --no-raw
redis-cli
redis-server --test-memory 1024
redis-server
-c 并发量(默认为50)
-n 客户端请求总量
-q 仅仅显示requests per second 信息
redis-benchmark -c 100 -n 20000 -r 10000-r 10000 表示只对后四位做随机处理(-r 不是随机数的个数)
-r 产生随机键
-p 每个请求pipline的数据量
-t 对指定命令进行基准测试
--csv 将结果按照CSV格式输出
redis-benchmark
Redis shell
好处:减少RTT
每次Pipline组装的命令不宜过多,否则会增加客户端的等待实践以及造成一定的网路阻塞
pipeline
multi 开始事务 exec 结束事务 discard 停止事务
命令错误:如语法错误,导致事务不执行
错误处理
事务
eval 脚本内容 key 个数 key 列表 参数列表如:eval 'return \"hello\" .. KEYS[1] .. ARGV[1]' 1 redis world
加载脚本 script load \"${cat lua_get.lua}\"
执行脚本 evalsha 脚本SHA1值 key个数 key列表 参数列表
evalsha
redis.call 脚本执行失败,则执行结束并返回 redis.pcall 脚本执行失败,则忽略错误继续执行脚本
redis api与lua
lua的用法
lua脚本在redis中是原子执行的
可以定制新的命令
多条命令打包,减少RTT
lua的好处
script loadscript existsscript flushscript kill
lua_time_limt(默认为5s) lua脚本超时时间,当lua脚本执行时间超过该限制后,并不会停止执行lua脚本,只会向其他正在执行的命令发送 BUSY 的信号,此时需要执行script kill 命令来杀死lua脚本。
当lua脚本正在执行写操作的时候,那么script kill 命令将不会生效,此时只能等待执行结束或者shutdown save 停掉redis服务
管理lua脚本
lua
事务与lua
本身不是一种数据结构,实际上就是字符串,但是可以对字符串的位进行操作
可以将bitmaps想象成一个以位为单位的数组,数组的每一个单元只能存储0和1,数组的下标叫做偏移量
数据结构模型
setbit key offset value注意点:第一次初始化bitmaps时,如果偏移量很大,那么可能会阻塞redis
getbit key offset
计算bitmaps中第一个值为targetBit的偏移量bitops key targetBit [start] [end]
bitmaps
HyperLogLog
发布消息 publish channel message
订阅消息 subscribe channel [channel ...]
取消订阅 unsubscribe [channel [channel ...]]
按照模式订阅和取消订阅psubscribe pattern [patterb...]punsubscribe [pattern [pattern ...]]
查看活跃的频道 pubsub channels [pattern]查看频道订阅数 pubsub numsub [channel ...]查看模式订阅数 pubsub numpat
发布订阅
GEO
小功能大用处
save 阻塞redis服务器,知道RDB过程完成为止
bgsave 后台执行RDB操作
手动触发
使用save先关配置,如'save m n '
从节点执行全量复制操作
执行debug reload命令重新加载redis时,也会自动触发save操作
默认情况下执行shutdown命令时,如果没有开启AOF持久化功能则自动执行bgsave
自动触发
触发机制
流程说明
RDB是紧凑压缩的二进制文件,可用于备份,全量复制场景
redis加载RDB恢复数据远远快于AOF
优点
无法实时/秒级持久化
RDB文件版本兼容问题
子主题
缺点
RDB优缺点
RDB
appendonly yes开启aof
AOF工作流程
使用AOF
将redis命令以文本格式写入到aof文件中
命令写入
文件同步
降低了文件占用空间
更小的AOF文件可以更快地被Redis加载
AOF重写目的
进程内已经超时的数据不再写入文件
旧的AOF文件含有无效命令
多条写命令可以合并为一个,如:lpush list a、lpush list b、lpush list c可以转化为:lpush list a b c
重写后AOF文件变小
直接调用bgrewriteaof命令
根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数确定自动触发时机。
触发时机
重写流程
优先加载AOF文件
重启加载
重写机制
对于错误格式的AOF文件,先进行备份,然后采用redis-check-aof--fix命令进行修复,修复后使用diff-u对比数据的差异,找出丢失的数据,有些可以人工修改补全
文件校验
AOF
阻塞
全局命令
对应关系
可以改进内部编码,而对外的数据结构和命令没有影响,这样一旦开发出更优秀的内部编码,无需改动外部数据结构和命令
多种内部编码实现可以在不同场景下发挥各自的优势
好处
数据结构和内部编码
IO多路复用单线程架构
单线程架构
预备知识
int:8个字节的长整型
embstr:小于等于39个字节的字符串
raw:大于39个字节的字符串
内部编码
计数
共享session
限速
典型使用场景
字符串
哈希类型元素小于hash-max-ziplist-entries配置(默认512)
所有值都小于hash-max-ziplist-value配置(默认64)
ziplist(压缩列表)
hashtable(哈希表)
映射实体属性
使用场景
哈希
当列表的元素个数小于list-max-ziplist-entries配置(默认512个)
列表中每个元素的值都小于list-max-ziplist-value配置时(默认64字节)
ziplist(压缩列表)
linkedlist(链表)
消息队列
文章列表
lpush + lpop = Stack(栈)lpush + rpop = Queue(队列)lpush + ltrim = 有限集合lpush + brpop = 消息队列
使用口诀
列表
集合中的元素都是整数且元素个数小于set-max-intset-entries配置(默认512个)
intset(整数集合)
hashtable(哈希表)
标签功能
集合
列表,集合和有序集合异同点
有序集合的元素个数小于zset-max-ziplist-entries配置(默认128个)
每个元素的值都小于zset-max-ziplist-value配置(默认64字节)
skiplist(跳跃表)
排行榜
有序集合
rename key newkey (强制重命名)
renamenx key newkey(如果newkey已经存在则不生效)
键重命名
randomkey
随机返回一个键
expire key seconds
expireat key timestamp
秒为单位
pexpire key milliseconds
pexpireat key milliseconds-timestamp
毫秒为单位
查询剩余时间 ttl pttl
persist key
清除过期时间
执行set命令会去掉过期时间
Redis不支持二级数据机(如哈希,列表)构内部元素的过期功能
setex = set +expire
键过期
单个键管理
move key db(把指定的键从源数据库迁移到目标数据库)
在源Redis上执行dump命令将键值序列化,格式为RDB
在目标Redis上restore命令将上面序列化的值进行复原
dump + restore
migrate host port key|\"\" destination-db timeout [copy] [replace] [keys key [key ...]]
migrate
命令比较
迁移键
全量遍历键 keys pattern
渐进式遍历 scan cursor [match pattern] [count number]
遍历键
切换数据库 select dbIndex
清除数据库 flushdb/flushall
数据库管理
键管理
API的理解和使用
Redis开发与运维
0 条评论
回复 删除
下一页