如何更快地用Java获取MySQL BLOB数据?- wix


如何以最快的响应时间从 MySQL 中获取整个 blob?

MySQL是否适合存储二进制数据的问题我们先搁置一旁。这里的问题是如何存储二进制数据,以便尽可能快地从数据库中读取数据?

解决方案可能是使用数据压缩。然而,这需要进行基准测试,因为在使用 CPU 进行解压缩和网络速度之间需要权衡。在这个基准测试中,我将比较不同压缩算法、使用 MySQL 本身进行压缩和根本不使用压缩之间的性能。

MySQL 中的 BLOB
MySQL 具有允许存储二进制数据的BLOB列类型(查看文档了解最大长度,以及使用 BLOB 的一些技巧)。

另一个方面是MySQL的存储行格式。根据行格式,MySQL 以不同方式存储数据。

  • DYNAMICBLOB用于存储指向其存储位置的 20 字节指针的行格式。REDUNDANT与行格式相反,COMPACT行格式将前 768 个字节存储在表中,其余字节存储在溢出页中。在此基准测试中,数据大小从 1028 字节开始,因此这种优化无关紧要。
  • COMPRESSED行格式启用数据库级别的压缩,因此 20 字节的指针将指向另一个存储,该存储将使用具有 4 字节长度前缀的 deflate进行压缩。为了进行基准测试,我们将在应用程序级别使用相同的算法来查看 MySQL 过度压缩的开销。您可能会发现另一篇有用的博客文章,其中概述了MySQL 压缩。

所以,我们要使用的第一个表结构是这样的:

CREATE  TABLE `uncompressed_blobs` ( 
  `id` INT  NOT  NULL  PRIMARY KEY, 
  `data` MEDIUMBLOB NOT  NULL
 ) ENGINE = InnoDB ROW_FORMAT = DYNAMIC ;

在此表中,我们将在不使用 MySQL 压缩的情况下存储未压缩的数据或在应用程序级别压缩的数据(显然,我们希望避免双重压缩,因为它无效)。

另一个用于对 MySQL 的压缩进行基准测试的表:

CREATE  TABLE `compressed_blobs` ( 
  `id` INT  NOT  NULL  PRIMARY KEY, 
  `data` MEDIUMBLOB NOT  NULL
 ) ENGINE = InnoDB ROW_FORMAT = COMPRESSED;


基准
对于这个基准测试,最重要的指标是吞吐量:我们可以在一秒钟内获得多少字节的未压缩数据。响应时间无法显示有意义的结果,因为它不包括压缩率。

AWS 配置的基准
1、真实数据集和数据大小在 600KB 到 4MB 之间的吞吐量:
lz4 领先于未压缩的 BLOB,而其他所有算法都比较慢。BLOB 越大,差异越显着。

2、较小的数据集 — 34KB 到 94KB:
特定示例的 lz4 压缩率明显更差。但是,请务必注意这一点——压缩率非常重要。
更大的尺寸和更好的压缩率——lz4 越来越优于其他一切。

本地主机的基准
除 lz4 之外,未压缩的性能明显优于任何其他算法。
在AWS中型 BLOB 配置的图表上,lz4 表现不佳(因为压缩率不佳)。但是,当您提高 MySQL(网络)的吞吐量时,lz4 继续发光:

MySQL 压缩算法
第一个比较是ROW_FORMAT=COMPRESSED和在ROW_FORMAT=DYNAMIC的压缩数据上使用MySQL的UNCOMPRESS功能。基本上,我们比较了存储的组织方式与简单的解压方式。

有趣的是,做SELECT UNCOMPRESS(data)比从存储本身自动解压数据稍快。

下一步是比较通过SELECT UNCOMPRESS(data)从MySQL获得未压缩的数据和从MySQL获得压缩的数据并在应用程序中自行解压的情况。
较低的网络使用率是非常有益的:在Java中解压缩的速度明显加快。

只有在最高压缩率的情况下,Java才会获胜。在其他情况下,MySQL更快。这可能意味着MySQL的UNCOMPRESS实现更快(这很合理,因为Java做了大量的内存拷贝和一些分配)。

lz4 与未压缩:
 lz4 明显胜出!

结论
对于我们的特定用例,lz4 看起来很有前途。当压缩率不好时,它会略有损失,但通常它会胜过其他任何东西。第二个选项是根本不使用任何压缩。

但重要的是要记住应用程序级压缩有一些缺点:

  • 数据不能在数据库中使用。因此,例如,如果您将 JSON 存储在 BLOB 中,您将无法使用 JSON 函数。
  • 它将 CPU 计算从 MySQL 转移到您的应用程序(在某些情况下这也可能是一个好处)。
  • 它需要应用程序方面的更多努力。

接下来要注意的是压缩比。了解你的数据,对你的数据进行基准测试,因为性能在很大程度上取决于实际的压缩率。

最后一件事——您的环境配置也可能极大地影响决策,因为较慢的服务器基准测试显示完全相反的结果(可能不完全,但接近它)。

源代码在GitHub 上