Словарь, который может сохранять свои элементы, реже получаемые на диске

В моем приложении я использую словарь (поддерживающий добавление, удаление, обновление и поиск), где оба ключа и значения могут быть или могут быть сериализованы (значения могут быть довольно крупными объектными графами). Я пришел к тому, что словарь стал настолько большим, что его полностью в памяти начали иногда запускать OutOfMemoryException (иногда в словарных методах, а иногда и в других частях кода).

После попытки полностью заменить словарь базой данных производительность снизилась до неприемлемого уровня.

Анализ шаблонов использования словаря показал, что обычно меньшая часть значений является "горячей" (к ней часто поступают), а остальные (большая часть) "холодны" (редко или никогда не обращаются). Трудно сказать, когда добавляется новое значение, если оно будет горячим или холодным, более того, некоторые значения могут перемещаться вперед и назад между горячими и холодными частями с течением времени.

Я думаю, что мне нужна реализация словаря, способного сбросить свои холодные значения на диск при событии с низкой памятью, а затем перезагрузить некоторые из них по требованию и сохранить их в памяти до тех пор, пока не произойдет следующее событие с низкой памятью когда их статус "горячий/холодный" будет пересмотрен. В идеале, реализация должна аккуратно регулировать размеры его горячих и холодных деталей и интервал смыва в зависимости от профиля использования памяти в приложении, чтобы максимизировать общую производительность. Поскольку в приложении существует несколько экземпляров словаря (с разными типами ключей/значений), им может потребоваться скоординировать их рабочие процессы.

Не могли бы вы предложить, как реализовать такой словарь?

Ответы

Ответ 1

Компилировать для 64-битного, развернуть на 64-битной, добавить память. Храните его в памяти.

Прежде чем вы вырастите свой собственный, вы также можете взглянуть на WeakReference http://msdn.microsoft.com/en-us/library/ms404247.aspx. Разумеется, это потребует от вас восстановления тех объектов, которые были исправлены, но следует надеяться, что те, кто исправлен, мало используются. Это связано с предостережением о том, что его собственные принципы не позволяют использовать слабые ссылки как автоматическое решение проблем управления памятью. Вместо этого создайте эффективную политику кэширования для обработки ваших объектов приложения.

Конечно, вы можете игнорировать это руководство и эффективно работать над своим кодом для его учета.

Вы можете реализовать политику кэширования и по истечении срока действия сохранить в базу данных, получить выборки и кеш. Разумеется, используйте скользящий срок действия, так как вы заинтересованы в сохранении тех, кто больше всего используется.

Помните, однако, что большинство использованных против самых тяжелых - это компромисс. Потеря объекта 10 раз в день, что требуется 5 минут для восстановления, будет раздражать пользователей гораздо больше, чем потерять объект 10000 раз, для восстановления которого требуется всего 5 мс.

И кто-то выше упоминал веб-кеш. Это автоматическое управление памятью с обратными вызовами, как указано, зависит от того, хотите ли вы их обмануть в своих приложениях.

И... последнее, но не менее важное: посмотрите на распределенный кеш. С помощью sharding вы можете разбить этот большой словарь на несколько машин.

Ответ 2

Просто идея - никогда не делала этого и никогда не использовала System.Runtime.Caching:

Внедрите обертку вокруг MemoryCache, которая будет:

  • Добавить элементы с указанным обратным вызовом выселения. Обратный вызов помещает выведенные элементы в базу данных.
  • Извлечь элемент из базы данных и вернуть обратно в MemoryCache, если элемент отсутствует в MemoryCache во время извлечения.
  • Если вы ожидаете большого количества запросов к элементам, отсутствующим как в базе данных, так и в памяти, вам, вероятно, потребуется реализовать либо фильтр цветения, либо кеш-ключи для существующих/отсутствующих элементов.

Ответ 3

У меня аналогичная проблема в прошлом.

Концепция, которую вы ищете, - это кэш чтения с очередью LRU (наименее используемым или наиболее часто используемым).

Есть ли там реализация LRU IDictionary?

Как вы добавляете в свой словарь слова, отслеживайте, какие из них используются в последнее время, удаляйте их из памяти и сохраняйте на диске.