在啥时候将大量结构化数据存储为 BLOB 才有意义?
Posted
技术标签:
【中文标题】在啥时候将大量结构化数据存储为 BLOB 才有意义?【英文标题】:At which point does storing a large amount of structured data as BLOB make sense?在什么时候将大量结构化数据存储为 BLOB 才有意义? 【发布时间】:2021-12-27 00:45:52 【问题描述】:我们正在运行一个用于数据分析的数据库支持的 Web 应用程序,目前基于 C#.NET,服务器上带有 EntityFramework,客户端主要是 html+javascript 框架(基于 Web)。
我们的应用程序会定期接收由用户上传或由其他基础设施接收的大量批量测量 X/Y 数据点,即 1e6 或更多。
目前我们在 MSSQL 中有一个名为 Values
和 id, series_id as int; x, y, z as float
的表。该表是BULK INSERT
,客户端上传时填充了数据,相关元数据保存在Series
表中。 db 总大小目前接近 1TB,其中 99.99% 为Values
数据。
这种方法实现起来很简单,但它有几个缺点,随着时间的推移,它变得复杂且缓慢:
我们必须以块的形式插入,以免对它进行预处理的 IIS 进程过载(目前每个块有 200'000 个数据点) 在 INSERT 期间 IIS 进程内存需求巨大(>1500MB 用于 200MB 数据) 插入速度太慢(500 万条记录相当于 100MB,即使使用 BULK INSERT 也需要 >30 秒才能插入) 在 INSERT 期间,整个表被锁定,即一次只能插入一个用户 检索数据也很慢,请求 1e6 条记录有时需要 >10 秒 删除具有 >1e6 条记录的系列经常会导致 Web 应用端超时。数据永远不会被部分选择,所以我们真的不需要将它放在一个表中。但它在发送给客户端之前被“精简”显示,即 1e6 条记录 - 默认情况下,即在 99% 的用例中 - 在发送给客户端之前减少到 2000 或 10'000 条记录。这被缓存在客户端上,但如果新客户端请求相同的集合,则会再次对其进行处理。 Values 表在series_id
上也有一个索引,它比表本身占用更多的磁盘空间。
我想知道将这种存储格式更改为具有自己的数据格式(CSV 或 JSON 或二进制)的“值”中的 BLOB 存储是否有意义,并且 - 也许 - 具有预处理“缩减”数据集的附加列可以在不改变的情况下推送到客户端的显示(例如,在 JSON 中)。所以新的Values
表格格式类似于
id, series_id, data(blob), reduced_data(blob)
每个Series
条目只有一个Value
,而不是1e6 或更多。收到上传的数据时会创建一次缩减的数据集,然后在客户端请求时用于显示
我将丢失通过 ID 或 X/Y 值选择的 values
的部分选择,但绝不会根据 id
或 series_id
以外的任何内容选择值,因此这是当前不是局限性。所以这是我的问题:
我觉得二进制数据格式带来的额外麻烦可能不值得,而且最好是压缩 CSV/JSON blob,而不是发明二进制格式。是吗?
我什至可能不知道的 BLOB 的其他缺点如何?大小限制似乎不是问题,varbinary(MAX)
就足够了。我不需要对 blob inside 的值的索引,只需在元数据(在 Series 表中)上。
想法?
【问题讨论】:
旁白:你不应该将你的表命名为Values
,因为这是一个保留关键字(source
是的。或者User
,或者... :-) 实际上,我没有。但是 a) 我很懒, b) 真实的表名会泄露有关我们应用程序的信息,这可能是超级机密的公司机密信息,你知道的。
【参考方案1】:
在 DB 中存储文件的主要优势之一是 DB 中的ACID
(原子性、一致性、隔离性、持久性)技术。这使我们能够在处理数据时安全地将所有数据插入到不同的表中。当您将文件作为 BLOB 存储在 DB 中时,您在将文件复制到其他存储时具有优势,因为 BLOB 比操作文件系统更快,并且您可以轻松备份文件。但是,如果每条记录的文件大小超过 10-50-100 MB,则不建议将文件存储在 BLOB 中。在这种情况下,向表中插入记录的持续时间可能需要 10-15-30 秒。不是很好,因为事务也持续这么久,而且事务过程中的所有表在这个意义上都被阻塞了,而这些表的长时间阻塞也会导致用户无法工作。 将文件存储为 BLOB 的有趣方式之一是 FILESTREAM BLOB 技术,该技术仅受 SQL Server 支持。您可以从this
【讨论】:
感谢您的指点。我将多个 50MB 数据块的 INSERT 基准测试到我们生产服务器上的示例表中,每个需要 1-2 秒,这是可以接受的。但是 FILESTREAM BLOB 也是一个好主意。以上是关于在啥时候将大量结构化数据存储为 BLOB 才有意义?的主要内容,如果未能解决你的问题,请参考以下文章