2016-08-02 50 views
2

我们正在尝试将文件加载到Cassandra中的blob列。当我们加载1-2 MB文件的文件时,它会很好。当装载大文件,说大约50 MB,得到以下错误:在一致性LOCAL_QUORUM写入查询时Cassandra:为大文件创建blob问题

卡桑德拉失败(被要求1个答复,但只有0副本回应,1失败)

它是一个单节点发展D B。任何提示或支持将不胜感激。

回答

1

50mb对于一个单元来说非常大。虽然有些过期,但仍然准确:http://cassandra.apache.org/doc/4.0/faq/#can-large-blob

在Cassandra中没有流出流出单元的机制,因此单元内容需要在内存中作为单个响应序列化。你可能会在某个地方触发一个限制或错误,导致抛出一个异常并导致失败的查询(检查cassandras system.log,可能是一个例外,它会描述什么会更好)。

如果您拥有CQL集合或记录批次,则还有额外的下限。 http://docs.datastax.com/en/cql/3.3/cql/cql_reference/refLimits.html

你可以尝试将你的blob分块。 Id实际上建议像64kb,并在客户端,遍历它们并生成一个流(也可以防止将它完全加载到内存中)。

CREATE TABLE exampleblob (
    blobid text, 
    chunkid int, 
    data blob, 
    PRIMARY KEY (blobid, chunkid)); 

然后只是SELECT * FROM exampleblob WHERE blobid = 'myblob';并遍历结果。插入变得更加复杂,因为你必须有逻辑来分割你的文件,但是这也可以以流媒体的方式来完成,并且在你的应用程序方面是高效的。

另一种方法是将blob上传到S3或某些分布式文件存储,将文件的散列用作存储桶/文件名。在卡桑德拉只存储文件名作为参考。

+0

谢谢克里斯的投入。我能够从system.log中找到错误并更改配置以使其正常工作。增加commitlog_segment_size_in_mb以使文件大小加倍。 –

+0

你基于块的方法几乎没有问题,但有一些pitfails。例如,不能保证SELECT调用将返回所有的块。如果你有太多的块(例如100K),你不知道它们可能有多少 - 你遇到了很大的麻烦,你不能设置LIMIT。顺便说一下,更新的常见问题链接是:http://cassandra.apache.org/doc/3.9/faq/#can-i-store-large-blobs-in-cassandra –

+0

如果使用法定人数(或本地q)读/写所有的块将被返回。您可以设置获取大小(默认值5000,在这种情况下应该更低),然后当您在客户端通过它们遍历驱动程序页面时,它不会一次全部提取它们。 –