Hive UDF 'org.apache.hadoop.hive.contrib.udf.UDFRowSequence', генерирующий одинаковое значение для первых двух записей - PullRequest
0 голосов
/ 03 мая 2018

Я пытаюсь сгенерировать значения автоинкремента, используя Hive UDF UDFRowSequence, но генерирует один и тот же идентификатор для первых двух записей.

+-------+----------+---+-------------------+
|rank_id|     state| id|           datetime|
+-------+----------+---+-------------------+
|      1|New Jersey| 10|2018-03-27 10:00:00|
|      1|     Tamil| 25|2018-03-27 11:05:00|
|      2|   TamilNa| 25|2018-03-27 11:15:00|
|      3| TamilNadu| 25|2018-03-27 11:25:00|
|      4|   Gujarat| 30|2018-03-27 11:00:00|
+-------+----------+---+-------------------+

Вот код, который я использую для автоинкремента.

package org.apache.hadoop.hive.contrib.udf;

import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.hive.ql.udf.UDFType;
import org.apache.hadoop.io.LongWritable;

/**
 * UDFRowSequence.
 */
@Description(name = "row_sequence",
    value = "_FUNC_() - Returns a generated row sequence number starting from 1")
@UDFType(deterministic = false, stateful = true)
public class UDFRowSequence extends UDF
{
  private LongWritable result = new LongWritable();

  public UDFRowSequence() {
    result.set(0);
  }

  public LongWritable evaluate() {
    result.set(result.get() + 1);
    return result;
  }
}

Может кто-нибудь сказать мне, что я делаю неправильно, когда генерирует один и тот же идентификатор для первых двух записей.

1 Ответ

0 голосов
/ 04 мая 2018

Видимо, вы не делаете ничего плохого. Но, похоже, такого решения не существует.

Причина, по которой вы получаете повторяющиеся числа, в основном потому, что ваша оценка происходит в 2-х мапперах (если вы используете искровую машину, то 2-х исполнителей). И у каждого исполнителя UDF начнет последовательность с 1. Таким образом, одно и то же значение для первых двух записей случайно. Результаты могут отличаться в зависимости от того, сколько картографов используется для выполнения запроса.

Вы можете достичь того, что хотите, ограничив количество исполнителей до 1. С точки зрения искры, я думаю, вы можете использовать операцию repartition(1).

Также посмотрите @ this thread , в котором есть несколько полезных моментов.

...