Чтение Hadoop SequenceFiles с помощью Hive

У меня есть некоторые сопоставленные данные из Common Crawl, которые я сохранил в формате SequenceFile. Я неоднократно пытался использовать эти данные "как есть" с Hive, чтобы я мог запрашивать и пробовать их на разных этапах. Но я всегда получаю следующую ошибку в выводе моей работы:

LazySimpleSerDe: expects either BytesWritable or Text object!

Я даже создал более простой (и меньший) набор данных из записей [Text, LongWritable], но это также не помогает. Если я вывожу данные в текстовый формат, а затем создаю таблицу, это работает нормально:

hive> create external table page_urls_1346823845675
    >     (pageurl string, xcount bigint) 
    >     location 's3://mybucket/text-parse/1346823845675/';
OK
Time taken: 0.434 seconds
hive> select * from page_urls_1346823845675 limit 10;
OK
http://0-italy.com/tag/package-deals    643    NULL
http://011.hebiichigo.com/d63e83abff92df5f5913827798251276/d1ca3aaf52b41acd68ebb3bf69079bd1.html    9    NULL
http://01fishing.com/fly-fishing-knots/    3437    NULL
http://01fishing.com/flyin-slab-creek/    1005    NULL
...

Я попытался использовать пользовательский формат ввода:

// My custom input class--very simple
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.SequenceFileInputFormat;
public class UrlXCountDataInputFormat extends 
     SequenceFileInputFormat<Text, LongWritable> {  }

Затем я создаю таблицу с помощью:

create external table page_urls_1346823845675_seq 
  (pageurl string, xcount bigint) 
  stored as inputformat 'my.package.io.UrlXCountDataInputFormat' 
  outputformat 'org.apache.hadoop.mapred.SequenceFileOutputFormat'  
  location 's3://mybucket/seq-parse/1346823845675/';

Но я все равно получаю ту же ошибку SerDer.

Я уверен, что есть кое-что действительно простое, что я упускаю здесь, но я не могу понять это правильно. Кроме того, я должен иметь возможность анализировать SequenceFiles на месте (т.е. я не могу преобразовать свои данные в текст). Поэтому мне нужно выяснить подход SequenceFile для будущих частей моего проекта.


Решение: как указано ниже @mark-grover, проблема в том, что Hive игнорирует ключ по умолчанию. Имея только один столбец (т.е. только значение), серверу не удалось сопоставить мой второй столбец.

Решение состояло в том, чтобы использовать пользовательский InputFormat, который был намного более сложным, чем тот, который я использовал изначально. Я отследил один ответ по ссылке на Git об использовании ключей вместо значений, а затем изменил его в соответствии со своими потребностями: взял ключ и значение из внутреннего SequenceFile.Reader и затем объединил их в окончательный вариант BytesWritable. Т.е. что-то вроде этого (из кастомного ридера, где и происходит вся тяжелая работа):

// I used generics so I can use this all with 
// other output files with just a small amount
// of additional code ...
public abstract class HiveKeyValueSequenceFileReader<K,V> implements RecordReader<K, BytesWritable> {

    public synchronized boolean next(K key, BytesWritable value) throws IOException {
        if (!more) return false;

        long pos = in.getPosition();
        V trueValue = (V) ReflectionUtils.newInstance(in.getValueClass(), conf);
        boolean remaining = in.next((Writable)key, (Writable)trueValue);
        if (remaining) combineKeyValue(key, trueValue, value);
        if (pos >= end && in.syncSeen()) {
          more = false;
        } else {
          more = remaining;
        }
        return more;
    }

    protected abstract void combineKeyValue(K key, V trueValue, BytesWritable newValue);

}

// from my final implementation
public class UrlXCountDataReader extends HiveKeyValueSequenceFileReader<Text,LongWritable>
    @Override
    protected void combineKeyValue(Text key, LongWritable trueValue, BytesWritable newValue) {
        // TODO I think we need to use straight bytes--I'm not sure this works?
        StringBuilder builder = new StringBuilder();
        builder.append(key);
        builder.append('\001');
        builder.append(trueValue.get());
        newValue.set(new BytesWritable(builder.toString().getBytes()) );
    }
}

С этим я получаю все свои столбцы!

http://0-italy.com/tag/package-deals    643
http://011.hebiichigo.com/d63e83abff92df5f5913827798251276/d1ca3aaf52b41acd68ebb3bf69079bd1.html    9
http://01fishing.com/fly-fishing-knots/ 3437
http://01fishing.com/flyin-slab-creek/  1005
http://01fishing.com/pflueger-1195x-automatic-fly-reels/    1999

1 ответ

Решение

Не уверен, влияет ли это на вас, но Hive игнорирует ключи при чтении SequenceFiles. Возможно, вам придется создать собственный InputFormat (если вы не можете найти его онлайн:-))

Ссылка: http://mail-archives.apache.org/mod_mbox/hive-user/200910.mbox/%3C5573211B-634D-4BB0-9123-E389D90A786C@metaweb.com%3E

Другие вопросы по тегам