Redis还提供了慢查询分析、Redis Shell、Pipeline、事务与Lua脚本、Bitmaps、HyperLogLog、发布订阅、GEO等功能

  • 慢查询:通过慢查询分析,找到有问题的命令进行优化
  • Redis Shell:
  • Pipeline:通过Pipeline(管道或者流水线)机制有效提高客户端性能
  • 事务与Lua:制作自己的专属原子命令
  • Bitmaps:通过在字符串数据结构上使用位操作,有效节省内存,为开发提供新的思路
  • HyperLogLog:基于概率的算法,节省内存空间
  • 发布订阅:消息通信机制
  • GEO:基于地理位置信息功能

慢查询分析

在执行命令前后计算每条命令的执行时间,当超过预设阈值,就会将这条命令的相关信息记录下来
image.png

  • 发送命令
  • 命令排队
  • 命令执行
  • 返回结果

慢查询只统计到命令执行的时间,所以没有慢查询不代表客户端没有超时问题

慢查询的两个配置参数:预设阈值、查询日志

redis的所有配置文件如下
image.png

预设阈值:slowlog-log-slower-than、slowlog-max-len

redis.conf配置文件
image.png

  • slowlog-log-slower-than:单位为us,默认为10000us,执行时间超过该时间就会被记录在慢查询日志中
  • slowlog-max-len:慢查询日志最多存储条数,如果超过该条数则最早的记录会被剔除

日志:slowlog get [n]、slowlog len、slowlog reset

查询日志存放在Redis内存列表中,Redis没有暴露这个列表的键,而是通过一组命令来实现对慢查询日志的访问和管理

  • 获取慢查询日志:slowlog get [n]
    返回当前Redis的慢查询,n为可以指定的条数
    image.png
  • 获取慢查询日志列表当前长度:slowlog len
    image.png
  • 慢查询日志重置:slowlog reset
    image.png

慢查询性能调优

  • slowlog-max-len:线上建议调大慢查询列表,记录慢查询时Redis会对长命令做截断操作,并不会占用大量内存。可设置为1000以上
  • slowlog-log-slower-than:需要根据redis并发量调整该值。Redis采用单线程。如果OPS不到1000,可以设置为1/1000=1ms,即1000以内的话可以设置1ms
  • 慢查询只记录执行命令时间,不包括命令排队和网络传输。当客户端出现请求超时,需要检查该时间点是否有对应的慢查询,如果没有可以考虑是否为网络方面
  • 慢查询是一个先进先出的队列,为防止慢查询较多丢失部分,可以定期执行slow get命令将慢查询日志持久化到其他存储中(MySQL等)

Redis Shell

image.png
Redis提供有redis-benchmark、redis-check-aof、redis-check-rdb、redis-cli、redis-sentinel、redis-server等shell工具

redis-cli 详解

redis-cli --help可以看出该shell的详细参数
image.png

  • -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 详解

image.png

  • redis-server --test-memory :检测当前系统能否稳定地分配指定的容量megabytes内存给Redis

redis-benchmark 详解

可以为Redis做基准性能测试
image.png

  • -c:客户端的并发数量(默认50)
  • -n:客户端请求总量(默认10000)
  • -q:仅显示redis-benchmark的requests per second信息
  • -r:
  • -P:每个请求pipeline的数据量(默认为1)
  • -k:代表客户端是否使用keepalive,1为使用,0为不使用,默认为1
  • -t:
  • --scv:结果按照scv格式输出,便于后续处理(导出到Excel等)

image.png

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:开始执行
    image.png

命令错误

如果属于语法错误(输入命令时错误),会造成整个事务无法执行

运行时错误

语法正确,但运行时出现错误(例如添加数据类型错误)
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)发布消息,订阅该频道的每个客户端都可以收到该消息
image.png

命令

Redis主要提供了发布消息、订阅频道、取消订阅以及按照模式订阅和取消订阅命令

发布消息:pulish channel message

返回订阅者个数
image.png
如上图,因为无订阅者所以为0

订阅消息:subscribe channel [channel1...]

订阅一个或多个channel

image.png

  • 注意点:
    1.客户端在执行订阅命令之后进入了订阅状态,只能接受subscribe、psubscribe、unsubscribe、punsubscribe的四个命令
    2.新开启的订阅客户端,无法接收到该频道之前的消息,因为Redis不会对发布的消息进行持久化
    3.和很多专业的消息队列系统(Kafka、RocketMQ)相比,Redis的发布订阅比较粗糙,无法实现消息堆积和回溯。但胜在足够简单

取消订阅:unsubscribe [channel [channel....]]

取消对指定频道的订阅,取消成功后不会再收到该频道的发布消息
image.png

按照模式订阅和取消订阅:psubscribe|punsubscribe [pattern [pattern...]]

支持以glob风格的订阅命令psubscribe和取消顶骨额命令punsubscribe

查询订阅

  • 查看活跃的频道:pubsub channels [pattern]
    image.png
  • 查看频道订阅数:pubsub numsub [channel ...]
    image.png
  • 查看模式订阅数:pubsub numpat
    image.png

使用场景

聊天室、公告牌、服务之间利用消息解耦都可以使用发布订阅模式

GEO(地理信息定位)

Redis3.2版本提供了GEO功能,支持存储地址位置信息用来实现诸如附近位置,摇一摇这类依赖于地理位置信息的功能。GEO功能是借鉴NoSQL数据库Ardb实现的

增加地理位置信息:geoadd key longitude latitude member [ longitude1 latitude1 member1...]

向key键增加经度、维度、成员,返回成功添加的member成员数
image.png

获取地理位置信息:geopos key member [member1...]

image.png
返回经纬度,不存在则返回nil

获取两个地理位置的距离:geodist key member1 member2 [unit]

  • unit:代表返回结果的单位
    1.m:meters代表米
    2.km:kilometers代表公里
    2.mi:miles代表英里
    4.ft:feet代表尺
    image.png
    不存在则返回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:将返回结果离中心节点的距离保存到指定键

image.png

获取geohash:geohash key member [member1...]

使用geohash将二位经纬度转换为以为字符串
image.png

  • geohash特点
    1.GEO的数据类型为zset,Redis将所有地理信息的geohash存放在zset中
    2.字符串越长表示的精度位置更准确,长度为9时精度在2米
    3.两个字符串越相似,则表示的位置距离越近
    4.geohash编码和经纬度是可以相互转换的

删除地理位置信息:zrem key member

GEO没有提供删除成员的命令,因为其底层实现时zset,可以借用zrem命令实现对地理位置信息的删除


这个家伙很懒,啥也没有留下😋