Mik*_*sen 5 redis stackexchange.redis
我正在尝试使用StackExchange Redis库跟踪间歇性的"突发"超时.以下是我们的设置:我们的API是用C#编写的,可以在Windows 2008和IIS上运行.我们有4台API服务器在生产中,我们有4台Redis机器(运行Linux最新LTS),每台机器有2个Redis实例(一个主机在端口7000上,一个从机在端口7001上).我几乎看过Redis服务器的各个方面,看起来很棒.日志,CPU和网络中的错误都不是很好,服务器方面的一切看起来都很棒.我可以tail -f在发生这种情况时使用Redis记录并且看不到任何异常(例如重写AOF文件或任何其他内容).我认为问题不在于Redis.
这是我目前所知道的:
这是一个示例超时异常.大多数看起来与此基本相同:
Type = StackExchange.Redis.RedisTimeoutException,Message = Timeout执行GET limeade:allActivities,inst:1,mgr:ExecuteSelect,err:never,queue:0,qu:0,qs:0,qc:0,wr:0,wq :0,in:0,ar:0,clientName:LIMEADEAPI4,serverEndpoint:10.xx.xx.11:7000,keyHashSlot:1295,IOCP :( Busy = 0,Free = 1000,Min = 2,Max = 1000) ,WORKER :(忙碌= 9,自由= 32758,最小值= 2,最大值= 32767)(请查看本文,了解可能导致超时的一些常见客户端问题:http: //stackexchange.github.io/ StackExchange.Redis /超时),堆栈跟踪= 在StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl [T](消息消息,ResultProcessor
1 processor, ServerEndPoint server) at StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl[T](Message message, ResultProcessor1个处理器,ServerEndPoint服务器)在StackExchange.Redis.RedisBase.ExecuteSync [T](消息消息,ResultProcessor1 processor, ServerEndPoint server) at StackExchange.Redis.RedisDatabase.StringGet(RedisKey key, CommandFlags flags) at Limeade.Caching.Providers.RedisCacheProvider1.Get [T](K cacheKey,CacheItemVersion和cacheItemVersion)在......
我已经做了一些关于追踪这些超时异常的研究,但令人惊讶的是所有数字都是零.队列中没有任何东西,没有等待处理的东西,我有大量的线程免费,没有做任何事情.一切看起来都很棒.
任何人都有任何想法如何解决这个问题?问题是这些缓存超时突发导致我们的数据库受到更多打击,在某些情况下这是一件坏事.我很乐意添加任何人都会发现有用的信息.
更新:连接代码
连接到Redis的代码是支持各种缓存环境和配置的相当复杂的系统的一部分,但我可以将其归结为基础知识.首先,有一个CacheFactory类:
public class CacheFactory : ICacheFactory
{
private static readonly ILogger log = LoggerManager.GetLogger(typeof(CacheFactory));
private static readonly ICacheProvider<CacheKey> cache;
static CacheFactory()
{
ICacheFactory<CacheKey> configuredFactory = CacheFactorySection.Current?.CreateConfiguredFactory<CacheKey>();
if (configuredFactory == null)
{
// Some error handling, not important
}
cache = configuredFactory.GetDefaultCache();
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
这ICacheProvider是实现与特定缓存系统通信的方式,可以对其进行配置.在这种情况下,configuredFactory是RedisCacheFactory这样的:
public class RedisCacheFactory<T> : ICacheFactory<T> where T : CacheKey, ICacheKeyRepository
{
private RedisCacheProvider<T> provider;
private readonly RedisConfiguration configuration;
public RedisCacheFactory(RedisConfiguration config)
{
this.configuration = config;
}
public ICacheProvider<T> GetDefaultCache()
{
return provider ?? (provider = new RedisCacheProvider<T>(configuration));
}
}
Run Code Online (Sandbox Code Playgroud)
该GetDefaultCache方法在静态构造函数中调用一次,并返回一个RedisCacheProvider.这个类实际连接到Redis:
public class RedisCacheProvider<K> : ICacheProvider<K> where K : CacheKey, ICacheKeyRepository
{
private readonly ConnectionMultiplexer redisConnection;
private readonly IDatabase db;
private readonly RedisCacheSerializer serializer;
private static readonly ILog log = Logging.RedisCacheProviderLog<K>();
private readonly CacheMonitor<K> cacheMonitor;
private readonly TimeSpan defaultTTL;
private int connectionErrors;
public RedisCacheProvider(RedisConfiguration options)
{
redisConnection = ConnectionMultiplexer.Connect(options.EnvironmentOverride ?? options.Connection);
db = redisConnection.GetDatabase();
serializer = new RedisCacheSerializer(options.SerializationBinding);
cacheMonitor = new CacheMonitor<K>();
defaultTTL = options.DefaultTTL;
IEnumerable<string> hosts = options.Connection.EndPoints.Select(e => (e as DnsEndPoint)?.Host);
log.InfoFormat("Created Redis ConnectionMultiplexer connection. Hosts=({0})", String.Join(",", hosts));
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
构造函数基于配置的Redis端点(在某些配置文件中)创建ConnectionMultiplexer.我每次创建连接时都会记录.我们没有看到任何过多的这些日志语句,并且与Redis的连接保持稳定.
在global.asax, 中尝试添加:
protected void Application_Start(object sender, EventArgs e)
{
ThreadPool.SetMinThreads(200, 200);
}
Run Code Online (Sandbox Code Playgroud)
对于我们来说,这将每天的错误从约 50-100 个减少到零。我相信对于要设置的数字没有一般规则,因为它取决于系统(我们可以使用 200),因此可能需要您进行一些实验。
我还相信这提高了网站的性能。
| 归档时间: |
|
| 查看次数: |
291 次 |
| 最近记录: |