Java 如何确定Apache Spark中的偏移量?

Java 如何确定Apache Spark中的偏移量?,java,apache-spark,offset,Java,Apache Spark,Offset,我正在搜索一些数据文件(~20GB)。我想在数据中找到一些特定的术语,并标记匹配的偏移量。有没有办法让Spark识别我正在操作的数据块的偏移量 import org.apache.spark.api.java.*; import org.apache.spark.SparkConf; import org.apache.spark.api.java.function.Function; import java.util.regex.*; public class Grep {

我正在搜索一些数据文件(~20GB)。我想在数据中找到一些特定的术语,并标记匹配的偏移量。有没有办法让Spark识别我正在操作的数据块的偏移量

import org.apache.spark.api.java.*;
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.function.Function;

import java.util.regex.*;

public class Grep {
        public static void main( String args[] ) {
            SparkConf        conf       = new SparkConf().setMaster( "spark://ourip:7077" );
            JavaSparkContext jsc        = new JavaSparkContext( conf );
            JavaRDD<String>  data       = jsc.textFile( "hdfs://ourip/test/testdata.txt" ); // load the data from HDFS
            JavaRDD<String>  filterData = data.filter( new Function<String, Boolean>() {
                    // I'd like to do something here to get the offset in the original file of the string "babe ruth"
                    public Boolean call( String s ) { return s.toLowerCase().contains( "babe ruth" ); } // case insens matching

            });

            long matches = filterData.count();  // count the hits

            // execute the RDD filter
            System.out.println( "Lines with search terms: " + matches );
 );
        } //  end main
} // end class Grep
import org.apache.spark.api.java.*;
导入org.apache.spark.SparkConf;
导入org.apache.spark.api.java.function.function;
导入java.util.regex.*;
公共课Grep{
公共静态void main(字符串参数[]){
SparkConf conf=新的SparkConf().setMaster(“spark://ourip:7077" );
JavaSparkContext jsc=新的JavaSparkContext(conf);
JavaRDD data=jsc.textFile(“hdfs://ourip/test/testdata.txt“”;//从HDFS加载数据
JavaRDD filterData=data.filter(新函数(){
//我想在这里做点什么来获得字符串“babe ruth”原始文件中的偏移量
公共布尔调用(字符串s){return s.toLowerCase().contains(“babe ruth”);}//大小写插入匹配
});
long matches=filterData.count();//计算命中率
//执行RDD过滤器
System.out.println(“带有搜索词的行:“+匹配项”);
);
}//末端总管
}//结束类Grep

我想在“filter”操作中计算原始文件中“baberuth”的偏移量。我可以得到当前行中“babe ruth”的偏移量,但是告诉我文件中行的偏移量的过程或函数是什么?

您可以使用
wholeTextFiles(字符串路径,int-minPartitions)
JavaSparkContext
中的方法返回一个
javapairdd
,其中键是filename,值是包含文件全部内容的字符串(因此,此RDD中的每条记录表示一个文件)。从这里,只需运行一个
map()
,它将对每个值调用
indexOf(String searchString)
。这将返回每个文件中的第一个索引以及相关字符串的出现

(编辑:)

因此,以分布式方式查找一个文件的偏移量(根据注释中下面的用例)是可能的。下面是一个在Scala中工作的示例

val searchString = *search string*
val rdd1 = sc.textFile(*input file*, *num partitions*)

// Zip RDD lines with their indices
val zrdd1 = rdd1.zipWithIndex()

// Find the first RDD line that contains the string in question
val firstFind = zrdd1.filter { case (line, index) => line.contains(searchString) }.first()

// Grab all lines before the line containing the search string and sum up all of their lengths (and then add the inline offset)
val filterLines = zrdd1.filter { case (line, index) => index < firstFind._2 }
val offset = filterLines.map { case (line, index) => line.length }.reduce(_ + _) + firstFind._1.indexOf(searchString)
val searchString=*搜索字符串*
val rdd1=sc.textFile(*输入文件*,*num分区*)
//压缩RDD行及其索引
val zrdd1=rdd1.zipWithIndex()
//查找包含所讨论字符串的第一个RDD行
val firstFind=zrdd1.filter{case(line,index)=>line.contains(searchString)}.first()
//抓取包含搜索字符串的行之前的所有行,并将它们的所有长度相加(然后添加内联偏移量)
val filterLines=zrdd1.filter{case(line,index)=>indexline.length}.reduce(+u)+firstFind._1.indexOf(searchString)
请注意,由于不考虑任何新行字符(输入格式使用新行作为记录之间的界限),因此您还需要在其上手动添加任何新行字符。新行数只是包含搜索字符串的行之前的行数,因此这是很容易添加的

不幸的是,我并不完全熟悉Java API,而且它也不太容易测试,因此我不确定下面的代码是否有效,但我已经做到了(我也使用了Java 1.7,但1.8用lambda表达式压缩了很多代码):

String searchString=*搜索字符串*;
JavaRDD data=jsc.textFile(“hdfs://ourip/test/testdata.txt");
JavaRDD ZRD1=data.zipWithIndex();
Tuple2 firstFind=zrdd1.filter(新函数(){
公共布尔调用(Tuple2输入){return input.productElement(0.contains)(searchString);}
}).first();
javarddfilterlines=zrdd1.filter(新函数(){
公共布尔调用(Tuple2输入){return input.productElement(1)
只有当您的输入是一个文件时(否则,
zipWithIndex()
不能保证文件中的偏移量),才能执行此操作,但此方法适用于任意数量分区的RDD,因此可以将您的文件随意划分为任意数量的块。

可以使用Spark common Hadoop输入格式。要从文件中读取字节偏移量,可以使用Hadoop中的类(org.apache.Hadoop.mapreduce.lib.input)。它已经与Spark捆绑在一起了

它将文件读取为键(字节偏移量)和值(文本行):

纯文本文件的输入格式。文件被分成几行。换行符或回车符用于表示换行结束。键是文件中的位置,值是文本行

在Spark中,可以通过调用
newAPIHadoopFile()

SparkConf conf=new SparkConf().setMaster(“”);
JavaSparkContext jsc=新的JavaSparkContext(conf);
//使用Hadoop格式读取文件内容
javapairdd data=jsc.newapiHadoop文件(
“文件路径”,//输入路径
TextInputFormat.class,//使用的输入格式类
LongWritable.class,//值的类
Text.class,//值的类
新配置());
JavaRDD mapped=data.map(新函数(){
@凌驾
公共字符串调用(Tuple2 tuple)引发异常{
//您将从中获得每一行作为元组(偏移量、文本)
long pos=元组。_1().get();//提取偏移量
字符串行=元组。_2().toString();//提取文本
返回pos+“”+行;
}
});

我不知道这里的偏移量是什么意思。你能说得更具体点吗?我很抱歉
String searchString = *search string*;
JavaRDD<String> data = jsc.textFile("hdfs://ourip/test/testdata.txt");

JavaRDD<Tuple2<String, Long>> zrdd1 = data.zipWithIndex();

Tuple2<String, Long> firstFind = zrdd1.filter(new Function<Tuple2<String, Long>, Boolean>() {
      public Boolean call(Tuple2<String, Long> input) { return input.productElement(0).contains(searchString); }
  }).first();

JavaRDD<Tuple2<String, Long>> filterLines = zrdd1.filter(new Function<Tuple2<String, Long>, Boolean>() {
      public Boolean call(Tuple2<String, Long> input) { return input.productElement(1) < firstFind.productElement(1); }
  });

Long offset = filterLines.map(new Function<Tuple2<String, Long>, Int>() {
      public Int call(Tuple2<String, Long> input) { return input.productElement(0).length(); }
  }).reduce(new Function2<Integer, Integer, Integer>() {
      public Integer call(Integer a, Integer b) { return a + b; }
  }) + firstFind.productElement(0).indexOf(searchString);