Мой WebAPI написан с использованием .NET Framework 4.7.2, и я также использую RedisStackChange 2.8.0.
У меня возникла проблема, когда количество ключей в Redis достигло около 7 миллионов. ключи:
StackExchange.Redis.RedisTimeoutException: таймаут выполнения GET (5000 мс), следующий: GET xxx, inst: 15, qu: 0, qs: 3, aw: False, rs: ReadAsync, ws: Idle, вход: 0, входной канал: 0, выходной канал: 132, serverEndpoint: 10.xx.xx.xx:xxxx, mc: 1/1/0, mgr: Доступно 7 из 10, имя клиента: XXXX-XXXX, IOCP: (Занят = 9, Свободен = 991, Мин = 16, Макс = 1000), РАБОЧИЙ: (Занят = 146, Свободен = 32621, Мин = 16, Макс = 32767)
Это приводит к сильному замедлению работы приложения. Чтобы устранить проблему, я увеличил время ожидания с 5 до 30 секунд (Redis и API используют один и тот же сервер – 48 ГБ ОЗУ).
Интересно, есть ли лучший способ справиться с этим?
Я впервые задаю вопрос, спасибо за чтение
Это сокращенная версия моего кода:
public class RedisClient : IDisposable
{
private ConnectionMultiplexer _connection;
public RedisClient()
{
Connect();
}
public void Connect()
{
var configuration = ConfigurationOptions.Parse(ConfigurationManager.AppSettings["REDIS_CONN_STRING"]);
_connection = ConnectionMultiplexer.Connect(configuration);
}
public static RedisClient GetReConnectInstance()
{
if (_redisClient == null)
{
_redisClient = new RedisClient();
}
return _redisClient;
}
private static RedisClient _redisClient;
public static RedisClient GetInstance()
{
if (_redisClient == null)
{
_redisClient = new RedisClient();
}
return _redisClient;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
Close();
}
}
}
public class RedisCacheManager
{
private IDatabase _db;
private IMinvoiceDbContext _minvoiceDbContext;
public RedisCacheManager(IMinvoiceDbContext minvoiceDbContext)
{
_minvoiceDbContext = minvoiceDbContext;
try
{
RedisClient redisClient = RedisClient.GetInstance();
_db = redisClient.Database();
}
catch (Exception ex)
{
Log.Error("RedisCacheManager", ex);
ReconnectDB();
}
}
private void ReconnectDB()
{
try
{
RedisClient redisClient = RedisClient.GetReConnectInstance();
_db = redisClient.Database();
}
catch (Exception ex)
{
Log.Error("ReconnectDB", ex);
}
}
public async Task Get(string key)
{
T rs = default(T);
try
{
var rValue = await _db.StringGetAsync(key);
if (!rValue.HasValue)
return default(T);
rs = Deserialize(rValue);
}
catch (RedisConnectionException ex)
{
Log.Error($"Get: {key}", ex);
ReconnectDB();
}
catch (Exception ex)
{
Log.Error("Get", ex);
}
return rs;
}
}
// WHEN I USE REDIS
RedisCacheManager cacheManager = new RedisCacheManager(_minvoiceDbContext);
string old = await cacheManager.Get(CacheKeyManager.CHECK_TAX_CODE_OLD);
Подробнее здесь: https://stackoverflow.com/questions/790 ... er-of-keys