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

Я разрабатываю утилиту командной строки Python, которая потенциально включает довольно большие запросы к набору файлов. Это достаточно ограниченный список запросов (например, индексированные столбцы БД). Чтобы повысить производительность в процессе, я могу сгенерировать отсортированные / структурированные списки, карты и деревья по одному разу и выполнять их неоднократно, вместо того, чтобы каждый раз попадать в файловую систему.

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

Требования:

  • Должно быть быстрым - любая обработка каждого выполнения должна быть сведена к минимуму, включая дисковый ввод-вывод и конструкцию объекта.
  • Должно быть независимым от ОС (или, по крайней мере, иметь возможность подключаться к аналогичным базовым поведениям в Unix/Windows, что более вероятно).
  • Необходимо разрешить достаточно сложные запросы / фильтрацию - я не думаю, что карта ключ / значение будет достаточно хорошей
  • Не нуждается в обновлении - (кратко) устаревшие данные в порядке, это просто кэш, фактические данные записываются на диск отдельно.
  • Не могу использовать тяжелый демон-процесс, такой как MySQL или MemCached - я хочу минимизировать затраты на установку, и просить каждого пользователя устанавливать эти сервисы - это слишком много.

Предпочтения:

  • Я хотел бы избежать какого-либо рода долго работающего процесса демона, если это возможно.
  • Хотя я хотел бы иметь возможность быстро обновлять кэш, перестройка всего кэша при обновлении - это не конец света, быстрое чтение гораздо важнее, чем быстрое чтение.

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

Кандидаты:

  • SQLite в памяти

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

  • База данных плоских файлов загружена в память с помощью mmap

    На противоположном конце спектра я мог бы записать кеши на диск, затем загрузить их в память с помощью mmap, чтобы разделить одно и то же пространство памяти между отдельными выполнениями. Мне не ясно, что произойдет с mmap, если все процессы завершатся. Это нормально, если mmap в конечном итоге очищается от памяти, но я бы хотел, чтобы он немного задерживался (30 секунд, несколько минут), чтобы пользователь мог запускать команды одну за другой, и кэш можно использовать повторно. Этот пример, кажется, подразумевает, что должен быть открытый дескриптор mmap, но я не нашел точного описания того, когда отображенные в память файлы удаляются из памяти и должны быть перезагружены с диска.

    Я думаю, что я мог бы реализовать это, если объекты mmap действительно остаются после выхода, но он чувствует себя очень низким уровнем, и я предполагаю, что кто-то уже реализовал более элегантное решение. Я бы не хотел начинать строить это только для того, чтобы понять, что я перестраиваю SQLite. С другой стороны, такое ощущение, что это будет очень быстро, и я мог бы провести оптимизацию, учитывая мой конкретный вариант использования.

  • Совместное использование объектов Python между процессами с использованием Processing

    Пакет "Обработка" указывает " Объекты могут быть разделены между процессами с использованием... общей памяти". Просматривая остальные документы, я больше не видел упоминаний об этом поведении, но это звучиточень многообещающе. Кто-нибудь может направить меня к дополнительной информации?

  • Хранить данные на диске RAM

    Моя проблема здесь связана с возможностями ОС, но я мог бы создать RAM-диск, а затем просто читать / писать на него, как мне угодно (SQLite?). Пакет fs.memoryfs кажется многообещающей альтернативой для работы с несколькими ОС, но комментарии подразумевают немало ограничений.

Я знаю, что pickle- это эффективный способ хранения объектов Python, поэтому он может иметь преимущества в скорости по сравнению с любым типом ручного хранения данных. Могу ли я подключить засолку к любому из перечисленных выше вариантов? Будет ли это лучше, чем плоские файлы или SQLite?

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

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

Спасибо большое за вашу помощь!

1 ответ

Решение

Я просто сделал бы самую простую вещь, которая могла бы работать.... который в вашем случае, скорее всего, будет просто в дамп файл. Если вы обнаружите, что это недостаточно быстро, попробуйте что-нибудь более сложное (например, memcached или SQLite). Дональд Кнут говорит: "Преждевременная оптимизация - корень всего зла"!

Другие вопросы по тегам