#c# #linq #caching #memcached #membase
#c# #linq #кэширование #memcached #membase
Вопрос:
Я только что установил membase и клиент enyim для .NET и наткнулся на статью, в которой упоминается этот метод интеграции linq:
public static IEnumerable<T> CachedQuery<T>
(this IQueryable<T> query, MembaseClient cache, string key) where T : class
{
object resu<
if (cache.TryGet(key, out result))
{
return (IEnumerable<T>)resu<
}
else
{
IEnumerable<T> items = query.ToList();
cache.Store(StoreMode.Set, key, items);
return items;
}
}
Сначала он проверит, находятся ли требуемые данные в кэше, и, если они не кэшируются, вернет их.
В настоящее время я использую a Dictionary<'String, List'>
в своем приложении и хочу заменить его подходом типа membase / memcached.
Как насчет аналогичного шаблона для добавления элементов в список <‘T’> или использования операторов Linq в кэшированном списке? Мне кажется, что было бы плохой идеей хранить весь список<‘T’> в кэше под одним ключом и извлекать его, добавлять к нему, а затем переустанавливать его каждый раз, когда вы хотите добавить элемент. Или это приемлемая практика?
public bool Add(T item)
{
object list;
if (cache.TryGet(this.Key, out list))
{
var _list = list as List<T>;
_list.Add(item);
return cache.Store(StoreMode.Set, this.Key, _list);
}
else
{
var _list = new List<T>(new T[] { item });
return cache.Store(StoreMode.Set, this.Key, _list);
}
}
Как обычно обрабатываются коллекции в подобной ситуации кэширования? Вместо этого обычно используются алгоритмы хеширования или какая-то система с префиксом ключа для идентификации «списков» типа T в хранилище ключей-значений кэша?
Ответ №1:
Это зависит от нескольких факторов: должно ли это быть масштабируемым? Зависит ли этот список от пользователя, и вы можете быть уверены, что «Добавить» не будет вызываться дважды одновременно для одного и того же списка? — Условия гонки представляют риск.
Я реализовал такую вещь, когда я сохранил общий список в membase, но он зависит от пользователя, поэтому я могу быть уверен, что условия гонки не будет.
Вы также должны учитывать объем сериализованного списка, который может быть большим. В моем случае списки были довольно маленькими.
Не уверен, поможет ли это, но я реализовал очень простой итеративный список с произвольным доступом через membase (через двойное косвенное обращение). Произвольный доступ осуществляется с помощью составного ключа (который состоит из нескольких полей).
Вам необходимо:
- Имейте ключ, который содержит длину списка.
- Иметь возможность создавать составной ключ (например, одно или несколько полей из вашего объекта).
- Укажите значение, которое вы хотите сохранить (например, другое поле).
Например:
list_length = 3
префикс1_0-> префикс2_[поле 1.значение][поле 2.значение][Поле 3.значение] -> поле 4.значение
префикс1_1-> префикс2_[поле 1.значение][поле 2.значение][Поле 3.значение] -> поле 4.значение
префикс1_2-> префикс2_[поле 1.значение][поле 2.значение][Поле 3.значение] -> поле 4.значение
Для выполнения последовательного доступа вы перебираете ключи с «prefix1». Для выполнения произвольного доступа вы используете ключи с «prefix2» и поля, которые составляют ключ.
Надеюсь, это достаточно понятно.