{"id":264933,"date":"2015-09-04T11:42:02","date_gmt":"2015-09-04T07:42:02","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=264933"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=264933","title":{"rendered":"Apache Spark \u0438\u043b\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0431\u043b\u0443\u0434\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f"},"content":{"rendered":"<p>     \t\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0446\u0438\u043a\u043b \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u0440\u043e DMP \u0438 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0441\u0442\u0435\u043a \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 <a href=\"http:\/\/targetix.net\/\">Targetix<\/a>.<br \/>  \u041d\u0430 \u044d\u0442\u043e \u0440\u0430\u0437 \u0440\u0435\u0447\u044c \u043f\u043e\u0439\u0434\u0435\u0442 \u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0432 \u043d\u0430\u0448\u0435\u0439 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 <b><a href=\"http:\/\/spark.apache.org\/\">Apache Spark<\/a><\/b> \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442e, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0440\u0435\u043c\u0430\u0440\u043a\u0435\u0442\u0438\u043d\u0433\u043e\u0432\u044b\u0435 \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u0438. <br \/>  \u0418\u043c\u0435\u043d\u043d\u043e \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u043e\u043c\u0443 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0443, \u043e\u0434\u043d\u0430\u0436\u0434\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0432 \u043b\u043e\u0431\u0437\u0438\u043a, \u0432\u044b \u0431\u0443\u0434\u0435\u0442\u0435 \u0432\u0438\u0434\u0435\u0442\u044c \u0435\u0433\u043e \u0432\u043e \u0432\u0441\u0435\u0445 \u0443\u0433\u043e\u043b\u043a\u0430\u0445 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0430 \u0434\u043e \u043a\u043e\u043d\u0446\u0430 \u0441\u0432\u043e\u0435\u0439 \u0436\u0438\u0437\u043d\u0438.<br \/>  \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0438 \u043d\u0430\u0431\u0438\u043b\u0438 \u043f\u0435\u0440\u0432\u044b\u0435 \u0448\u0438\u0448\u043a\u0438 \u0432 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0438 \u0441 Apache Spark. <br \/>  \u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0438 Spark-\u043a\u043e\u0434 \u043f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c.<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/833\/c23\/2aa\/833c232aaea64f228ad5ee8075dc1601.jpg\"\/><br \/>  <a name=\"habracut\"><\/a>  <\/p>\n<h4><b>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/b><\/h4>\n<p>  \u0414\u043b\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u0446\u0435\u043b\u0435\u0439 \u0440\u0430\u0437\u044a\u044f\u0441\u043d\u0438\u043c \u0442\u0435\u0440\u043c\u0438\u043d\u043e\u043b\u043e\u0433\u0438\u044e \u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435.<br \/>  <b>\u0427\u0442\u043e \u0436\u0435 \u0442\u0430\u043a\u043e\u0435 \u0440\u0435\u043c\u0430\u0440\u043a\u0435\u0442\u0438\u043d\u0433?<\/b> \u041e\u0442\u0432\u0435\u0442 \u043d\u0430 \u044d\u0442\u043e\u0442 \u0432\u043e\u043f\u0440\u043e\u0441 \u0432\u044b \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u0432 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A0%D0%B5%D1%82%D0%B0%D1%80%D0%B3%D0%B5%D1%82%D0%B8%D0%BD%D0%B3\">\u0432\u0438\u043a\u0438<\/a>), \u0430 \u0435\u0441\u043b\u0438 \u043a\u043e\u0440\u043e\u0442\u043a\u043e, \u0442\u043e \u0440\u0435\u043c\u0430\u0440\u043a\u0435\u0442\u0438\u043d\u0433 (\u043e\u043d \u0436\u0435 \u0440\u0435\u0442\u0430\u0440\u0433\u0435\u0442\u0438\u043d\u0433) \u2014 \u0440\u0435\u043a\u043b\u0430\u043c\u043d\u044b\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430 \u0441\u0430\u0439\u0442 \u0440\u0435\u043a\u043b\u0430\u043c\u043e\u0434\u0430\u0442\u0435\u043b\u044f \u0434\u043b\u044f \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0446\u0435\u043b\u0435\u0432\u043e\u0433\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f.<\/p>\n<p>  \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0442 \u0441\u0430\u043c\u043e\u0433\u043e \u0440\u0435\u043a\u043b\u0430\u043c\u043e\u0434\u0430\u0442\u0435\u043b\u044f, \u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u0430\u044f <b>first party data<\/b>, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0432 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u0441 \u0441\u0430\u0439\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e\u0442 \u0443 \u0441\u0435\u0431\u044f \u043d\u0430\u0448 \u043a\u043e\u0434 \u2014 <b>SmartPixel<\/b>. \u042d\u0442\u043e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435 (user agent), \u043f\u043e\u0441\u0435\u0449\u0451\u043d\u043d\u044b\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u0445 \u0438 \u0441\u043e\u0432\u0435\u0440\u0448\u0451\u043d\u043d\u044b\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f\u0445. \u0417\u0430\u0442\u0435\u043c \u043c\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Apache Spark \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u0438 \u0434\u043b\u044f \u043f\u043e\u043a\u0430\u0437\u0430 \u0440\u0435\u043a\u043b\u0430\u043c\u044b.<\/p>\n<h4><b>\u0420\u0435\u0448\u0435\u043d\u0438\u0435<\/b><\/h4>\n<p>  <\/p>\n<h5>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u0438\u0441\u0442\u043e\u0440\u0438\u0438<\/h5>\n<p>  \u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043d\u0430 \u0447\u0438\u0441\u0442\u043e\u043c Hadoop \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f MapReduce \u0437\u0430\u0434\u0430\u0447\u0438 \u0438 \u0443 \u043d\u0430\u0441 \u044d\u0442\u043e \u0434\u0430\u0436\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c. \u041e\u0434\u043d\u0430\u043a\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u0430\u043a\u043e\u0433\u043e \u0432\u0438\u0434\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u0434\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u0447\u0435\u043d\u044c \u0441\u043b\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u0438 \u043e\u0442\u043b\u0430\u0436\u0438\u0432\u0430\u0442\u044c.<\/p>\n<p>  <i>\u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0442\u0440\u0451\u0445 \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432 \u043c\u044b \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043c \u043a\u043e\u0434 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 audience_id \u043f\u043e visitor_id.<\/i>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u0434\u0430 MapReduce:<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">public static class Map extends Mapper&lt;LongWritable, Text, Text, Text&gt; {    @Override    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {        String s = value.toString();        String[] split = s.split(&quot; &quot;);        context.write(new Text(split[0]), new Text(split[1]));    } }  public static class Reduce extends Reducer&lt;Text, Text, Text, ArrayWritable&gt; {    @Override    protected void reduce(Text key, Iterable&lt;Text&gt; values, Context context) throws IOException, InterruptedException {        HashSet&lt;Text&gt; set = new HashSet&lt;&gt;();        values.forEach(t -&gt; set.add(t));         ArrayWritable array = new ArrayWritable(Text.class);        array.set(set.toArray(new Text[set.size()]));        context.write(key, array);    } }  public static class Run {    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {        Job job = Job.getInstance();        job.setJarByClass(Run.class);        job.setMapperClass(Map.class);        job.setReducerClass(Reduce.class);        job.setOutputKeyClass(Text.class);        job.setOutputValueClass(ArrayWritable.class);        FileInputFormat.addInputPath(job, new Path(args[0]));        FileOutputFormat.setOutputPath(job, new Path(args[1]));        System.exit(job.waitForCompletion(true) ? 0 : 1);    } }  <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0417\u0430\u0442\u0435\u043c \u043d\u0430 \u0433\u043b\u0430\u0437\u0430 \u043d\u0430\u043c \u043f\u043e\u043f\u0430\u043b\u0441\u044f Pig. \u042f\u0437\u044b\u043a \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 Pig Latin, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u043b \u043a\u043e\u0434 \u0432 MapReduce \u0437\u0430\u0434\u0430\u0447\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u043a\u0443\u0434\u0430 \u043c\u0435\u043d\u044c\u0448\u0435 \u043a\u043e\u0434\u0430, \u0434\u0430 \u0438 \u0441 \u044d\u0441\u0442\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043e\u043d \u0431\u044b\u043b \u043a\u0443\u0434\u0430 \u043b\u0443\u0447\u0448\u0435.  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u0434\u0430 Pig:<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">A = LOAD '\/data\/input' USING PigStorage(' ') AS (visitor_id:chararray, audience_id:chararray); B = DISTINCT A; C = GROUP B BY visitor_id; D = FOREACH C GENERATE group AS visitor_id, B.audience_id AS audience_id; STORE D INTO '\/data\/output' USING PigStorage(); <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0412\u043e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u044b\u043b\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0441 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435\u043c. \u041f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u043c\u043e\u0434\u0443\u043b\u0438 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f, \u0442.\u043a. \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u0431\u0430\u0437 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u043b\u0438 Pig.<\/p>\n<p>  \u0417\u0434\u0435\u0441\u044c \u0442\u043e \u043d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c \u043f\u0440\u0438\u0448\u0435\u043b Spark.  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u0434\u0430 Spark:<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">SparkConf sparkConf = new SparkConf().setAppName(&quot;Test&quot;); JavaSparkContext jsc = new JavaSparkContext(sparkConf); jsc.textFile(args[0])        .mapToPair(str -&gt; {            String[] split = str.split(&quot; &quot;);            return new Tuple2&lt;&gt;(split[0], split[1]);        })        .distinct()        .groupByKey()        .saveAsTextFile(args[1]); <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0417\u0434\u0435\u0441\u044c \u0438 \u043a\u0440\u0430\u0442\u043a\u043e\u0441\u0442\u044c, \u0438 \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u043e, \u0442\u0430\u043a \u0436\u0435 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043c\u043d\u043e\u0433\u0438\u0445 <b>OutputFormat<\/b>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043e\u0431\u043b\u0435\u0433\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0435 \u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043b\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438.<\/p>\n<h5><b>\u041d\u044b\u043d\u0435\u0448\u043d\u044f\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/b><\/h5>\n<p>  \u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0432 \u0446\u0435\u043b\u043e\u043c \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/b34\/990\/02f\/b3499002fcb94c3ab2b6550833f590f8.jpg\"\/><\/p>\n<p>  \u0414\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u043a \u043d\u0430\u043c \u0441\u043e SmartPixel&#8217;\u0435\u0439, \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u043d\u0430 \u0441\u0430\u0439\u0442\u0430\u0445. \u041a\u043e\u0434 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c, \u043e\u043d \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u0435\u043d \u043b\u044e\u0431\u043e\u0439 \u0432\u043d\u0435\u0448\u043d\u0435\u0439 \u043c\u0435\u0442\u0440\u0438\u043a\u0435. \u041e\u0442\u0441\u044e\u0434\u0430 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0432 \u0432\u0438\u0434\u0435 <b>{ Visitor_Id: Action }<\/b>. \u041f\u043e\u0434 Action \u0442\u0443\u0442 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u0435 \u0446\u0435\u043b\u0435\u0432\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435: \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b\/\u0442\u043e\u0432\u0430\u0440\u0430, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0432 \u043a\u043e\u0440\u0437\u0438\u043d\u0443, \u043f\u043e\u043a\u0443\u043f\u043a\u0430 \u0438\u043b\u0438 \u043b\u044e\u0431\u043e\u0435 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u0435 \u0440\u0435\u043a\u043b\u0430\u043c\u043e\u0434\u0430\u0442\u0435\u043b\u0435\u043c.<\/p>\n<p>  \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0440\u0435\u043c\u0430\u0440\u043a\u0435\u0442\u0438\u043d\u0433\u0430 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 2 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439:  <\/p>\n<ul>\n<li>\u041f\u043e\u0442\u043e\u043a\u043e\u0432\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 (<b>streaming<\/b>).<\/li>\n<li>\u041f\u0430\u043a\u0435\u0442\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 (<b>batching<\/b>).<\/li>\n<\/ul>\n<h5><b>\u041f\u043e\u0442\u043e\u043a\u043e\u0432\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430<\/b><\/h5>\n<p>  \u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0432 \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u0438 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c Spark Streaming \u0441 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u043e\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 10 \u0441\u0435\u043a\u0443\u043d\u0434. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u044e \u043f\u043e\u0447\u0442\u0438 \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e\u0433\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f (\u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u044d\u0442\u0438\u0445 \u0441\u0430\u043c\u044b\u0445 10 \u0441\u0435\u043a\u0443\u043d\u0434). \u0412\u0430\u0436\u043d\u043e \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0432 \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b \u043f\u043e\u0442\u0435\u0440\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430\u0445 \u0438\u0437-\u0437\u0430 \u043f\u0438\u043d\u0433\u0430 \u0434\u043e \u0431\u0430\u0437 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u043b\u0438 \u043a\u0430\u043a\u0438\u0445-\u043b\u0438\u0431\u043e \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u0440\u0438\u0447\u0438\u043d.<\/p>\n<p>  \u0413\u043b\u0430\u0432\u043d\u043e\u0435 \u2014 \u044d\u0442\u043e \u0431\u0430\u043b\u0430\u043d\u0441 \u043c\u0435\u0436\u0434\u0443 \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u043e\u0442\u043a\u043b\u0438\u043a\u0430 \u0438 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u043d\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c\u044e. \u0427\u0435\u043c \u043c\u0435\u043d\u044c\u0448\u0435 <b>batchInterval<\/b>, \u0442\u0435\u043c \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442\u0441\u044f, \u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0442\u0440\u0430\u0447\u0435\u043d\u043e \u043d\u0430 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043d\u0430\u043a\u043b\u0430\u0434\u043d\u044b\u0435 \u0440\u0430\u0441\u0445\u043e\u0434\u044b, \u0442\u0430\u043a \u0447\u0442\u043e \u0437\u0430 \u0440\u0430\u0437 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u043d\u0435 \u0442\u0430\u043a \u043c\u043d\u043e\u0433\u043e. \u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0437\u0430 \u0440\u0430\u0437 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u043e \u0442\u043e\u0433\u0434\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 \u0442\u0440\u0430\u0442\u0438\u0442\u0441\u044f \u0434\u0440\u0430\u0433\u043e\u0446\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0434\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432 \u043d\u0443\u0436\u043d\u0443\u044e \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u044e.  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0412\u044b\u0431\u043e\u0440 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0438\u0437 Kafka:<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">public class StreamUtil {    private static final Function&lt;JavaPairRDD&lt;String, byte[]&gt;, JavaRDD&lt;Event&gt;&gt; eventTransformFunction =            rdd -&gt; rdd.map(t -&gt; Event.parseFromMsgPack(t._2())).filter(e -&gt; e != null);     public static JavaPairReceiverInputDStream&lt;String, byte[]&gt; createStream(JavaStreamingContext jsc, String groupId, Map&lt;String, Integer&gt; topics) {        HashMap prop = new HashMap() {{            put(&quot;zookeeper.connect&quot;, BaseUtil.KAFKA_ZK_QUORUM);            put(&quot;group.id&quot;, groupId);        }};        return KafkaUtils.createStream(jsc, String.class, byte[].class, StringDecoder.class, DefaultDecoder.class, prop, topics, StorageLevel.MEMORY_ONLY_SER());    }     public static JavaDStream&lt;Event&gt; getEventsStream(JavaStreamingContext jssc, String groupName, Map&lt;String, Integer&gt; map, int count) {        return getStream(jssc, groupName, map, count, eventTransformFunction);    }     public static &lt;T&gt; JavaDStream&lt;T&gt; getStream(JavaStreamingContext jssc, String groupName, Map&lt;String, Integer&gt; map,                                               Function&lt;JavaPairRDD&lt;String, byte[]&gt;, JavaRDD&lt;T&gt;&gt; transformFunction) {        return createStream(jssc, groupName, map).transform(transformFunction);    }     public static &lt;T&gt; JavaDStream&lt;T&gt; getStream(JavaStreamingContext jssc, String groupName, Map&lt;String, Integer&gt; map, int count,                                               Function&lt;JavaPairRDD&lt;String, byte[]&gt;, JavaRDD&lt;T&gt;&gt; transformFunction) {        if (count &lt; 2) return getStream(jssc, groupName, map, transformFunction);         ArrayList&lt;JavaDStream&lt;T&gt;&gt; list = new ArrayList&lt;&gt;();        for (int i = 0; i &lt; count; i++) {            list.add(getStream(jssc, groupName, map, transformFunction));        }        return jssc.union(list.get(0), list.subList(1, count));    } } <\/code><\/pre>\n<p>  \u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u043e\u0442\u043e\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0442\u043e\u043f\u0438\u043a\u0438 \u0438 \u0438\u043c\u044f \u0433\u0440\u0443\u043f\u043f\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u0435\u0439 (jssc, topics \u0438 groupId \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e). \u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441\u0432\u043e\u0439 \u0441\u0434\u0432\u0438\u0433 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u043e \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u0442\u043e\u043f\u0438\u043a\u0443. \u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u0435\u0439 \u0434\u043b\u044f \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u0435\u0440\u0432\u0435\u0440\u0430\u043c\u0438. \u0412\u0441\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430\u0434 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 transformFunction \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u0442\u043e\u043c \u0436\u0435 \u043f\u043e\u0442\u043e\u043a\u0435, \u0447\u0442\u043e \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u0438.  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439:<\/b><\/p>\n<div class=\"spoiler_text\">\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430  <\/p>\n<pre><code class=\"java\">   public JavaPairRDD&lt;String, Condition&gt; conditions;    private JavaStreamingContext jssc;    private Map&lt;Object, HyperLogLog&gt; hlls;    public JavaStreamingContext create() {        sparkConf.setAppName(&quot;UniversalStreamingBuilder&quot;);        sparkConf.set(&quot;spark.serializer&quot;, &quot;org.apache.spark.serializer.KryoSerializer&quot;);        sparkConf.set(&quot;spark.storage.memoryFraction&quot;, &quot;0.125&quot;);         jssc = new JavaStreamingContext(sparkConf, batchInterval);        HashMap map = new HashMap();        map.put(topicName, 1); \/\/ Kafka topic name and number partitions         JavaDStream&lt;Event&gt; events = StreamUtil.getEventsStream(jssc, groupName, map, numReceivers).repartition(numWorkCores);         updateConditions();         events.foreachRDD(ev -&gt; {            \/\/ Compute audiences            JavaPairRDD&lt;String, Object&gt; rawva = conditions.join(ev.keyBy(t -&gt; t.pixelId))                    .mapToPair(t -&gt; t._2())                    .filter(t -&gt; EventActionUtil.checkEvent(t._2(), t._1().condition))                    .mapToPair(t -&gt; new Tuple2&lt;&gt;(t._2().visitorId, t._1().id))                    .distinct()                    .persist(StorageLevel.MEMORY_ONLY_SER())                    .setName(&quot;RawVisitorAudience&quot;);             \/\/ Update HyperLogLog`s            rawva.mapToPair(t -&gt; t.swap()).groupByKey()                    .mapToPair(t -&gt; {                        HyperLogLog hll = new HyperLogLog();                        t._2().forEach(v -&gt; hll.offer(v));                        return new Tuple2&lt;&gt;(t._1(), hll);                    }).collectAsMap().forEach((k, v) -&gt; hlls.merge(k, v, (h1, h2) -&gt; HyperLogLog.merge(h1, h2)));             \/\/ Save to Aerospike and HBase            save(rawva);             return null;        });        return jssc;    } <\/code><\/pre>\n<p>  \u0417\u0434\u0435\u0441\u044c, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0434\u0432\u0430 (events \u0438 conditions) RDD (Resilient Distributed Dataset), \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f join \u043f\u043e pixel_id. \u041c\u0435\u0442\u043e\u0434 save \u2014 \u0444\u0435\u0439\u043a\u043e\u0432\u044b\u0439. \u042d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0434. \u041d\u0430 \u0435\u0433\u043e \u043c\u0435\u0441\u0442\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0439.<\/p>\n<p>  \u0417\u0430\u043f\u0443\u0441\u043a  <\/p>\n<pre><code class=\"java\">   public void run() {        create();        jssc.start();        long millis = TimeUnit.MINUTES.toMillis(CONDITION_UPDATE_PERIOD_MINUTES);        new Timer(true).schedule(new TimerTask() {            @Override            public void run() {                updateConditions();            }        }, millis, millis);         new Timer(false).scheduleAtFixedRate(new TimerTask() {            @Override            public void run() {                flushHlls();            }        }, new Date(saveHllsStartTime), TimeUnit.MINUTES.toMillis(HLLS_UPDATE_PERIOD_MINUTES));         jssc.awaitTermination();    } <\/code><\/pre>\n<p>  \u0412\u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442. \u041f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u044d\u0442\u043e\u043c\u0443 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f 2 \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0443\u0441\u043b\u043e\u0432\u0438\u0439 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f HyperLogLog. \u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432 \u043a\u043e\u043d\u0446\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f awaitTermination(), \u0438\u043d\u0430\u0447\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u0441\u044f \u043d\u0435 \u043d\u0430\u0447\u0430\u0432\u0448\u0438\u0441\u044c.  <\/div>\n<\/div>\n<p>  <\/p>\n<h5><b>\u041f\u0430\u043a\u0435\u0442\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430<\/b><\/h5>\n<p>  \u0420\u0430\u0437 \u0432 \u0434\u0435\u043d\u044c \u043f\u0435\u0440\u0435\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442 \u0432\u0441\u0435 \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u0438, \u0447\u0442\u043e \u0440\u0435\u0448\u0430\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0445 \u0438 \u0443\u0442\u0435\u0440\u044f\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445. \u0415\u0441\u0442\u044c \u0443 \u0440\u0435\u043c\u0430\u0440\u043a\u0435\u0442\u0438\u043d\u0433\u0430 \u043e\u0434\u043d\u0430 \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u0430\u044f \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u2014 \u043d\u0430\u0432\u044f\u0437\u0447\u0438\u0432\u043e\u0441\u0442\u044c \u0440\u0435\u043a\u043b\u0430\u043c\u044b. \u0417\u0434\u0435\u0441\u044c \u0432\u0441\u0442\u0443\u043f\u0430\u0435\u0442 <b>lookback window<\/b>. \u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u0430\u0442\u0430 \u0435\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432 \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u044e, \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<br \/>  \u0417\u0430\u043d\u0438\u043c\u0430\u0435\u0442 1.5-2 \u0447\u0430\u0441\u0430 \u2014 \u0432\u0441\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043d\u0430 \u0441\u0435\u0442\u044c. \u041f\u0440\u0438\u0447\u0435\u043c \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u044d\u0442\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043f\u043e \u0431\u0430\u0437\u0430\u043c: \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u0432 Aerospike 75 \u043c\u0438\u043d\u0443\u0442(\u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u043e\u0434\u043d\u043e\u043c pipeline), \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u2014 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0432 HBase \u0438 Mongo (35 \u043c\u0438\u043d\u0443\u0442).  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u043e\u0434 \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438:<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">JavaRDD&lt;Tuple3&lt;Object, String, Long&gt;&gt; av = HbaseUtil.getEventsHbaseScanRdd(jsc, hbaseConf, new Scan())                 .mapPartitions(it -&gt; {                     ArrayList&lt;Tuple3&lt;Object, String, Long&gt;&gt; list = new ArrayList&lt;&gt;();                     it.forEachRemaining(e -&gt; {                         String pixelId = e.pixelId;                         String vid = e.visitorId;                         long dt = e.date.getTime();                         List&lt;Condition&gt; cond = conditions.get(pixelId);                         if (cond != null) {                             cond.stream()                                     .filter(condition -&gt; e.date.getTime() &gt; beginTime - TimeUnit.DAYS.toMillis(condition.daysInterval)                                             && EventActionUtil.checkEvent(e, condition.condition))                                     .forEach(condition -&gt; list.add(new Tuple3&lt;&gt;(condition.id, vid, dt)));                         }                     });                     return list;                 }).persist(StorageLevel.DISK_ONLY()).setName(&quot;RawVisitorAudience&quot;); <\/code><\/pre>\n<p>  \u0417\u0434\u0435\u0441\u044c \u043f\u043e\u0447\u0442\u0438 \u0442\u043e \u0436\u0435, \u0447\u0442\u043e \u0438 \u0432 \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435, \u043d\u043e \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f join. \u0412\u043c\u0435\u0441\u0442\u043e \u043d\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 event \u043f\u043e \u0441\u043f\u0438\u0441\u043a\u0443 condition \u0441 \u0442\u0430\u043a\u0438\u043c \u0436\u0435 pixel_id. \u041a\u0430\u043a \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0442\u0430\u043a\u0430\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043c\u0435\u043d\u044c\u0448\u0435 \u043f\u0430\u043c\u044f\u0442\u0438 \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0431\u044b\u0441\u0442\u0440\u0435\u0435.  <\/div>\n<\/div>\n<p>  <\/p>\n<h5><b>\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0432 \u0431\u0430\u0437\u044b<\/b><\/h5>\n<p>  \u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0438\u0437 Kafka \u0432 HBase \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0431\u044b\u043b\u043e \u0437\u0430\u0448\u0438\u0442\u043e \u0432 \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441, \u043d\u043e \u0438\u0437-\u0437\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u0441\u0431\u043e\u0435\u0432 \u0438 \u043e\u0442\u043a\u0430\u0437\u043e\u0432 \u0431\u044b\u043b\u043e \u0440\u0435\u0448\u0435\u043d\u043e \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u0435\u0433\u043e \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f <b>Kafka Reliable Receiver<\/b>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0435 \u0442\u0435\u0440\u044f\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 Checkpoint \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043c\u0435\u0442\u0430\u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0438 \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445. <br \/>  \u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432 HBase \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043e\u043a\u043e\u043b\u043e 400 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432. \u0412\u0441\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u0431\u0430\u0437\u0435 180 \u0434\u043d\u0435\u0439 \u0438 \u0443\u0434\u0430\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u043e TTL.  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 Reliable Receiver:<\/b><\/p>\n<div class=\"spoiler_text\">\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0443\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 create() \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 JavaStreamingContextFactory \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430  <\/p>\n<pre><code class=\"java\">sparkConf.set(&quot;spark.streaming.receiver.writeAheadLog.enable&quot;, &quot;true&quot;); jssc.checkpoint(checkpointDir); <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0432\u043c\u0435\u0441\u0442\u043e  <\/p>\n<pre><code class=\"java\">JavaStreamingContext jssc = new JavaStreamingContext(sparkConf, batchInterval); <\/code><\/pre>\n<p>  \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c  <\/p>\n<pre><code class=\"java\">JavaStreamingContext jssc = JavaStreamingContext.getOrCreate(checkpointDir, new \u0412\u0430\u0448\u0420\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b\u0439\u041a\u043b\u0430\u0441\u0441()); <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0432 Aerospike \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0441\u0430\u043c\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e OutputFormat \u0438 Lua-\u0441\u043a\u0440\u0438\u043f\u0442\u0430. \u0414\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0434\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0434\u0432\u0430 \u043a\u043b\u0430\u0441\u0441\u0430 \u043a \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u0443 (<a href=\"https:\/\/github.com\/v-lukashin\/aerospike-hadoop\">\u0444\u043e\u0440\u043a<\/a>).  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 Lua-\u0441\u043a\u0440\u0438\u043f\u0442\u0430:<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">public class UpdateListOutputFormat extends com.aerospike.hadoop.mapreduce.AerospikeOutputFormat&lt;String, Bin&gt; {    private static final Log LOG = LogFactory.getLog(UpdateListOutputFormat.class);     public static class LuaUdfRecordWriter extends AsyncRecordWriter&lt;String, Bin&gt; {         public LuaUdfRecordWriter(Configuration cfg, Progressable progressable) {            super(cfg, progressable);        }         @Override        public void writeAerospike(String key, Bin bin, AsyncClient client, WritePolicy policy, String ns, String sn) throws IOException {            try {                policy.sendKey = true;                Key k = new Key(ns, sn, key);                 Value name = Value.get(bin.name);                Value value = bin.value;                Value[] args = new Value[]{name, value, Value.get(System.currentTimeMillis() \/ 1000)};                 String packName = AeroUtil.getPackage(cfg);                String funcName = AeroUtil.getFunction(cfg); \t\t\/\/ Execute lua script                client.execute(policy, null, k, packName, funcName, args);            } catch (Exception e) {                LOG.error(&quot;Wrong put operation: \\n&quot; + e);            }        }    }     @Override    public RecordWriter&lt;String, Bin&gt; getAerospikeRecordWriter(Configuration entries, Progressable progressable) {        return new LuaUdfRecordWriter(entries, progressable);    } } <\/code><\/pre>\n<p>  \u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438\u0437 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0430\u043a\u0435\u0442\u0430.  <\/div>\n<\/div>\n<p>  \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432 \u0441\u043f\u0438\u0441\u043e\u043a \u043d\u043e\u0432\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439.  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Lua-\u0441\u043a\u0440\u0438\u043f\u0442:<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"lua\">local split = function(str)    local tbl = list()    local start, fin = string.find(str, &quot;,[^,]+$&quot;)    list.append(tbl, string.sub(str, 1, start - 1))    list.append(tbl, string.sub(str, start + 1, fin))    return tbl end local save_record = function(rec, name, mp)    local res = list()    for k,v in map.pairs(mp) do        list.append(res, k..&quot;,&quot;..v)    end     rec[name] = res     if aerospike:exists(rec) then        return aerospike:update(rec)    else        return aerospike:create(rec)    end end function put_in_list_first_ts(rec, name, value, timestamp)     local lst = rec[name]     local mp = map()      if value ~= nil then         if list.size(value) &gt; 0 then             for i in list.iterator(value) do                 mp[i] = timestamp end         end     end      if lst ~= nil then         if list.size(lst) &gt; 0 then             for i in list.iterator(lst) do                 local sp = split(i)                 mp[sp[1]] = sp[2] end         end     end      return save_record(rec, name, mp) end <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u042d\u0442\u043e\u0442 \u0441\u043a\u0440\u0438\u043f\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0432 \u0441\u043f\u0438\u0441\u043e\u043a \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u0439 \u043d\u043e\u0432\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432\u0438\u0434\u0430 \u00abaudience_id,timestamp\u00bb. \u0415\u0441\u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442, \u0442\u043e timestamp \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u0436\u043d\u0438\u043c.<\/p>\n<p>  \u0425\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0441\u0442\u0438\u043a\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u0432, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f:<br \/>  Intel Xeon E5-1650 6-cores 3.50 GHz (HT), 64GB DDR3 1600;<br \/>  \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 CentOS 6;<br \/>  \u0412\u0435\u0440\u0441\u0438\u044f CDH 5.4.0.<\/p>\n<p>  \u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/211\/7a0\/cb4\/2117a0cb4d44422695a4179c4583aaab.jpg\"\/><\/p>\n<h4><b>\u0412 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438<\/b><\/h4>\n<p>  \u041d\u0430 \u043f\u0443\u0442\u0438 \u043a \u0434\u0430\u043d\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u044b \u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 (\u0421#, Hadoop MapReduce \u0438 Spark) \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0441 \u0437\u0430\u0434\u0430\u0447\u0430\u043c\u0438 \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0442\u0430\u043a \u0438 \u043f\u0435\u0440\u0435\u0441\u0447\u0451\u0442\u043e\u0432 \u043e\u0433\u0440\u043e\u043c\u043d\u044b\u0445 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445. \u0417\u0430 \u0441\u0447\u0451\u0442 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e\u0433\u043e \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u043b\u044f\u043c\u0431\u0434\u0430 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b, \u043f\u043e\u0432\u044b\u0441\u0438\u043b\u043e\u0441\u044c \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u0434\u0430. \u0412\u0440\u0435\u043c\u044f \u043f\u043e\u043b\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u043d\u044b\u0445 \u043a\u0430\u043d\u0430\u043b\u043e\u0432, \u0441\u043d\u0438\u0437\u0438\u043b\u043e\u0441\u044c \u0441 \u0434\u0435\u0441\u044f\u0442\u043a\u0430 \u0447\u0430\u0441\u043e\u0432, \u0434\u043e \u0434\u0435\u0441\u044f\u0442\u043a\u0430 \u043c\u0438\u043d\u0443\u0442. \u0410 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u0430\u044f \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u043c\u043e\u0441\u0442\u044c \u0441\u0442\u0430\u043b\u0430 \u043a\u0430\u043a \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u0439. <br \/>  \u041f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u0432\u044b \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430 \u043d\u0430\u0448\u0435\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435 <a href=\"http:\/\/hybrid.ru\">Hybrid<\/a>.<\/p>\n<h4><b>P.S.<\/b><\/h4>\n<p>  \u041e\u0441\u043e\u0431\u0430\u044f \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f  <a href=\"http:\/\/habrahabr.ru\/users\/danilaperepechin\/\" class=\"user_link\">DanilaPerepechin<\/a> \u0437\u0430 \u043d\u0435\u043e\u0446\u0435\u043d\u0438\u043c\u0443\u044e \u043f\u043e\u043c\u043e\u0449\u044c \u0432 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u0441\u0442\u0430\u0442\u044c\u0438.     \t<\/p>\n<div class=\"clear\"><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/266009\/\"> http:\/\/habrahabr.ru\/post\/266009\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>     \t\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0446\u0438\u043a\u043b \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u0440\u043e DMP \u0438 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0441\u0442\u0435\u043a \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 <a href=\"http:\/\/targetix.net\/\">Targetix<\/a>.<br \/>  \u041d\u0430 \u044d\u0442\u043e \u0440\u0430\u0437 \u0440\u0435\u0447\u044c \u043f\u043e\u0439\u0434\u0435\u0442 \u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0432 \u043d\u0430\u0448\u0435\u0439 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 <b><a href=\"http:\/\/spark.apache.org\/\">Apache Spark<\/a><\/b> \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442e, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0440\u0435\u043c\u0430\u0440\u043a\u0435\u0442\u0438\u043d\u0433\u043e\u0432\u044b\u0435 \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u0438. <br \/>  \u0418\u043c\u0435\u043d\u043d\u043e \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u043e\u043c\u0443 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0443, \u043e\u0434\u043d\u0430\u0436\u0434\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0432 \u043b\u043e\u0431\u0437\u0438\u043a, \u0432\u044b \u0431\u0443\u0434\u0435\u0442\u0435 \u0432\u0438\u0434\u0435\u0442\u044c \u0435\u0433\u043e \u0432\u043e \u0432\u0441\u0435\u0445 \u0443\u0433\u043e\u043b\u043a\u0430\u0445 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0430 \u0434\u043e \u043a\u043e\u043d\u0446\u0430 \u0441\u0432\u043e\u0435\u0439 \u0436\u0438\u0437\u043d\u0438.<br \/>  \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0438 \u043d\u0430\u0431\u0438\u043b\u0438 \u043f\u0435\u0440\u0432\u044b\u0435 \u0448\u0438\u0448\u043a\u0438 \u0432 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0438 \u0441 Apache Spark. <br \/>  \u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0438 Spark-\u043a\u043e\u0434 \u043f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c.<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/833\/c23\/2aa\/833c232aaea64f228ad5ee8075dc1601.jpg\"\/>  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-264933","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/264933","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=264933"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/264933\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=264933"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=264933"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=264933"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}