微信号:gh_d863b47fc1cc

介绍:人生也是一场马拉松,然而这场马拉松也有上坡下坡,不同的是路途中很少或者几乎没有志愿者为你服务.希望我们能一起鼓舞彼此,跑完精彩的"马拉松!"

浅谈redis超时(一)

2016-07-25 08:21 Andy_xu

        其实redis运维过程中,最大的就是三个难题,只要解决这三个问题,redis就可以说几乎没有什么问题了,业务就可以放心使用了,运维redis的人也就可以喝喝茶干嘛的了。

        But,要实现并做好这三点不是随意说说那么简单的:

        1.集群化部署和管理web;

        2.监控和报警;

        3.延迟排查分析

为什么说这三点是最主要的,首先集群化部署和管理会让整个redis状态透明起来,管理人员可以很方便的多多个集群进行管理和维护,不仅减少维护成本,也能减少出错成本,毕竟命令行下的东西还是有出错概率的嘛;监控和报警其实很大程度上能够让redis运行状态透明起来,比如流量在某段时间多高,内存使用情况,tps、qps等,同时部分权限开通给业务方也能让业务方更好的评估业务状态;为什么要单说延迟排查分析呢,因为普通的redis维护其他方面都比较简单,而延迟是对业务影响会比较大而且原因比较复杂的一个问题。

        什么延迟呢?所谓延迟就是超过业务方设定的超时时间依然得不到响应,就可以认为有延迟存在了,因为一般的redis请求基本上都是毫秒级别的,而业务一般会设置几十秒甚至一二百秒作为超时时间限制。

参照:http://redis.io/topics/latency 

简单测试一下延迟体验:

随便登陆到某一个redis节点执行以下命令,感受下返回时间:

debug sleep 10

这条命令相当于手动让redis延迟了10s,由于是单线程处理请求的,这一操作会影响到其他业务响应,因此就可能造成了业务上的超时。什么?你觉得才10s就会延迟,其实几百号秒的延迟对于redis这种内存数据库来说已经是很影响性能的了,毕竟作为缓存使用,针对一个高吞吐高并发的业务系统来说,每一毫秒的影响都是巨大的。

        知道了延迟之后,就需要开始排查延迟是由什么引起的,有监控的前提下,其实可以先通过监控大概看下,没有的话就按照以下步骤走吧,不能说很规整,但起码我认为还是可以作为依据的,毕竟是借鉴官网的嘛。


  1. 确认是否使用慢查询,可以使用slowlog get num查看相应的慢命令

            http://redis.io/commands/slowlog
            127.0.0.1:6379> SLOWLOG get 10
            1) 1) (integer) 4                             #慢操作索引
            2) (integer) 1466059344               #事件发生的Unix时间戳
            3 ) (integer) 250133                      #事件耗时微妙(0.25s,250ms,250133us)
            4) 1) "debug"                               #时间具体命令以及相应参数
            2) "sleep"
            3) ".25"
            127.0.0.1:6379> CONFIG SET slowlog-log-slower-than 1000 #设置当key的操作超过多长时间就会别加入到slowlog队列 默认单位us(0.001s) 默认是超过10ms

注意:

         unix时间戳转换方式:

              date -d@'1466059344' "+ %Y-%m-%d %H:%M:%S"

              date -d"2016-06-16 16:50:50" '+%s'

注意:一般大量的key删除操作,以及keys遍历操作都可能会造成超时


2.查看redis状态的几个关键项:

            内存使用情况,当前链接客户端数量,ops等

使用info命令其实就可以看出来具体的状态信息,具体下一章再分析


3.查看透明大页是否禁止掉(Transparent huge pages)。

            官方建议是禁止掉比较好,线上测试其实效果不是特别明显
            linux下查看默认内存页大小(getconf PAGESIZE),默认是4K
            设置hugepage的数量;sysctl vm.nr_hugepages = 1024
            echo never > /sys/kernel/mm/transparent_hugepage/enabled


4.查看redis主机是否为虚拟机,这样会有内在延迟
            测试延迟:
            ./redis-cli --intrinsic-latency 100
            这个命令可以在server段进行判断是否redis有延迟,在客户端通过-h -p 参数可以进行对比一下是否为网络上的影响。


5.启用延迟监控:

http://redis.io/topics/latency-monitor 
      latency monitoring: 
                可以找出相应的延迟的敏感代码路径
                延迟记录按照不同的时间进行时间流分隔统计
                从时间序列中获取原始数据并进行报表
                分析报表并提供人类可读的报告,并且根据度量值进行判断

        时间序列(time series):
                每个时间延迟任务都会记录到时间序列
                每个时间序列包含160个元素
                每个元素为一组:unix时间戳和事件执行所消耗的时间长
                同一时间同一事件发生的延迟时间是会记录在一个时间序列。因此即使一个给定事件连续的延迟是可以衡量的(比如用户设置临界值太低),也至少得180s才能可达
                最大延迟时间中的每一个元素都会被记录下来


        怎样启用latency monitoring:
            首先对于用户场景来说,什么是高延迟。应用请求查询少于1ms并且;短时间有比较少客户端的应用经历2m的延迟是可以接受的
        因此,开启latency monitor首先需要设置延迟时间阈值在毫秒级别(latency threshold)。当然了,也需要根据实际情况进行设定相应的值了

         CONFIG SET latency-monitor-threshold 100
        需要注意的是:latency-monitor的阈值不能大于slowlog的值
        注意:延迟监控所需要的内存是非常小的,当然能增加内存是最好的啦


latency命令报告出来的相关信息
         用户接口使用latency命令进行调用,同时参数后面可以接很多其他的子命令
        latency latest 记录最后的延迟事件的记录。每个事件包含以下几个变量:(事件名、事件延迟状态时间戳、延迟时间ms、此时间最大延迟)
127.0.0.1:6379> latency latest
1) 1) "command"                         #事件为command
2) (integer) 1466059344           #2016-6-16 14:42:24
3) (integer) 250                         #延迟时间0.25s
4) (integer) 1000                       #command事件延迟最大时间为1s

latency history events 此命令可以打印相应延迟事件相关的时间和耗时
127.0.0.1:6379> latency history command
1) 1) (integer) 1466059051
2) (integer) 10
2) 1) (integer) 1466059324
2) (integer) 13
3) 1) (integer) 1466059332
2) (integer) 1000
4) 1) (integer) 1466059344
2) (integer) 250

latency reset cevents 重置事件的相关延迟操作,清空记录
127.0.0.1:6379> latency reset command
(integer) 1
127.0.0.1:6379> latency graph command
command - high 700 ms, low 100 ms (all time high 700 ms)
--------------------------------------------------------------------------------
o#
_#||
o||||
_#|||||

2222111
6421961
sssssss

另外,一般情况下大量的删除,过期以及淘汰(由maxmemory-policy控制的)的大对象,也会造成redis阻塞,进而造成相应的延迟。如果经常有比较大的对象进行删除,过期和淘汰的,建议将这些对象分割成一些小对象。即对比较大的key进行拆分


6.持久化对延迟造成的影响
一般情况来说,持久话的也会影响延迟,因为持久话操作必须对内存中的数据线进行一次save操作。因此必须根据以下相关的参数进行持久性(durability)和延迟/性能(latency/performance)做相应的权衡:
1.AOF + fsync always:这种方式会比较慢一些
2.AOF + fsync every second:这个将是这种的一种方案
3.AOF + fsync every second + no-appendfsync-on-rewrite option set to yes: 比较好的一种方式,但是需要避免在往磁盘同步的时候进行fsync
4.AOF + fsync never. 磁盘压力会比较小
5.RDB.



爱跑步,爱生活,爱技术的逗逼自述。


 
生活马拉松 更多文章 初尝Docker1.12(一) 浅谈redis超时(二)
猜您喜欢 iOS开发最常用的第三方库 美克家居采用IBM面向iOS的MobileFirst零售行业解决方案 变革导购服务客户模式 API 调用次数限制实现 20小时学会编程,他是怎么做到的? 功能分离与功能降级