范围查询期间的Cassandra OutOfMemoryError

范围查询期间的Cassandra OutOfMemoryError,cassandra,Cassandra,我有一个包含1MB Blob的表 创建表blob_1( 关键文本, 版本bigint, 块int, 对象\u blob blob, 对象大小int, 主键(键、版本、区块) ) 每个lob分布在大约100个块上。 以下查询导致OutOfMemory错误: 从blobs_1中选择object_size,其中key='key1'和version=1 以下是错误: java.lang.OutOfMemoryError:java堆空间 位于org.apache.cassandra.io.util.Ran

我有一个包含1MB Blob的表

创建表blob_1( 关键文本, 版本bigint, 块int, 对象\u blob blob, 对象大小int, 主键(键、版本、区块) )

每个lob分布在大约100个块上。 以下查询导致OutOfMemory错误:

从blobs_1中选择object_size,其中key='key1'和version=1

以下是错误:

java.lang.OutOfMemoryError:java堆空间 位于org.apache.cassandra.io.util.RandomAccessReader.readBytes(RandomAccessReader.java:344) 位于org.apache.cassandra.utils.ByteBufferUtil.read(ByteBufferUtil.java:392) 位于org.apache.cassandra.utils.ByteBufferUtil.readWithLength(ByteBufferUtil.java:355) 位于org.apache.cassandra.db.ColumnSerializer.deserializeColumnBody(ColumnSerializer.java:124) 位于org.apache.cassandra.db.OnDiskAtom$Serializer.deserializefromstable(OnDiskAtom.java:85) 位于org.apache.cassandra.db.Column$1.computeNext(Column.java:75) 位于org.apache.cassandra.db.Column$1.computeNext(Column.java:64) 位于com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:143) 位于com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:138) 位于org.apache.cassandra.db.columniterator.SimpleSliceReader.computeNext(SimpleSliceReader.java:88) 位于org.apache.cassandra.db.columniterator.SimpleSliceReader.computeNext(SimpleSliceReader.java:37) 位于com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:143) 位于com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:138) 位于org.apache.cassandra.db.columniterator.SSTableSliceIterator.hasNext(SSTableSliceIterator.java:82) 在org.apache.cassandra.db.columniterator.LazyColumnIterator.computeNext(LazyColumnIterator.java:82) 在org.apache.cassandra.db.columniterator.LazyColumnIterator.computeNext(LazyColumnIterator.java:59) 位于com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:143) 位于com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:138) 位于org.apache.cassandra.db.filter.QueryFilter$2.getNext(QueryFilter.java:157) 位于org.apache.cassandra.db.filter.QueryFilter$2.hasNext(QueryFilter.java:140) 位于org.apache.cassandra.utils.MergeIterator$Candidate.advance(MergeIterator.java:144) 位于org.apache.cassandra.utils.MergeIterator$manytone.advance(MergeIterator.java:123) 位于org.apache.cassandra.utils.MergeIterator$manytone.computeNext(MergeIterator.java:97) 位于com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:143) 位于com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:138) 位于org.apache.cassandra.db.filter.SliceQueryFilter.collectReducedColumns(SliceQueryFilter.java:185) 位于org.apache.cassandra.db.filter.QueryFilter.collater列(QueryFilter.java:122) 位于org.apache.cassandra.db.filter.QueryFilter.collatendiskatom(QueryFilter.java:80) 位于org.apache.cassandra.db.RowIteratorFactory$2.getReduced(RowIteratorFactory.java:101) 位于org.apache.cassandra.db.RowIteratorFactory$2.getReduced(RowIteratorFactory.java:75) 位于org.apache.cassandra.utils.MergeIterator$manytone.consume(MergeIterator.java:115)
在org.apache.cassandra.utils.MergeIterator$ManyToOne.computeNext(MergeIterator.java:98)

上,发生错误的原因是cassandra在读取表的单个列时反序列化了超过必要数量的数据(至少cassandra 1.2,可能在2.0分支中有所改进)


为了解决这个问题,您可以为元数据(大小等)引入一个单独的表。它会降低写入速度,但会大大提高读取性能。

您需要减小页面大小。默认分页大小适用于正常的小列/行。对于较大的blob,需要缩小分页大小


这发生在2.0.2上。令人沮丧的是,一个查询就这么容易使服务器崩溃。我也创建了一个自动化的查询。因为这发生在cqlsh中,java驱动程序帮不了什么忙。所以,如果我只需要对象的大小,就无法避免抓取blob?我可以将“object_size”移动到另一个表中,但当我尝试获取作为主键一部分的“chunk”时,会出现相同的问题,并且无法将其移动到另一个表中。