2013-12-12 64 views
1

我有一個包含1MB blob的表。範圍查詢期間的Cassandra OutOfMemoryError

CREATE TABLE blobs_1( 關鍵文本, 版本BIGINT, 塊INT, object_blob一滴, object_size INT, PRIMARY KEY(鍵,版本,塊) )

每個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) at org.apache.cassandra.db.OnDiskAtom $ Serializer.deserializeFromSSTable(OnDiskAtom.java:85) at 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) at org.apache.cassandra.db.columniterator.SimpleSliceReader.computeNext(SimpleSliceReader.java:88) at 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) at 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。 com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:138) (org.apache.cassandra.db.filter.QueryFilter $ 2.get) (QueryFilter.java:157) at org.apache.cassandra.db.filter.QueryFilter $ 2.hasNext(QueryFilter.java:140) at org.apache.cassandra.utils.MergeIterator $ Candidate.advance(MergeIterator.java: 144) at org.apache.cassandra.utils.MergeIterator $ ManyToOne.advance(MergeIterator.java:123) at org .apache.cassandra.utils.MergeIterator $ ManyToOne.computeNext(MergeIterator.java:97) at com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:143) at com.google.common.collect.AbstractIterator .hasNext(AbstractIterator.java:138) at org.apache.cassandra.db.filter.SliceQueryFilter.collectReducedColumns(SliceQueryFilter.java:185) at org.apache.cassandra.db.filter.QueryFilter.collat​​eColumns(QueryFilter.java :122) 在org.apache.cassandra.db.filter.QueryFilter.collat​​eOnDiskAtom(QueryFilter.java:80) 在org.apache.cassandra.db.RowIteratorFactory $ 2.getReduced(RowIteratorFactory.java:101) 在有機apache.cassandra.db.RowIteratorFactory港幣$ 16。getReduced(RowIteratorFactory.java:75) at org.apache.cassandra.utils.MergeIterator $ ManyToOne.consume(MergeIterator.java:115) at org.apache.cassandra.utils.MergeIterator $ ManyToOne.computeNext(MergeIterator.java: 98)

+0

這發生在2.0.2上。令人沮喪的是,單個查詢如此輕易地崩潰了服務器。 – user3025533

回答

0

發生此錯誤是因爲Cassandra在讀取表的單個列(至少Cassandra 1.2,也許這已在2.0分支中得到改進)時反序列化了超出必要的數據。

要解決這個問題,你可以引入一個單獨的元數據表(尺寸等)。它會減慢寫入的速度,但會大大提高讀取性能。

2

您需要減少頁面大小。默認分頁大小適用於普通的小列/行。對於大塊,您需要縮小分頁大小。

https://github.com/datastax/java-driver/blob/2.0/driver-core/src/main/java/com/datastax/driver/core/Statement.java#L234

+0

我也創建了https://issues.apache.org/jira/browse/CASSANDRA-6492來自動執行此操作。 – jbellis

+0

因爲這發生在cqlsh中,所以java驅動程序不會有太大的幫助。那麼,如果我只需要object_size,就沒有辦法避免抓取blob了?我可以將「object_size」移動到另一個表中,但是當我試圖獲取作爲主鍵一部分的「塊」時會發生同樣的問題,並且這不能移動到另一個表中。 – user3025533