【问题标题】:Cassandra Hadoop map reduce with wide rows ignores slice predicate具有宽行的 Cassandra Hadoop 映射减少忽略切片谓词
【发布时间】:2013-07-31 18:04:14
【问题描述】:

我有一个宽行列族,我试图针对它运行 map reduce 作业。 CF 是按时间排序的事件集合,其中列名本质上是时间戳。我需要针对 CF 中的特定日期范围运行 MR 作业。

当我在widerow 属性设置为false 的情况下运行作业时,预期的列切片将传递到映射器类。但是当我将widerow设置为true时,会处理整个列族,忽略切片谓词。

问题是我必须使用 Widerow 支持,因为切片中的列数可能会变得非常大,如果一次性加载会消耗所有内存。

我找到了概述问题的 JIRA 任务,但它已被关闭为“无法重现” - https://issues.apache.org/jira/browse/CASSANDRA-4871?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel

我正在运行 cassandra 1.2.6 并在我的 jar 中使用 cassandra-thrift 1.2.4 和 hadoop-core 1.1.2。 CF 是使用 CQL3 创建的。

值得注意的是,无论我是使用 SliceRange 还是使用 setColumn_names() 指定列,都会发生这种情况 - 它仍然会处理所有列。

任何帮助将不胜感激。

【问题讨论】:

    标签: hadoop mapreduce cassandra thrift


    【解决方案1】:

    所以这似乎是设计使然。在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

    【讨论】:

      【解决方案2】:

      对不起,添加评论作为答案,但我们正在尝试做同样的事情,但你提到你能够“当我运行作业时将 Widerow 属性设置为 false,预期的列切片被传递到映射器类。”但是当我们将widerow属性设置为false时,我们仍然会遇到错误。你是如何在切片谓词中传递时间戳范围的。

      我们使用的 CF 是事件的时间线,其中 uid 作为分区键,event_timestamp 作为复合列。等价的cql是,

      创建表 testcf ( uid varchar, eventnt_timestamp 时间戳, 事件变量, PRIMARY KEY (uid, event_timestamp));

      Map reduce 代码 – 仅发送开始和结束日期内的事件(注意:我们可以从 cassandra-client 和 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)
      

      想知道我们是否在切片范围内的 start 和 end 参数中发送了不正确的数据。

      任何提示或帮助都是有用的。

      【讨论】:

      • 在我的例子中,我们使用 c# 记号而不是时间戳作为我们的复合列。所以切片范围是使用(伪代码) range.setStart("634926384000000000".getBytes());我假设如果您将范围开始和结束设置为空字节数组,它可以正常工作吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多