Я перемещаю весь существующий кеш-сервер Azure In-Role в Redis и решил использовать предварительный просмотр Azure Redis вместе с библиотекой StackExchange.Redis(https://github.com/StackExchange/StackExchange.Redis). Я написал для него весь код без особых проблем, но при запуске он абсолютно неэффективен и постоянно выдает ошибки таймаута (мой период таймаута установлен на 15 секунд).
Вот соответствующий код того, как я настраиваю соединение Redis и использую его для простых операций:
private static ConnectionMultiplexer _cacheService;
private static IDatabase _database;
private static object _lock = new object();
private void Initialize()
{
if (_cacheService == null)
{
lock (_lock)
{
if (_cacheService == null)
{
var options = new ConfigurationOptions();
options.EndPoints.Add("{my url}", 6380);
options.Ssl = true;
options.Password = "my password";
// needed for FLUSHDB command
options.AllowAdmin = true;
// necessary?
options.KeepAlive = 30;
options.ConnectTimeout = 15000;
options.SyncTimeout = 15000;
int database = 0;
_cacheService = ConnectionMultiplexer.Connect(options);
_database = _cacheService.GetDatabase(database);
}
}
}
}
public void Set(string key, object data, TimeSpan? expiry = null)
{
if (_database != null)
{
_database.Set(key, data, expiry: expiry);
}
}
public object Get(string key)
{
if (_database != null)
{
return _database.Get(key);
}
return null;
}
Выполнение очень простых команд, таких как "Получить" и "Установить часто", или выполнить 5-10 секунд. Похоже, что это сводит на нет всю цель использования его в качестве кеша, если он работает медленнее, чем фактическое получение реальных данных из моей базы данных:)
Я делаю что-то явно неправильное?
Изменить: вот некоторые статистические данные, которые я вытащил с сервера (с помощью Redis Desktop Manager) в случае, если кто-то проливает свет на что-либо.
Server
redis_version:2.8.12
redis_mode:standalone
os:Windows
arch_bits:64
multiplexing_api:winsock_IOCP
gcc_version:0.0.0
process_id:2876
tcp_port:6379
uptime_in_seconds:109909
uptime_in_days:1
hz:10
lru_clock:16072421
config_file:C:\Resources\directory\xxxx.Kernel.localStore\1\redis_2092_port6379.conf
Clients
connected_clients:5
client_longest_output_list:0
client_biggest_input_buf:0
client_total_writes_outstanding:0
client_total_sent_bytes_outstanding:0
blocked_clients:0
Memory
used_memory:4256488
used_memory_human:4.06M
used_memory_rss:67108864
used_memory_rss_human:64.00M
used_memory_peak:5469760
used_memory_peak_human:5.22M
used_memory_lua:33792
mem_fragmentation_ratio:15.77
mem_allocator:dlmalloc-2.8
Persistence
loading:0
rdb_changes_since_last_save:72465
rdb_bgsave_in_progress:0
rdb_last_save_time:1408471440
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:-1
rdb_current_bgsave_time_sec:-1
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
Stats
total_connections_received:25266
total_commands_processed:123389
instantaneous_ops_per_sec:10
bytes_received_per_sec:275
bytes_sent_per_sec:65
bytes_received_per_sec_human:
Изменить 2. Вот методы расширения, которые я использую для Get/Set. Это очень простые методы, которые просто превращают объект в JSON и вызывают StringSet
.
public static object Get(this IDatabase cache, string key)
{
return DeserializeJson<object>(cache.StringGet(key));
}
public static void Set(this IDatabase cache, string key, object value, TimeSpan? expiry = null)
{
cache.StringSet(key, SerializeJson(value), expiry: expiry);
}
Изменить 3: вот несколько примеров сообщений об ошибках:
A first chance exception of type 'System.TimeoutException' occurred in StackExchange.Redis.dll
Timeout performing GET MyCachedList, inst: 11, queue: 1, qu=1, qs=0, qc=0, wr=0/1, in=0/0
A first chance exception of type 'System.TimeoutException' occurred in StackExchange.Redis.dll
Timeout performing GET MyCachedList, inst: 1, queue: 97, qu=0, qs=97, qc=0, wr=0/0, in=3568/0