第一个redis应用方法导致的提示redis LRANGE命令超时问题的解决
2017-06-19 16:08
585 查看
我的第一个redis应用的方法代码如下:
此方法在使用中通过对服务器的监察,发现cpu从原来的1%左右飙升到40-50%。而且在错误日志出现了大量有关redis超时提示。错误提示代码如下:
Timeout performing LRANGE Redis:QuestionsLibraryList, inst: 7, queue: 8, qu: 0, qs: 8, qc: 0, wr: 0, wq: 0, in: 2944, ar: 0, clientName: iZ25f3l6awvZ, serverEndpoint: 127.0.0.1:8383, keyHashSlot: 3349, IOCP: (Busy=1,Free=799,Min=8,Max=800), WORKER: (Busy=9,Free=791,Min=8,Max=800)
(Please take a look at this article for some common client-side issues that can cause timeouts: http://stackexchange.github.io/StackExchange.Redis/Timeouts)
可以确认这个都是页面调用RedisHelper.ListRange这个方法引起的。从网上扒的资料来看,redis是单进程,单线程的。也就是说,短时间内网站向redis服务发出了大量的ListRange指令。由于指令是在队列中一条一条处理的。导致后面的指令得不到处理。
我又到服务器上打开cmd窗口,然后进入redis命令后输入:
SLOWLOG GET
然后发觉最近的超时命令都是LRANGE,而且每条都超过了10几秒。但我很疑惑,因为我的RedisHelper类是单例连接,使用的都是静态方法和静态属性,静态变量。难道是我使用的GetRedisQuestionsLibraryList() 不是静态方法的缘故?这不科学啊,虽然我这个方法是实例方法。可是这个方法中自redis服务中获取值的方法确实实实在在的静态方法啊。这令我很凌乱,在网上扒资料,并没有找到这块有用的东西。但问题还是要解决。因为没有理论佐证,只好进行尝试。于是我把此方法改为静态属性的形式代码:
然后修改相关调用代码,编译,上传到服务器上进行测试。结果出现了大量的redis的Timeout performing LRANGE Redis超时提示。和原来的错误一样。果断修改为静态方法形式进行测试,代码如下:
修改相关调用代码,编译,上传服务器测试,仍然是哪个错误提示。我表示很无语。马上再换,这次换为静态变量的形式,代码如下:
上传上去后,观察网站cpu的使用。又观察错误日志代码。经过一个多小时的跟踪,这次没发现cpu使用大幅上扬的情况,也没发现超时错误。这算是解决了。可是我很无语,你说实例方法调用,会出现大量排队现象,怎么静态方法及静态属性这两种获取方法也出现大量redis排队现象。概念理解的不透么,也只能这样说了。
扒了扒资料也就找到一个似乎能解释通的。提到了静态变量的初始化及赋值。
1、任何带有初始值设定项的静态字段,则在执行该类的静态构造函数时,先要按照文本顺序执行那些初始值设定项
2、如果没有编写静态构造函数,而这时类中包含带有初始值设定的静态字段,那么编译器会自动生成默认的静态构造函数
3、类的静态构造函数在给定应用程序域中至多执行一次:只有创建类的实例或者引用类的任何静态成员才激发静态构造函数
这意味着我上面所写的静态变量的赋值方法,其实在C#的编译器中是自动创建的静态构造函数中完成的赋值操作,并且只执行了一次。。
静态方法及静态属性按我以前的理解,它是所有该类的实例方法都可以使用的,并且在这里的话这个静态方法或者静态属性只调用一次Redis中的LRANGE命令。然而从测试的情况来看,它和实例方法一样,每次使用都要调用一次Redis中的LRANGE命令。我又对静态方法及静态属性的理论解释深入挖掘,发现了一个有意思的解释,就是它是一系列行为的组合。是一个action,也就是动作。那这也意味着每次调用的时候,它里面的一系列操作都要执行一遍。这样就解释通了。由于每次调用静态属性和静态方法,里面的操作都要执行,那自然对Redis的LRANGE命令进行了多次调用操作。然后导致了redis报超时错误。而静态变量由于赋值就进行了一次,也就是Redis的LRANGE命令只调用了一次,所以不会遇到由于大量调用造成超时的问题
public List<QuestionsLibrary> GetRedisQuestionsLibraryList() { var qlist = RedisHelper.ListRange<QuestionsLibrary>(RedisKey.RedisQuestionsLibraryList); if (qlist == null || qlist.Count() <= 0) { List<QuestionsLibrary> list = new QuestionsLibraryService().GetNolock(m => true).ToList(); RedisHelper.ListRightPush(RedisKey.RedisQuestionsLibraryList, list); return list; } else { return RedisHelper.ListRange<QuestionsLibrary>(RedisKey.RedisQuestionsLibraryList); } }
此方法在使用中通过对服务器的监察,发现cpu从原来的1%左右飙升到40-50%。而且在错误日志出现了大量有关redis超时提示。错误提示代码如下:
Timeout performing LRANGE Redis:QuestionsLibraryList, inst: 7, queue: 8, qu: 0, qs: 8, qc: 0, wr: 0, wq: 0, in: 2944, ar: 0, clientName: iZ25f3l6awvZ, serverEndpoint: 127.0.0.1:8383, keyHashSlot: 3349, IOCP: (Busy=1,Free=799,Min=8,Max=800), WORKER: (Busy=9,Free=791,Min=8,Max=800)
(Please take a look at this article for some common client-side issues that can cause timeouts: http://stackexchange.github.io/StackExchange.Redis/Timeouts)
可以确认这个都是页面调用RedisHelper.ListRange这个方法引起的。从网上扒的资料来看,redis是单进程,单线程的。也就是说,短时间内网站向redis服务发出了大量的ListRange指令。由于指令是在队列中一条一条处理的。导致后面的指令得不到处理。
我又到服务器上打开cmd窗口,然后进入redis命令后输入:
SLOWLOG GET
然后发觉最近的超时命令都是LRANGE,而且每条都超过了10几秒。但我很疑惑,因为我的RedisHelper类是单例连接,使用的都是静态方法和静态属性,静态变量。难道是我使用的GetRedisQuestionsLibraryList() 不是静态方法的缘故?这不科学啊,虽然我这个方法是实例方法。可是这个方法中自redis服务中获取值的方法确实实实在在的静态方法啊。这令我很凌乱,在网上扒资料,并没有找到这块有用的东西。但问题还是要解决。因为没有理论佐证,只好进行尝试。于是我把此方法改为静态属性的形式代码:
protected static List<QuestionsLibrary> RedisQuestionsLibraryList { get { var qlist = RedisHelper.ListRange<QuestionsLibrary>(LMSoft.WebCommon.RedisKey.RedisQuestionsLibraryList); if (qlist == null || qlist.Count() <= 0) { List<QuestionsLibrary> list = new QuestionsLibraryService().GetNolock(m => true).ToList(); RedisHelper.ListRightPush(LMSoft.WebCommon.RedisKey.RedisQuestionsLibraryList, list); return list; } else { return qlist; } } }
然后修改相关调用代码,编译,上传到服务器上进行测试。结果出现了大量的redis的Timeout performing LRANGE Redis超时提示。和原来的错误一样。果断修改为静态方法形式进行测试,代码如下:
protected static List<QuestionsLibrary> GetRedisQuestionsLibraryList() { var qlist = RedisHelper.ListRange<QuestionsLibrary>(LMSoft.WebCommon.RedisKey.RedisQuestionsLibraryList); if (qlist == null || qlist.Count() <= 0) { List<QuestionsLibrary> list = new QuestionsLibraryService().GetNolock(m => true).ToList(); RedisHelper.ListRightPush(LMSoft.WebCommon.RedisKey.RedisQuestionsLibraryList, list); return list; } else { return qlist; } }
修改相关调用代码,编译,上传服务器测试,仍然是哪个错误提示。我表示很无语。马上再换,这次换为静态变量的形式,代码如下:
protected static List<QuestionsLibrary> RedisQuestionsLibraryList = getRedisQuestionsLibraryList(); private static List<QuestionsLibrary> getRedisQuestionsLibraryList() { var qlist = RedisHelper.ListRange<QuestionsLibrary>(LMSoft.WebCommon.RedisKey.RedisQuestionsLibraryList); if (qlist == null || qlist.Count() <= 0) { List<QuestionsLibrary> list = new QuestionsLibraryService().GetNolock(m => true).ToList(); RedisHelper.ListRightPush(LMSoft.WebCommon.RedisKey.RedisQuestionsLibraryList, list); return list; } else { return qlist; } }
上传上去后,观察网站cpu的使用。又观察错误日志代码。经过一个多小时的跟踪,这次没发现cpu使用大幅上扬的情况,也没发现超时错误。这算是解决了。可是我很无语,你说实例方法调用,会出现大量排队现象,怎么静态方法及静态属性这两种获取方法也出现大量redis排队现象。概念理解的不透么,也只能这样说了。
扒了扒资料也就找到一个似乎能解释通的。提到了静态变量的初始化及赋值。
1、任何带有初始值设定项的静态字段,则在执行该类的静态构造函数时,先要按照文本顺序执行那些初始值设定项
2、如果没有编写静态构造函数,而这时类中包含带有初始值设定的静态字段,那么编译器会自动生成默认的静态构造函数
3、类的静态构造函数在给定应用程序域中至多执行一次:只有创建类的实例或者引用类的任何静态成员才激发静态构造函数
这意味着我上面所写的静态变量的赋值方法,其实在C#的编译器中是自动创建的静态构造函数中完成的赋值操作,并且只执行了一次。。
静态方法及静态属性按我以前的理解,它是所有该类的实例方法都可以使用的,并且在这里的话这个静态方法或者静态属性只调用一次Redis中的LRANGE命令。然而从测试的情况来看,它和实例方法一样,每次使用都要调用一次Redis中的LRANGE命令。我又对静态方法及静态属性的理论解释深入挖掘,发现了一个有意思的解释,就是它是一系列行为的组合。是一个action,也就是动作。那这也意味着每次调用的时候,它里面的一系列操作都要执行一遍。这样就解释通了。由于每次调用静态属性和静态方法,里面的操作都要执行,那自然对Redis的LRANGE命令进行了多次调用操作。然后导致了redis报超时错误。而静态变量由于赋值就进行了一次,也就是Redis的LRANGE命令只调用了一次,所以不会遇到由于大量调用造成超时的问题
相关文章推荐
- Word提示:“向程序发送命令时出现问题”解决方法
- Word提示:“向程序发送命令时出现问题”解决方法
- 解决curl超时导致应用崩溃的问题
- 解决curl超时导致应用崩溃的问题
- Win8系统打开excel提示“向程序发送命令时出现问题”的解决方法
- SELinux导致无法访问外网,PHP连接MySQL异常Can't connect to MySQL server、redis程序访问提示Redis server went away的解决方法
- 共享一文件夹提示"服务器存储空间不足,无法处理此命令"的问题解决方法
- adb install命令安装含有中文名apk提示INSTALL_FAILED_INVALID_URI问题解决方法
- 编译android源码提示/usr/bin/jar命令不存在问题的解决方法
- Tomcat中应用调用Libvirt库进行控制时可能导致线程卡死问题的解决方法
- STM32的串口函数_库函数USART_SendData问题和解决方法--硬件复位导致第一个字节丢失
- 解决AJAX应用,会话超时(Session Timeout)的问题,粗略方法(不考虑使用Filter的前提下)
- Android应用第一次安装成功点击“打开”后Home键切出应用后再点击桌面图标返回导致应用重启问题的解决方法
- 问题描述: 安装&重启完成后,我输入命令xm list,提示错误 xm list Can't find hypervisor information in sysfs 解决方法: # mv /
- 安装Tomcat时候提示因无法写入服务而导致无法安装问题的解决方法
- cygwin中运行命令提示command not found的解决方法
- C# using System.Xml.Linq;提示没有命令空间问题解决
- [整合]DB2表锁定解决方法【主要还是程序问题导致的锁表】
- Java 应用显示中文乱码问题的解决方法
- Redhat7对于ifconfig命令问题的解决方法