redis audit内存分析工具在redis cluster中的应用

来源:互联网 发布:wince pdf软件下载 编辑:程序博客网 时间:2024/06/16 20:15

内容:

redis audit工具是使用ruby语言编写的脚本,用来分析redis哪些key占内存比较多,及占用内存较多的key键的过期时间。在分析redis内存增长时非常有帮助。在分析时,为了防止对生产库的影响,一般在从库上执行。但是在使用redis audit分析redis cluster从库实例时发现报错不能使用。于是花了些时间分析原因并使之能够使用redis cluster从库实例。


背景:

有个redis集群由于接入了新业务系统,导致redis cluster内存8个实例增加了64g内存。另外还在以每天8g的速度增加。


使用工具rubyredis audit查询哪些key占内存比较多,发现这个工具还不能支持redis cluster环境。



抽查了几个key的过期时间,发现都是千万年的过期时间。下面这个key46千年。


127.0.0.1:6410> ttl "b7b9dd35-1149-41ab-94d5-14906a68ab50_1464403073675"

(integer) 1462986538098


联系该系统的外购厂商查看,解释说这些key是少数的配置信息。其他内存是正常增长,要求扩容。


实在没办法了,只好将aof文件拷贝到一个非集群空实例上进行回放,再使用redis audit进行分析。


---------------------------------------------------+--------------+-------------------+---------------------------------------------------
Key                                                | Memory Usage | Expiry Proportion | Last Access Time                                  
---------------------------------------------------+--------------+-------------------+---------------------------------------------------
e005a0c4-
242a-4888-8418-ca3b46b7951a_3547790698057 | 3.38%        | 100.0%            | 0 seconds                                        
cbd4d269-
8081-498b:10100000003215023              | 2.55%        | 100.0%            | 3 seconds                                         
cbd4d269-
488b-4fba-8a71-7c5125cfe268_90e1865f11559 | 0.57%        | 100.0%            | 61 days, 13 hours, 3 minutes, 12 seconds         
e82192ea-
439b-4b18-ad79-1b03d440042b_0000000000000 | 0.36%        | 100.0%            | 0 seconds                                        
fff01f23-
881e-434d-8061-5229c2c67a0a_E12861F9-5418 | 0.28%        | 100.0%            | 61 days, 13 hours, 3 minutes, 13 seconds         
2c69edf4-844d-4b6d-80ad-aa26046d5b34_015c7b47c43c1 | 0.17%        | 100.0%            | 0 seconds                                       

==============================================================================

Found 8 keys containing strings, like:

[0;33m765b506e-9052-4002-b2e4-c2062e392da6_1464172442715, 74be1490-1501-4634-bfb1-9ea25b14ed9a_1464923898832, 27b4e195-0208-4434-9345-91a2f127c173_1464572544882, 32b18e20-0997-4c80-b335-f69ad857e86d_1464077619056, 2b5456e5-4948-4f7d-9a9f-2679b566a732_1464362686736, 3038b6e7-3929-4023-88ac-3eec1e198075_1462865085803, 71b10e08-8399-4572-a807-a2a59277a66f_1464250132607, 73b4706e-4016-4651-9755-06a44aa16a1a_1464751883853[0m

These keys use [0;1;4m0.08%[0m of the total sampled memory (16 bytes)

[0;1;4m100.0%[0m of these keys expire (8), with maximum ttl of 16938711 days, 9 hours, 33 minutes, 23 seconds

Average last accessed time: [0;1;4m0 seconds[0m - (Max: 0 seconds Min:0 seconds)

==============================================================================

Found 8 keys containing strings, like:

[0;33m47160e49-4421-44f1-a6aa-de40d00fa752_1464230697555, 752e6455-9511-4f71-9eff-5932d0b5c5d5_1461976447739, e0053117-4541-49f8-a998-da86ea0740f3_14641242393705948206e-1219-4f76-a877-a535b4bf8a53_14648874592614470937e-1641-4fd5-bba7-47ac21477536_1464716582874, 2595e912-8264-45f4-b109-ea06f843b4ef_146482509873963821e85-9080-497f-9438-adae16a551cd_1463280482719, 774e7379-8333-412f-a7fa-b5b0b0d7e44f_1464358656511[0m

These keys use [0;1;4m0.08%[0m of the total sampled memory (16 bytes)

[0;1;4m100.0%[0m of these keys expire (8), with maximum ttl of 16938711 days, 9 hours, 33 minutes, 14 seconds

Average last accessed time: [0;1;4m0 seconds[0m - (Max: 0 seconds Min:0 seconds)

通过分析发现几乎所有的key都是万年以上的过期时间。要求厂商再次排查,原来是将过期时间单位看错了,多乘了几个0


经过这次问题分析,发现分析过程比较麻烦,最好工具redis audit直接分析redis cluster。于是尝试查找下redis audit在redis cluster运行时出错的原因。


根据前面在redis cluster下运行出错的信息进行debug redis audit脚本,发现真实的报错如下:


根据报错信息猜测是key被分片到其他节点。

redis 3.0的客户端工具redis-cli有个选项-c 是用来连接redis cluster集群的,但是rubyredis客户端api没有提供类似功能。在网上查找了ruby访问redis cluster客户端redis-rb-cluster (https://github.com/antirez/redis-rb-cluster)

修改了redis-audit代码使用rubyRedisCluster创建连接,运行后发现还是有同样的报错。


查看redis-rb-cluster提供的案例example.rb:调用的是get接口和set,并能从cluster中成功的设置和获取key



具体在redis-rb-cluster文件cluster.rb中封装的接口中,先是根据key获取slot,然后根据slot在获取可以所在的实例(也就是host和端口)。。



查看slot函数,发现redis cluster使用的是CCITT standardsXMODEM CRC 16 algorithm。百度了下CCITTCCITT是国际电报电话咨询委员会的简称,它是国际电信联盟(ITU)的前身。Xmodem是在1978年由Ward Christensen创建的用于调制解调器纠错的协议。



了解了redis cluster连接方法,就很容易解决redis-audit工具的问题,将原来的连接方式修改为先获取randomkey,根据key找到对应的节点,并创建连接。


本来到这儿可以结束了,但是为了查找下这些key最终都指向哪个实例了,将选择的节点都打印出来,发现都是同一个节点:

192.168.0.5:6379

192.168.0.5:6379

192.168.0.5:6379

192.168.0.5:6379

192.168.0.5:6379

192.168.0.5:6379


而其slot都是在节点6379slot区间:8192-10239。这个节点192.168.0.5是发起查找实例192.168.0.6的主库节点。这里解释下,为了防止redis audit分析工具对生产库的影响,规定redis audit只能对redis的从库执行,这样redis的主库是不受影响的。


那么为什么在redis cluster集群中在redis从实例上查询数据,连接会被定向到redis主实例上呢?查了redis cluster官方文档http://redis.io/commands/readonly,发现如果需要查询redis cluster的从实例数据,需要执行函数redis.readonly()。否则,redis cluster会自动将客户端的连接重新定向到从库对应的主库。


通过近两天的时间分析,了解了redis cluster的分片算法,学习了ruby连接redisredis cluster的方法原理。并修改了redis audit工具,使之能够适用redis cluster的架构。


下面是经过和其他同事讨论规范后的redis audit修改代码:请见标黄部分:


[padba@localhost-redis-audit-master]$ more redis-audit.rb

#!/usr/bin/ruby


….省略其他代码


host = ARGV[0]

port = ARGV[1].to_i

db = ARGV[2].to_i

sample_size = ARGV[3].to_i

password = ARGV[4]


redis = Redis.new(:host => host, :port => port, :password => password, :db => db)


begin

         redis.readonly()

rescue Exception => e

    puts "The redis instance is not a cluster member."

End


修改后redis audit可以支持在redis cluster从库上进行分析了。


总结:

在使用redis audit分析redis cluster从库实例时,需要修改脚本redis-audit.rb,在连接redis时调用方法redis.readonly()方法,这个是redis cluster从库实例特殊要求的。随着redis cluster的广泛使用,希望能够对后续redis cluster从库的内存问题分析有所帮助。


原创粉丝点击