Redis还提供了慢查询分析、Redis Shell、Pipeline、事务与Lua脚本、Bitmaps、HyperLogLog、发布订阅、GEO等功能
- 慢查询:通过慢查询分析,找到有问题的命令进行优化
- Redis Shell:
- Pipeline:通过Pipeline(管道或者流水线)机制有效提高客户端性能
- 事务与Lua:制作自己的专属原子命令
- Bitmaps:通过在字符串数据结构上使用位操作,有效节省内存,为开发提供新的思路
- HyperLogLog:基于概率的算法,节省内存空间
- 发布订阅:消息通信机制
- GEO:基于地理位置信息功能
- 慢查询分析
- Pipeline
- 事务与Lua
- Bitmaps
- HyperLogLog
- 发布订阅
- GEO(地理信息定位)
- 增加地理位置信息:geoadd key longitude latitude member [ longitude1 latitude1 member1...]
- 获取地理位置信息:geopos key member [member1...]
- 获取两个地理位置的距离:geodist key member1 member2 [unit]
- 获取指定范围内的地理信息位置集合:georadius key longitude latitude radiusm|km|ft|mi [withcoord] [whitdist] [withhash] [COUNT count] [asc|desc] [store key] [storedist key] 、georadiusbymember key member radiusm|km|ft|mi [withcoord] [whitdist] [withhash] [COUNT count] [asc|desc] [store key] [storedist key]
- 获取geohash:geohash key member [member1...]
- 删除地理位置信息:zrem key member
慢查询分析
在执行命令前后计算每条命令的执行时间,当超过预设阈值,就会将这条命令的相关信息记录下来
- 发送命令
- 命令排队
- 命令执行
- 返回结果
慢查询只统计到命令执行的时间,所以没有慢查询不代表客户端没有超时问题
慢查询的两个配置参数:预设阈值、查询日志
redis的所有配置文件如下
预设阈值:slowlog-log-slower-than、slowlog-max-len
redis.conf配置文件
- slowlog-log-slower-than:单位为us,默认为10000us,执行时间超过该时间就会被记录在慢查询日志中
- slowlog-max-len:慢查询日志最多存储条数,如果超过该条数则最早的记录会被剔除
日志:slowlog get [n]、slowlog len、slowlog reset
查询日志存放在Redis内存列表中,Redis没有暴露这个列表的键,而是通过一组命令来实现对慢查询日志的访问和管理
- 获取慢查询日志:slowlog get [n]
返回当前Redis的慢查询,n为可以指定的条数
- 获取慢查询日志列表当前长度:slowlog len
- 慢查询日志重置:slowlog reset
慢查询性能调优
- slowlog-max-len:线上建议调大慢查询列表,记录慢查询时Redis会对长命令做截断操作,并不会占用大量内存。可设置为1000以上
- slowlog-log-slower-than:需要根据redis并发量调整该值。Redis采用单线程。如果OPS不到1000,可以设置为1/1000=1ms,即1000以内的话可以设置1ms
- 慢查询只记录执行命令时间,不包括命令排队和网络传输。当客户端出现请求超时,需要检查该时间点是否有对应的慢查询,如果没有可以考虑是否为网络方面
- 慢查询是一个先进先出的队列,为防止慢查询较多丢失部分,可以定期执行slow get命令将慢查询日志持久化到其他存储中(MySQL等)
Redis Shell
Redis提供有redis-benchmark、redis-check-aof、redis-check-rdb、redis-cli、redis-sentinel、redis-server等shell工具
redis-cli 详解
redis-cli --help可以看出该shell的详细参数
- -r [repeat]:代表该命令将执行repeat次
- -i [interval]:每隔interval秒执行一次命令,必须和-r一起使用
- -x:从标准输入(stdin)读取数据作为redis-cli的最后一个参数
- -c [cluster]:连接Redis Cluster节点需使用,防止moved和ask异常
- -a:
- --scan、--pattern:
- --slave:把当前客户端模拟成当前Redis节点的从节点,可以获取当前Redis节点的更新操作
- --rdb:请求Redis实例生成并发送RDB持久化文件,保存在本地
- --pipe:将命令封装成Redis通信协议定义的数据格式,批量发送给Redis执行
- --bigkeys:
- --eval:执行指定Lua脚本
- --latency:检测Redis客户端和Redis服务端网络延迟
- --stat:实时获取Redis的重要统计信息
- --raw、--no-raw:分别返回格式化后的结果和原始的格式
redis-server 详解
- redis-server --test-memory
:检测当前系统能否稳定地分配指定的容量megabytes内存给Redis
redis-benchmark 详解
可以为Redis做基准性能测试
- -c:客户端的并发数量(默认50)
- -n:客户端请求总量(默认10000)
- -q:仅显示redis-benchmark的requests per second信息
- -r:
- -P:每个请求pipeline的数据量(默认为1)
- -k:代表客户端是否使用keepalive,1为使用,0为不使用,默认为1
- -t:
- --scv:结果按照scv格式输出,便于后续处理(导出到Excel等)
Pipeline
Pipeline概念
- Redis客户端执行一条命令分为
1.发送命令
2.命令排队
3.命令执行
4.返回结果
1+4步骤称为Round Trip Time(RTT,往返时间)
Redis提供了批量操作命令(mget、mset等),有效地节约RTT,但很多命令不支持批量操作,这个和Redis的高并发高吞吐特性背道而驰。Redis命令执行时间通常在us级别,所以有Redis性能瓶颈是网络传输延迟的说法。
Pipelinne(流水线)机制能改善这类问题,可以将一组Redis命令进行组装,通过一次RTT传输给Redis,再将这组Redis命令的执行结果按顺序返回给客户端。
大部门Reids的高级语言客户端例如Java的Jedis支持Pipeline
性能测试
1000条set非Pipeline和Pipeline的执行时间对比
网络 延迟(时间ms) 非Pipeline(时间ms) Pipeline(时间ms)
本机 0.17 573 134
内网服务器 0.41 1610 240
异地机房 7 78499 1104
原生批量命令与Pipeline对比
- 区别
1.原生是原子的,Pipeline是非原子的
2.原生一个命令对应多个key,Pineline支持多个命令
3.原生是Redis服务端实现,Pipeline是客户端和服务端共同实现
Redis调优
- 每次Pipeline组装的民联个数应有节制,若数据量过大会增加客户端等待时间,造成网络阻塞,可以将一次包含大量命令的Pipeline命令拆分成多次较小的Pipeline来完成
- Pipeline只能操作一个Redis实例,但在分布式场景中,可作为批量操作的重要优化手段
事务与Lua
为保证多条命令组合的原子性,Redis提供简单事务功能以及集成Lua脚本来解决这个问题
- 简单事务:是因为Redis不支持事务中的回滚特性,且无法实现命令之间的逻辑关系计算
事务
要么全部执行,要么全部不执行,否则会出现数据不一致的情况
- Redis简单事务的实现
1.multi:开启事务
2.输入执行的命令回车后继续输入要执行的命令
3.exec:开始执行
命令错误
如果属于语法错误(输入命令时错误),会造成整个事务无法执行
运行时错误
语法正确,但运行时出现错误(例如添加数据类型错误)
Redis不支持回滚功能,需要开发人员自己修复,在应用场景开启事务之前要确保事务中的key没有被其他客户端修改过,才执行事务,否则不执行(类似乐观锁)。Redis提供watch命令来解决这类问题
Lua语言用法简述
Lua语言由C语言实现,目标是作为嵌入式程序移植到其他应用程序,小巧且功能强大,许多应用都选用其作为脚本语言
数据类型及逻辑处理
- Lua提供了以下数据类型
1.booleans:布尔类型
2.numbers:数值
3.strings:字符串
4.tables:表格
函数定义
在Lua中,函数以function开头,以end结尾,funcName为函数名,中间部分为函数体,例如:
function funcName()
...
end
Redis与Lua
Redis管理Lua脚本
Bitmaps
数据结构模型
可以实现对位的操作,合理地使用能够有效地提高内存使用率和开发效率
- Bitmaps本身不是一种数据结构,实际位字符串,但可以对字符串的位进行操作
- Bitmaps单独提供了一套命令,可以把Bitmaps想象成一个以位为单位的数组,数组的每个单元只能存储0和1,数组的下标在Bitmaps中叫做偏移量
命令
设置值:setbit key offset value
HyperLogLog
HyperLogLog并不是一种新的数据结构(实际类型为字符串类型),而是一种基数算法。可以利用极小的内存空间完成独立总数的统计,数据集可以是IP、Email、ID等
发布订阅
Redis提供了基于“发布/订阅”模式的消息机制,在此模式下,消息发布者和订阅者不直接进行通信,发布者客户端向指定的频道(channel)发布消息,订阅该频道的每个客户端都可以收到该消息
命令
Redis主要提供了发布消息、订阅频道、取消订阅以及按照模式订阅和取消订阅命令
发布消息:pulish channel message
返回订阅者个数
如上图,因为无订阅者所以为0
订阅消息:subscribe channel [channel1...]
订阅一个或多个channel
- 注意点:
1.客户端在执行订阅命令之后进入了订阅状态,只能接受subscribe、psubscribe、unsubscribe、punsubscribe的四个命令
2.新开启的订阅客户端,无法接收到该频道之前的消息,因为Redis不会对发布的消息进行持久化
3.和很多专业的消息队列系统(Kafka、RocketMQ)相比,Redis的发布订阅比较粗糙,无法实现消息堆积和回溯。但胜在足够简单
取消订阅:unsubscribe [channel [channel....]]
取消对指定频道的订阅,取消成功后不会再收到该频道的发布消息
按照模式订阅和取消订阅:psubscribe|punsubscribe [pattern [pattern...]]
支持以glob风格的订阅命令psubscribe和取消顶骨额命令punsubscribe
查询订阅
- 查看活跃的频道:pubsub channels [pattern]
- 查看频道订阅数:pubsub numsub [channel ...]
- 查看模式订阅数:pubsub numpat
使用场景
聊天室、公告牌、服务之间利用消息解耦都可以使用发布订阅模式
GEO(地理信息定位)
Redis3.2版本提供了GEO功能,支持存储地址位置信息用来实现诸如附近位置,摇一摇这类依赖于地理位置信息的功能。GEO功能是借鉴NoSQL数据库Ardb实现的
增加地理位置信息:geoadd key longitude latitude member [ longitude1 latitude1 member1...]
向key键增加经度、维度、成员,返回成功添加的member成员数
获取地理位置信息:geopos key member [member1...]
返回经纬度,不存在则返回nil
获取两个地理位置的距离:geodist key member1 member2 [unit]
- unit:代表返回结果的单位
1.m:meters代表米
2.km:kilometers代表公里
2.mi:miles代表英里
4.ft:feet代表尺
不存在则返回nil
获取指定范围内的地理信息位置集合:georadius key longitude latitude radiusm|km|ft|mi [withcoord] [whitdist] [withhash] [COUNT count] [asc|desc] [store key] [storedist key] 、georadiusbymember key member radiusm|km|ft|mi [withcoord] [whitdist] [withhash] [COUNT count] [asc|desc] [store key] [storedist key]
georadius、georadiusbymember两个命令作用是一样的,都是以一个地理位置为中心算出指定半径内的其他地理位置信息。georadius需要给出具体的经纬度、georadiusbymember只需要给出成员即可。radiusm|km|ft|mi是必须参数,制定了半径(带单位)
- withcoord:返回结果中包含经纬度
- withdist:返回经过中包含离中心节点位置的距离
- withhash:返回结果中包含geohash
- COUNT count:指定返回结果的数量
- asc|desc:返回结果按照离中心节点的距离做升序或者降序
- store key:将返回结果的地理位置信息保存到指定键
- storedist key:将返回结果离中心节点的距离保存到指定键
获取geohash:geohash key member [member1...]
使用geohash将二位经纬度转换为以为字符串
- geohash特点
1.GEO的数据类型为zset,Redis将所有地理信息的geohash存放在zset中
2.字符串越长表示的精度位置更准确,长度为9时精度在2米
3.两个字符串越相似,则表示的位置距离越近
4.geohash编码和经纬度是可以相互转换的
删除地理位置信息:zrem key member
GEO没有提供删除成员的命令,因为其底层实现时zset,可以借用zrem命令实现对地理位置信息的删除
Comments | 0 条评论