【发布时间】:2018-10-09 13:28:55
【问题描述】:
我正在运行许多具有可重用结果的非常慢的计算(并且通常计算新的东西依赖于之前已经执行的计算)。为了利用它们,我想将结果存储在某个地方(永久)。计算可以由两个标识符唯一标识:实验名称和计算名称,其值是一个浮点数组(我目前将其存储为原始二进制数据)。它们需要经常通过实验和计算名称单独访问(读取和写入),有时还需要通过实验名称(即给定实验的所有计算及其结果)。它们有时也被连接起来,但如果读写速度很快,则不需要额外支持此操作。任何 Web 应用程序都不需要访问此数据(仅由需要计算结果的非生产脚本使用,但每次都计算它们是不可行的),并且不需要事务,但每次写入都需要是原子的(例如,关闭计算机不应导致数据损坏/部分数据)。读取也需要是原子的(例如,如果两个进程试图访问一个计算的结果,但它不存在,所以其中一个开始保存新结果,另一个进程应该在完成时接收它,或者在全部)。远程访问数据不是必需的,但很有帮助。
所以,TL;DR 要求:
- 二进制数据的永久存储(不需要存储标识符以外的元数据)
- 基于复合标识符的快速访问(读/写)
- 能够通过复合标识符的一部分读取所有数据
- 并发、原子读/写
- 无需事务、复杂查询等。
- 远程访问很不错,但不是必需的
- 整个过程主要是为了节省时间,所以速度很关键
目前我尝试的解决方案是:
- 将它们存储为单独的文件(每个实验一个目录,每个计算一个二进制文件) - 需要手动处理原子性,而且大多数文件系统仅支持最长 255 个字符的文件名(计算名称可能比这更长),因此需要额外的映射;我也不确定 ext4(这是我正在使用的文件系统并且无法更改它)是否旨在处理数百万个文件
- 使用 sqlite 数据库(只有一个表和一个复合主键) - 起初它看起来很完美,但是当我们获得数百 GB 的数据(数百万 ~ 100 KB 的 blob,以及它们的数量和它们的大小会增加),它开始变得非常慢,即使在应用了互联网上的优化之后
当然,在 sqlite 失败后,第一个想法就是转移到像 postgres 这样的“适当”数据库,但后来我意识到,在这种情况下,关系数据库可能并不是真正要走的路(尤其是因为速度很关键在这里,我不需要它们的大部分功能)-尤其是 postgres 可能不是要走的路,因为最接近 blob 的是 bytea,它需要额外的转换(因此可以保证性能命中)。然而,在研究了一些关于键值数据库(这似乎适用于我的问题)之后,我发现我检查的所有数据库都不支持复合键,并且通常对键有长度限制(例如,couchbase 刚刚250 字节)。那么,我应该只使用普通的关系数据库,尝试使用 NoSQL 数据库之一,还是像 HDF5 这样完全不同的数据库?
【问题讨论】:
标签: database performance storage