redis实用功能

1、慢查询分析

慢查询日志:系统在命令执行前后计算每条命令的执行时间,当超过预设阀值,就将该条命令的相关信息记录下来(比如发生时间、耗时、命令详细信息)记录下来。

redis客户端执行一条命令有以下步骤:
1)、发送命令;
2)、命令排队;
3)、命令执行;
4)、命令返回;
慢查询只统计步骤3的时间,故没有慢查询并不代表客户端没有超时。

1.1 :慢查询配置参数

redis提供了两个可供配置参数:
1)、slowlog-log-slower-than:预设阀值,其单位为微妙,默认值为10000;
2)、slowlog-max-len:redis使用一个列表来存储慢查询日志,slowlog-max-len就是列表的最大长度。一个新的命令满足慢查询条件时被插入这个列表中,当慢查询日志列表已处于其最大长度时,最早插入的一个命令将从列表中移出。

redis中有两种修改配置的方式:修改配置文件或使用config set命令动态修改。

config set slowlog-log-slower-than 20000
config set slowlog-max-len 1000
config rewrite

若需要将配置持久化到配置文件,需执行config rewrite命令。

管理慢查询日志:
1)、获取慢查询日志:

slowlog get [n]

每个慢查询日志由4个属性组成,分别是慢查询日志标识id、发生时间戳、命令耗时、执行命令及参数;
2)、获取慢查询日志列表当前的长度:

slowlog len

3)、慢查询日志重置:

slowlog reset
1.2 :配置建议

1)、slowlog-max-len配置建议:线上建议调大慢查询列表,记录慢查询时redis会对长命令做截断操作,并不会占用大量内存;
2)、slowlog-log-slower-than:默认命令执行超过10毫秒的命令判定为慢查询,需根据redis并发量调整该值;
3)、慢查询只记录命令执行时间,并不包括命令排队和网络传输时间;
4)、由于慢查询日志是一个先进先出的队列,如果在慢查询比较多的情况下就会丢失部分慢查询命令;

2、redis shell

redis提供了redis-cli、redis-server、redis-benchmark等shell工具。

2.1 :redis-cli

命令详解:
1、-r(repeat):代表将同一条命令执行多次:

redis-cli -a xxx -r 3 ping

2、-i(interval):代表每隔几秒钟执行一次命令,-i 选项必须与-r 选项一起使用:

redis-cli -a xxx -r 5 -i 1 ping

3、-x :代表从标准输入读取数据作为redis-cli的最后一个参数:

$ echo "redis" | redis-cli -a yhj1994 -x set hello

4、-c(cluster) :连接redis-cluster节点时需要使用的,可以防止moved和ask异常:
5、-a(auth) :如果配置了密码,此选项和避免输入密码:
6、–scan和–pattern:用于扫描特定模式的键,相当于scan命令:
7、–slave:可以将当前客户端模拟成当前节点的从节点,用来获取当前redis节点的更新操作:PING命令是主从复制产生的;
8、–rdb:该选项会请求redis实例生成并发送rdb持久化文件保存到本地:
9、–pipe:用于将命令封装成redis通信协议定义的数据格式,批量发送给redis执行:
10、–bigkeys:该选项使用scan命令对redis的键进行采样,从中找到内存占用比较大的键值:

redis-cli -a xxx --bigkeys

11、–eval:用于执行指定Lua脚本:

12、–latency:
1)、–latency:测试客户端到目标redis的网络延迟;
2)、–latency-history:以分时段的形式展示延迟信息;
3)、–latency-dist:使用统计图表的形式从控制台输出延迟统计信息;

redis-cli -a xxx --latency
redis-cli -a xxx --latency-history
redis-cli -a xxx --latency-dist

13、–stat:实时获取redis的重要统计信息,虽info命令的统计信息更全面,但stat命令能看到一些增量信息;

redis-cli -a xxx --stat

14、–raw和–no-raw:
–no-raw选项要求命令的返回结果必须是原始格式,–raw要求命令返回的结果必须是序列化之后的结果;

redis-cli -a xxx --raw
redis-cli -a xxx --no-raw
2.2 :redis-server

redis-server除了启动redis外,还有一个–test-memory选项,该命令用来测试当前操作系统能否稳定地分配指定容量的内存给redis。

redis-server --test-memory 1024

参考地址:
http://www.memtest86.com
http://pyropus.ca/software/memtester

2.3 :redis-benchmark

1、-c(clients):代表客户端的并发数量(默认50);
2、-n(num) :代表客户端请求总量(默认100000):

redis-benchmark -c 100 -n 20000

代表100个客户端同时请求redis,共执行20000次;
3、-q:仅仅显示redis-benchmark的request per second的值:

redis-benchmark -c 100 -n 20000 -q

4、-r:随机向库中插入随机键值,选项会在key、counter键上加一个12位的后缀,-r 10000表示只对后四位进行随机处理:

redis-benchmark -c 100 -n 20000 -r 10000

5、-P:代表每个请求pipeline的数据量(默认1);
6、-k :代表客户端是否使用keepalive,1为使用,0为不使用,默认使用;
7、-t :可以指定命令进行基准测试:

redis-benchmark -t get,set -q

8、–csv:将结果按照csv格式输出,便于后续处理:

redis-benchmark -t get,set --csv
3、Pipeline
3.1 :概念

redis客户端执行命令分为4步:
1)、发送命令;
2)、命令排队;
3)、命令执行;
4)、返回结果;
其中第1和第4步成为Round Trip Time(RTT往返时间)。
redis提供了批量操作命令(mget、mset等),有效节约RTT,但大部分命令是不支持批量操作的;
Pipeline机制可改善上述问题,它将一组redis命令进行组装,通过一次RTT传输给redis,再将这组redis命令执行结果按顺序返回给客户端;

3.2 :原生命令对比

1、原生批量命令是原子的,Pipeline是非原子的;
2、原生批量命令是一个命令对应多个key,Pipeline支持多个命令;
3、原生批量命令是redis服务端支持实现的,而Pipeline需要服务端和客户端的共同实现;

3.3 :配置建议

实际当中Pipeline组装的命令个数不能没有节制,否则一次组装Pipeline数据量过大,一方面会增加客户端的等待时间,另一方面会造成网络阻塞,可以将一次包含大量命令的Pipeline拆分成多次较小的Pipeline来完成。

4、事务与Lua
4.1 :redis事务

redis提供了简单的事务功能,将一组需要一起执行的命令放到multi和exec两个命令之间,multi命令代表事务开始,exec命令代表事务结束,它们之间的命令是原子顺序执行的:

multi
sadd user:a:follow user:b
sadd user:b:fans user:a

只有在exec命令执行后,事务才算结束:

exec
sismember user:a:follow user:b

如果要停止事务的执行,使用discard命令代替exec命令即可:

discard
sismember user:a:follow user:b

1、命令错误:
下面操作误将set写成了sett,属于语法错误,会造成整个事务无法执行,key和counter的值未发生变化:

multi
sett key world
incr counter
exec

2、运行时错误:
例如用户b再添加粉丝列表时,误将sadd命令写成zadd命令,这种情况redis并不会回滚,因为这属于运行时错误:

multi
sadd user:a:follow user:b
zadd user:b:fans 1 user:a
exec

有些场景需要在事务之前,确保事务中的key没有被其他客户端修改过才执行事务,否则不执行,故redis提供了watch命令来解决这类问题。

时间点ClientAClientB
T1set key “java”
T2watch key
T3multi
T4append key python
T5append key redis
T6exec
T7get key

最终事务未执行,返回结果为"javapython"

4.2 :redis与Lua

1、在redis当中使用Lua:
1)、eval:

eval 脚本内容 key个数 key列表 参数列表

eg:eval 'return "hello " .. KEYS[1] .. ARGV[1]' 1 redis world

如果Lua脚本较长,还可以使用redis-cli–eval直接执行文件。

2)、evalsha:
首先将Lua脚本加载到服务端,得到该脚本的SHA1校验和,evalsha命令使用sha1作为参数可以直接执行对应Lua脚本,避免每次发送Lua脚本的开销。如此客户端就不需要每次执行脚本内容,脚本也会常驻在服务端,脚本功能得到了复用。

加载脚本:script load命令可以将脚本内容加载到redis内存中;

redis-cli script load "${cat lua_get.lua}"

执行脚本:evalsha命令使用sha1值,执行逻辑与eval一致;

evalsha xxxx 1 redis world

2、Lua的redis api:
Lua可以使用redis.call函数实现对redis的访问,以下示例调用get/set命令:

redis.call("set","hello","world")
redis.call("get")

在redis中执行:

eval 'return redis.call("get",KEYS[1])' 1 hello

3、Lua脚本对redis开发运维的好处:
1)、Lua脚本在redis中是原子执行的,执行过程中间不会插入其他命令;
2)、Lua命令脚本可以定制命令并可以将命令常驻在redis内存中;
3)、Lua脚本可以将多条命令一次性打包,有效减少网络开销;

案例:

redis-cli -a xxx --eval /xx/xx/lrange_and_mget.lua hot:user:list

脚本lrange_and_mget.lua内容:

local mylist = redis.call("lrange",KEYS[1],0,-1)
local count = 0
for index,key in ipairs(mylist)
do
	redis.call("incr",key)
    count = count + 1
end
return count
4.3 :管理Lua脚本

redis提供了4个命令实现对Lua脚本的管理:
1)、script load:命令用于将Lua脚本加载到redis内存当中;

script load script

2)、script exists:判断sha1是否已经加载到redis内存中;

script exists sha1 [sha1 ...]

3)、script flush:清除redis内存中已加载的所有Lua脚本;
4)、script kill:杀掉正在执行的脚本,如果Lua脚本比较耗时,甚至Lua脚本本身存在问题,那么此时Lua脚本的执行会阻塞redis;

如果Lua脚本在执行写入操作,那么script kill将不会生效,只能使用shutdown nosave停掉服务;

5、bitmaps
5.1 :结构模型

1、bitmaps本身不是一种数据结构,实际上它就是字符串,但是它可以对字符串的位进行操作;
2、bitmaps单独提供了一套命令,所以在redis中使用bitmaps和使用字符串不太相同。可以理解为一个以位为单位的数组,数组的每个单元只能存储1和0,数组下标在bitmaps中称之为偏移量;

5.2 :常用命令
命令解释
setbit key offset value设置值
getbit key offset获取值
bitcount key [start] [end]获取bitmaps指定范围值为1的个数
bitop op destkey key [key …]bitmaps间的运算
bitpos key targetBit [start] [end]计算bitmaps中第一个值为targetBit的偏移量
6、HyperLogLog
6.1 :常用命令

1、添加:

pfadd key element [element ...]

2、计算独立用户数:

pfcount key [key ...]

集合类型与HyperLogLog占用空间对比

数据类型1天1个月1年
集合类型80M2.4G28G
HyperLogLog15K450K5M

3、合并:

pgmerge destkey sourcekey [sourcekey ...]

pfmerge可以求出多个HyperLogLog的并集并赋值给destkey。

7、发布订阅
7.1 :常用命令

1、发布命令:

publish channel message

2、订阅消息:

subscribe channel [channel ...]

注意点:
1)、客户端在执行订阅命令之后进入了订阅状态,只能接受subscribe、psubscribe、unsubscribe、punsubscribe的四个命令;
2)、新开启的订阅客户端,无法收到该频道之前的消息,因为redis不会对发布的消息进行持久化;

3、取消订阅:

unsubscribe [channel [channel ...]]

4、按照模式订阅或取消:

psubscribe pattern [pattern ...]
punsubscribe [pattern [pattern ...]]

5、查询订阅:
1)、查看活跃频道:

pubsub channels [pattern]

2)、查看频道订阅数:

pubsub numsub [channels]

3)、查看模式订阅数:

pubsub numpat
8、GEO

GEO功能支持存储地理位置信息用来实现诸如附近位置、摇一摇等依赖于地理位置信息的功能

8.1 :常用命令

1、增加地理位置信息:

geoadd key longitude latitude member [longitude latitude number ...]

eg:geoadd cities:locations 116.30 40.00 beijing

如果key对应的member添加结果返回为1则为新增,为0表示已存在或更新。

2、获取地理位置信息:

geopos key member [member ...]

3、获取两个地理位置的距离:

geodist key member1 member2 [unit]

unit可选值:
1)、m 代表米;
2)、km 代表公里;
3)、mi 代表英里;
4)、ft 代表尺;

4、获取指定位置范围内的地理信息位置集合:

georadius key longitude latitude radius m|km|mi|ft [withcoord] [withdist] [withhash] [COUNT count] [asc|desc] [store key] [storedist key]

georadiusbymember key member radius m|km|mi|ft [withcoord] [withdist] [withhash] [COUNT count] [asc|desc] [store key] [storedist key]

两个命令的效果类似,都是给定一个具体位置及半径求出半径范围内匹配的位置。
参数解释:
1)、withcoord:返回结果中包含经纬度;
2)、withdist:返回结果中包含离中心节点位置的距离;
3)、withhash:返回结果中包含geohash;
4)、COUNT count:指定返回结果的数量;
5)、asc|desc:返回结果根据距中心距离升序或降序;
6)、store key:将返回结果的地理位置信息保存到指定key;
7)、storedist key:将返回结果距离中心结果的距离保存到指定key;

5、获取geohash:

geohash key member [member ...]

redis使用geohash将二维经纬度转换为一维字符串。
geohash的特点:
1)、GEO的数据类型为zset,redis将所有地理位置信息的geohash存放在zset中;
2)、字符串越长,表示的位置更精确;
3)、两个字符串相似度越近,它们之间的距离越近,redis使用字符串的前缀匹配算法实现相关命令;
4)、geohash编码的经纬度是可以相互转化的;

geohash长度与精度的对应关系

geohash长度精度(km)
12500
2630
378
420
52.4
60.61
70.076
80.019
90.002

6、删除地理位置信息:

zrem key member

GEO未提供删除成员命令,但因其底层实现是zset,故可使用zrem命令实现对地理位置信息的删除

参考《redis开发与运维》
redis官网文档:https://redis.io/documentation

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值