【问题标题】:What are the pros or cons of storing json as text vs blob in cassandra?在 cassandra 中将 json 存储为文本与 blob 的优缺点是什么?
【发布时间】:2015-09-29 02:34:33
【问题描述】:

对我来说,blob 的一个问题是,在 java 中,ByteBuffer(映射到 cassandra 中的 blob)不可序列化,因此不适用于 EJB。

考虑到 json 相当大,在 cassandra 中存储 json 的更好类型是什么。是文本还是 blob?

在决定 blob 与 json 时,json 的大小是否重要?

如果是像 oracle 这样的任何其他数据库,通常使用 blob/clob。但是在 Cassandra 中,每个单元格可以容纳 2GB 大小,这有关系吗?

对于这种情况,请将此问题视为文本与 blob 之间的选择,而不是针对是否对 json 使用单列的建议进行排序。

【问题讨论】:

  • 为什么要存储 JSON?为什么不将数据存储为表的字段而不是 blob?
  • 这个 JSON 只是一个包含更多列的表的一部分。这个 json 只是另一列。基本上,我对知道 json 的内容不感兴趣,我只是将其存储并检索到其他知道内容的系统。但是json本身相当大。你知道,寡核苷酸、板序列可能很大。
  • JSON 应该是 UTF-8 数据,而 Cassandra 的 text 类型将字符串存储为 UTF-8,因此除非您想进行压缩,否则应该没有什么区别。但是,从 Java 字符串到 ByteBuffer 的简单转换可能会导致实际包含 UTF-16 的 BLOB,这可能会占用大约 两倍 的空间。如果将其存储为二进制,现在每次交互都有机会选择错误编码格式。

标签: java json cassandra blob


【解决方案1】:

我认为在 Cassandra 中将 literal JSON 数据存储为 BLOB 没有任何好处。充其量您的存储成本是相同的,并且通常 API 在处理 BLOB 类型方面不太方便,因为它们在处理字符串/文本时不太方便。

例如,如果您使用他们的Java API,那么为了使用参数化的PreparedStatement 将数据存储为BLOB,您首先需要将其全部加载到ByteBuffer 中,例如通过打包您的 JSON 数据到 InputStream

除非您正在处理非常大 JSON sn-ps,否则无论如何都会强制您流式传输数据,否则访问BLOB 类型需要做相当多的额外工作。你会从中得到什么?基本上什么都没有。

但是,我认为询问“我应该将 JSON 存储为文本,还是 gzip 并将压缩数据存储为 BLOB”是有一些好处的。

问题的答案取决于您如何配置 Cassandra 和您的表。特别是,只要您使用 Cassandra 1.1 或更高版本,您的表就会默认启用压缩。这可能就足够了,尤其是当您的 JSON 数据在每一行中相当一致时。

但是,Cassandra 的内置压缩适用于整个表,而不是单个行。因此,通过在存储之前手动压缩 JSON 数据,将压缩字节写入 ByteBuffer,然后将数据作为 BLOB 传送到 Cassandra,您可以获得更好的压缩率。

因此,它本质上归结为存储空间、编程便利性和 CPU 使用率之间的权衡。我将决定如下:

  1. 最小化消耗的存储量是您最大关心的问题吗?
    • 如果是,则压缩 JSON 数据并将压缩后的字节存储为 BLOB
    • 否则,请继续执行 #2。
  2. Cassandra 的内置压缩功能是否适用于您的表并已启用?
    • 如果否(并且如果您无法启用压缩),则压缩 JSON 数据并将压缩后的字节存储为 BLOB
    • 否则,请继续执行 #3。
  3. 您要在每一行中存储的数据是否相对统一?
    • 可能对于 JSON 数据,答案是“是”,在这种情况下,您应该将数据存储为文本并让 Cassandra 处理压缩;
    • 否则继续执行 #4。
  4. 您想要效率还是方便?
    • 效率;压缩 JSON 数据并将压缩字节存储为 BLOB
    • 方便;压缩 JSON 数据,base64 压缩数据,然后将 base64 编码的数据存储为文本。

【讨论】:

  • 在您的第 4 点(压缩+编码+文本)=CET 上,我们将在多大程度上提高效率。我可以想象大小会下降,但转换为 CET 并返回 JSON 的成本如何。这不会造成 CPU 瓶颈
【解决方案2】:

由于数据不是二进制的,因此几乎没有理由使用二进制大对象。当然可以,但为什么呢?文本对人类来说更容易阅读,并且没有真正的速度/大小差异(。

即使在其他数据库中,您通常也可以将 JSON 存储为文本。例如。甚至 MySQL 也有可以处理大量文本的文本字段(LONGTEXT = 4Gb)。是的,Oracle 落后了,但希望他们有时也会得到一个合理的长文本字段。

但是为什么要将整个 Json 对象存储为文本呢? json 应该真正被规范化并存储为数据库中的多个字段。

【讨论】:

  • 还有其他实用的原因让我们按原样存储 json。因为,我们不关心json包含什么,它只是来自其他系统,我们只是存储和返回。
  • 如果您不关心保存的内容,那么关系数据库可能不是最佳选择。但是,是的,有一些有效的边缘情况,您希望存储 json 字符串而不关心它包含的内容。在这种情况下,如果您有该选项,则 text 比 clob/blob 更好。但这仍然是一个边缘案例。您失去了数据库的大部分功能,几乎没有收获(除了不必关心您存储的内容)。
  • 进一步澄清。 json 不是我表中唯一的列,它只是其中一列,还有其他我有兴趣了解内容的列……顺便说一下,边缘情况是什么?
  • @Astrogat 除了问题涉及Cassandra,它不是关系数据库。想要存储 JSON 对象而不是将整个事物分解为规范化的关系模式,有很多正当理由。易于处理大型、深度层次结构是一个重要的结构。
【解决方案3】:

我肯定会说文本会比存储 JSON 的 blob 更好。 JSON 最终是文本,所以这种类型是有意义的,但对于 blob 也可能有额外的开销,因为一些驱动程序似乎要求在插入它们之前将它们转换为十六进制。此外,在使用 cqlsh 时,blob 显示为 base64 编码的字符串,因此如果您需要进行测试,您将无法轻松检查实际存储的 JSON 内容。我不确定 blob 到底是如何存储在磁盘上的,但我想它与文本的存储方式非常相似。

话虽如此,存储大条目可能会导致问题和is not recommended。这可能会导致分片问题并消耗大量内存。虽然常见问题解答指的是超过 64MB 的文件,但根据经验,当您开始存储大量文件时,即使每个文件平均只有几兆字节,也会导致性能问题。如果可能的话,如果您希望 JSON 的大小为兆字节,并且将对该存储的引用存储在 Cassandra 中,那么最好使用对象存储。

【讨论】:

    【解决方案4】:

    在即将发布的 2.2 版本中,Cassandra 还原生支持 JSON。 http://www.datastax.com/dev/blog/whats-new-in-cassandra-2-2-json-support

    【讨论】:

    • 这似乎是关于 json 存储。我说的是在一个表中创建一个列,该列甚至还有其他字段。
    猜你喜欢
    • 1970-01-01
    • 2021-10-29
    • 1970-01-01
    • 2010-09-17
    • 2016-10-02
    • 2019-11-14
    • 1970-01-01
    • 1970-01-01
    • 2016-03-26
    相关资源
    最近更新 更多