Чтение 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 (если вы не можете найти его онлайн:-))