Я выполняю много очень медленных вычислений с возможностью многократного использования результатов (и часто вычисление чего-то нового зависит от вычислений, которые уже были выполнены ранее).Чтобы использовать их, я хочу хранить результаты где-то (постоянно).Вычисления могут быть однозначно идентифицированы двумя идентификаторами: именем эксперимента и именем вычисления, а значением является массив чисел с плавающей запятой (которые в настоящее время я храню в виде необработанных двоичных данных).К ним нужно обращаться по отдельности (читать и писать) очень часто по эксперименту и названию вычислений, а иногда и просто по названию эксперимента (то есть во всех вычислениях с их результатами для данного эксперимента).Они также иногда объединяются, но если чтение и запись выполняются быстро, дополнительная поддержка этой операции не требуется.К этим данным не нужно будет обращаться ни к какому веб-приложению (используется только непроизводственными сценариями, которым нужны результаты вычислений, но вычислять их каждый раз невозможно), и нет необходимости в транзакциях, но каждая запись требуетбыть атомарным (например, выключение компьютера не должно приводить к поврежденным / частичным данным).Чтение также должно быть атомарным (например, если два процесса пытаются получить доступ к результату одного вычисления, а его там нет, поэтому один из них начинает сохранять новый результат, другой процесс должен либо получить его по завершении, либо ничего не получить привсе).Удаленный доступ к данным не требуется, но полезен.
Итак, требования TL; DR:
- постоянное хранение двоичных данных (не нужно хранить метаданные, кроме идентификатора)
- очень быстрый доступ (чтение/ запись) на основе составного идентификатора
- возможность чтения всех данных по одной части составного идентификатора
- одновременное, атомарное чтение / запись
- нет необходимости в сложных транзакцияхзапросы и т. д.
- было бы неплохо иметь удаленный доступ, но не обязательно
- все это в основном для экономии времени, поэтому скорость имеет решающее значение
Решения, которые я до сих пор пробовал:
- сохранение их как отдельных файлов (один каталог на эксперимент, один двоичный файл на вычисления) - требует ручной обработки атомарности, а также большинство файловых систем поддерживают только имена файловдлиной до 255 символов (а имена вычислений могут быть длиннее), поэтому потребуется дополнительное отображение;также я не уверен, что ext4 (которая является файловой системой, которую я использую и не могу изменить) предназначена для обработки миллионов файлов
- с использованием базы данных sqlite (только с одной таблицей и составным первичнымключ) - сначала это казалось идеальным, но когда мы получили сотни гигабайт данных (миллионы блобов ~ 100 КБ, и их число, и их размер увеличатся), это стало очень медленно, даже после применения найденных оптимизацийв интернете
Естественно, после сбоя sqlite первой идеей было просто перейти на «правильную» базу данных, такую как postgres, но потом я понял, что, возможно, в этом случае реляционная база данных не совсемпуть (особенно потому, что скорость здесь критична, и мне не нужны большинство их функций) - и особенно postgres, вероятно, не тот путь, так как ближайший объект к BLOB-объекту - это bytea, который требует дополнительных преобразований (поэтомухит производительности гарантирован).Тем не менее, после небольшого исследования баз данных значения ключа (что, похоже, относится к моей проблеме), я обнаружил, что все проверенные базы данных не поддерживают составные ключи и часто имеют ограничения по длине для ключей (например, у couchbase есть только250 байт).Итак, я должен просто пойти с нормальной реляционной базой данных, попробовать одну из баз данных NoSQL, или, может быть, что-то совершенно другое, как HDF5?