我有一个宽行列族,我正试图针对它运行map reduce作业。CF是一个按时间顺序排列的事件集合,其中列名本质上是时间戳。我需要根据CF中的特定日期范围运行MR作业。
当我在widerow属性设置为false的情况下运行作业时,所需的列片段会传递到mapper类中。但是,当我将widerow设置为true时,将处理整个列族,忽略slice谓词。
问题是,我必须使用宽行支持,因为如果一次加载,切片中的列数可能会增长得很大,并消耗所有内存。
我发现了这个JIRA任务,它概述了这个问题,但它已经被关闭,因为"无法复制"-https://issues.apache.org/jira/browse/CASSANDRA-4871?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-选项卡
我运行cassandra 1.2.6,并使用cassandra节俭1.2.4&我的jar中有hadoop内核1.1.2。CF是使用CQL3创建的。
值得注意的是,无论我是使用SliceRange还是使用setColumn_name()指定列,都会发生这种情况——它仍然处理所有列。
任何帮助都将不胜感激。
所以这似乎是故意的。在github中的word_count示例中,存在以下注释:
// this will cause the predicate to be ignored in favor of scanning everything as a wide row
ConfigHelper.setInputColumnFamily(job.getConfiguration(), KEYSPACE, COLUMN_FAMILY, true);
呃。那就太公平了。然而,当使用宽行时,没有办法限制列,这似乎很疯狂。
更新
显然,解决方案是使用新的apache.cassandra.hadoop.cql3库。请参阅github上的新示例以供参考:https://github.com/apache/cassandra/blob/trunk/examples/hadoop_cql3_word_count/src/WordCount.java
很抱歉,添加注释作为答案,但我们正在尝试做同样的事情,但您提到您可以这样做:"当我在widrow属性设置为false的情况下运行作业时,预期的列片段将传递到mapper类中。"但当我们将widrow属性设为false时,我们仍然会收到错误。您是如何在切片谓词中传递时间戳范围的。
我们使用的CF是事件的时间轴,uid作为分区键,event_timestamp作为合成列。等效cql为
创建表格测试cf(uid varchar,event_ timestamp时间戳,事件varchar,PRIMARY KEY(uid,event_timestamp));
Map reduce代码–只发送开始和结束日期内的事件(注意:我们可以从cassandra客户端和时间戳组合列上的cqlsh查询,并获得所需的事件)
// Settting widerow to false
config.setInputColumnFamily(Constants.KEYSPACE_TRACKING, Constants.CF_USER_EVENTS, false);
DateTime start = getStartDate(); // e.g., July 30th 2013
DateTime end = getEndDate(); // e.g., Aug 6th 2013
SliceRange range = new SliceRange(
ByteBufferUtil.bytes(start.getMillis()),
ByteBufferUtil.bytes(end.getMillis()),
false, Integer.MAX_VALUE);
SlicePredicate predicate = new SlicePredicate().setSlice_range(range);
config.setInputSlicePredicate(predicate);
But the above code doesn't work. We get the following error,
java.lang.RuntimeException: InvalidRequestException(why:Invalid bytes remaining after an end-of-component at component0)
at org.apache.cassandra.hadoop.ColumnFamilyRecordReader$StaticRowIterator.maybeInit(ColumnFamilyRecordReader.java:384)
想知道我们在切片范围内的开始和结束参数中是否发送了不正确的数据。
任何提示或帮助都是有用的。