Кэш Appfabric работает в 4 раза медленнее, чем SQL Server 2008 ??

Я запускаю тест, в котором я сравниваю время выборки в ч/б appfabric и SQL Server 2008 и вижу, что appFabric работает в 4 раза медленнее, чем SQL Server.

У меня есть установка SQL Server 2008, которая содержит только одну таблицу с 4 столбцами (все nvarchar). В таблице 6000 строк. Я вставляю ту же строку (как сериализуемый объект CLR) в кеш appfabric. Я запускаю цикл для получения данных x раз.

Вот код

public class AppFabricCache
{
readonly DataCache myDefaultCache;

public AppFabricCache()
{
//-------------------------
// Configure Cache Client 
//-------------------------

//Define Array for 1 Cache Host
var servers = new List<DataCacheServerEndpoint>(1);

//Specify Cache Host Details 
//  Parameter 1 = host name
//  Parameter 2 = cache port number
servers.Add(new DataCacheServerEndpoint(@"localhost", 22233));

//Create cache configuration
var configuration = new DataCacheFactoryConfiguration();

//Set the cache host(s)
configuration.Servers = servers;

//Set default properties for local cache (local cache disabled)
configuration.LocalCacheProperties = new DataCacheLocalCacheProperties();

//Disable exception messages since this sample works on a cache aside
DataCacheClientLogManager.ChangeLogLevel(System.Diagnostics.TraceLevel.Off);

//Pass configuration settings to cacheFactory constructor
DataCacheFactory myCacheFactory = new DataCacheFactory(configuration);

//Get reference to named cache called "default"
myDefaultCache = myCacheFactory.GetCache("default");
}

public bool TryGetCachedObject(string key, out object value)
{
value = myDefaultCache.Get(key);
bool result = value != null;
return result;
}

public void PutItemIntoCache(string key, object value)
{
myDefaultCache.Put(key, value, TimeSpan.FromDays(365));
}

}

А вот и цикл для получения данных из кеша

public double RunReadStressTest(int numberOfIterations, out int recordReadCount)
{
recordReadCount = 0;
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < numberOfIterations; i++)
{
for (int j = 1; j <= 6000; j++)
{
string posId = "PosId-" + j;
try
{
object value;
if (TryGetCachedObject(posId, out value))
recordReadCount++;
}
catch (Exception e)
{
Trace.WriteLine("AS%% - Exception - " + e.Message);
}
}
}
sw.Stop();
return sw.ElapsedMilliseconds;
}
}

У меня точно такая же логика для получения данных с SQL Server. Это создает

sqlCommand = 'Select * from TableName where posId = 'someId'' 

Вот результаты...

SQL Server 2008 R2  Reading-1(ms)   Reading-2(ms)   Reading-3(ms)   Average Time in Seconds
 Iteration Count = 5    2528              2649            2665                 2.614
 Iteration Count = 10   5280              5445            5343                 5.356
 Iteration Count = 15   7978              8370            7800                 8.049333333
 Iteration Count = 20   9277              9643            10220                9.713333333

AppFabric                 Reading-1         Reading-2   Reading-3   Average Time in Seconds
Iteration Count = 5        10301            10160            10186                10.21566667
Iteration Count = 10       20130            20191            20650                20.32366667
Iteration Count = 15       30747            30571            30647                30.655
Iteration Count = 20       40448            40541            40503                40.49733333

Я что-то упустил здесь? Почему это так медленно?


person user1707312    schedule 28.09.2012    source источник


Ответы (3)


Разница заключается в накладных расходах сети. В вашем примере SQL вы прыгаете по сети один раз и выбираете N строк. В вашем примере с AppFabric вы переходите по сети PER RECORD, а не массово. В этом разница. Чтобы доказать это, временно сохраните свои записи в AppFabric как список и получите только список один раз или используйте массовый API AppFabric, чтобы выбрать их все в одном запросе — это должно объяснить большую часть разницы.

person Haney    schedule 25.05.2013
comment
не думаю, что он это делает: похоже, он извлекает данные построчно: sqlCommand = 'Select * from TableName, где posId = 'someId'' - person Matt Evans; 04.06.2014

Это может быть вызвано встроенной сериализацией .Net.

Сериализация .Net использует отражение, которое, в свою очередь, имеет очень низкую производительность. Я бы рекомендовал изучить использование пользовательского написанного кода сериализации.

person redcalx    schedule 17.12.2012

Я думаю, что ваш тест предвзят, и ваши результаты не оптимальны.

О распределенном кэше

  • Локальный кеш: вы отключили функцию локального кеша. Объекты кэша всегда извлекаются с сервера; сетевой перенос и десериализация имеют свою стоимость.
  • BulkGet: BulkGet повышает производительность при работе с небольшими объектами, например при извлечение множества объектов размером от 1 до 5 КБ или меньше.
  • Без сжатия данных: без сжатия между клиентами AppFabric и Cache. Проверьте это.

О вашем тесте

Еще одна важная вещь заключается в том, что вы не тестируете одно и то же: с одной стороны вы тестируете SELECT *, а с другой стороны вы тестируете N x GET ITEM.

person Cybermaxs    schedule 05.10.2012
comment
Я не думаю, что вы использовали d-cache раньше. Просто знать некоторые вещи недостаточно. ››Если я включу локальный кеш, это будет несправедливый тест. ››Массовое получение — я мог бы сделать то же самое и для SQL-сервера, и я почти уверен, что это было бы значительно быстрее. Sql Server ненавидит не что иное, как просто получение одной строки. ››Зачем мне включать сжатие только для 6k записей? каждый с хранилищем только 4 строк. - person user1707312; 05.10.2012
comment
@ user1707312 Я не понимаю вашего комментария. могли бы вы объяснить ? Я не мастер AppFabric. Я использовал его с одного года. Если вы использовали d-cache раньше, вы также должны знать, что использование d-cache направлено не на повышение производительности, а на масштабируемость. Нагрузочное тестирование в цикле for на одном клиенте с одной таблицей данных — не лучший подход. - person Cybermaxs; 05.10.2012
comment
забыть - это позволяет не попасть в него. Кстати, с точки зрения производительности попробуйте сравнить AppFabric с Memcache/Couchbase. - person user1707312; 05.10.2012
comment
@user1707312 user1707312 Ваш сценарий тоже неясен. Также добавьте тест сервера sql и данные (6000 строк в порядке, но что находится внутри каждой строки). Для эффективного D-кэширования вы должны классифицировать свои данные и использовать соответствующий шаблон доступа. Исходя из моего прошлого опыта, самое сложное в кэшировании (локальном или распределенном) — найти наилучшую степень детализации. - person Cybermaxs; 05.10.2012
comment
Я получил лучший ответ в форме MSDN. social.msdn.microsoft. com/Forums/en-US/velocity/thread/ - person user1707312; 09.10.2012
comment
Эй, пользователь 1707312, можешь написать ответ здесь и отметить его как отвеченный. - person garfbradaz; 17.12.2012