2012-11-02 6 views
5

Ich habe einige MapRed-Daten aus dem Common Crawl, die ich in einem SequenceFile-Format gespeichert habe. Ich habe wiederholt versucht, diese Daten "wie besehen" mit Hive zu verwenden, so dass ich sie in verschiedenen Phasen abfragen und abfragen kann. Aber ich bekomme immer folgende Fehler in meiner Job-Ausgabe:Lesen von Hadoop SequenceFiles mit Hive

LazySimpleSerDe: expects either BytesWritable or Text object! 

Ich habe sogar eine einfachere (und kleiner) Datensatz von [Text, LongWritable] Aufzeichnungen aufgebaut, aber das nicht so gut. Wenn ich die Daten auszugeben in Textformat und dann eine Tabelle auf, dass erstellen, es funktioniert gut:

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 
... 

Ich habe versucht, eine benutzerdefinierte Inputformat mit:

// 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> { } 

ich die Tabelle erstellen dann mit:

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/'; 

Aber ich bekomme immer noch den gleichen SerDer Fehler.

Ich bin sicher, es gibt etwas wirklich Grundlegendes Ich vermisse hier, aber ich kann nicht scheinen, es richtig zu machen. Außerdem muss ich in der Lage sein, die SequenceFiles an Ort und Stelle zu analysieren (d. H. Ich kann meine Daten nicht in Text konvertieren). Daher muss ich den SequenceFile-Ansatz für zukünftige Teile meines Projekts herausfinden.


Lösung: Als @ mark-Grover unten wies darauf hin, das Problem ist, dass Hive den Schlüssel standardmäßig ignoriert. Mit nur einer Spalte (d. H. Nur dem Wert) konnte der Serder meine zweite Spalte nicht zuordnen.

Die Lösung bestand darin, ein benutzerdefiniertes InputFormat zu verwenden, das sehr viel komplexer war als das, was ich ursprünglich verwendet hatte. Ich fand eine Antwort auf den Link zu einem Git über die Verwendung der Schlüssel anstelle der Werte, und dann änderte ich es nach meinen Bedürfnissen: nimm den Schlüssel und den Wert von einem internen SequenceFile.Reader und kombiniere sie dann zum endgültigen BytesWritable. I.e. so etwas wie dies (aus dem benutzerdefinierten Reader, wie das ist, wo all die harte Arbeit geschieht):

// 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())); 
    } 
} 

Damit ich alle meine Spalten!

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 
+0

Gefunden eine ausführlichere Diskussion über den Schlüssel anstelle der Werte verwenden hier: [Apache Hive thread] (http://mail-archives.apache.org/mod_mbox/hive-user/201204.mbox/%[email protected].com%3E), die mich zum [gist] führen (https://gist.github.com/2421795), die ein benutzerdefiniertes Format und einen Reader hatte. Die Verwendung dieser beiden Links und die anderen Informationen erlaubten mir, das obige zu konstruieren. – codingmonk

Antwort

0

Nicht sicher, ob dies Auswirkungen auf Sie hat, aber Hive ignoriert Schlüssel beim Lesen von SequenceFiles. Möglicherweise müssen Sie eine benutzerdefinierte Inputformat erstellen (es sei denn, Sie ein Online-:-) finden)

Referenz: http://mail-archives.apache.org/mod_mbox/hive-user/200910.mbox/%[email protected]%3E

+0

Ja, das scheint mein Problem zu sein. I.e. Sie ignorierte den Schlüssel und fuhr dann fort, die zweite Spalte zu suchen - und konnte keine finden. Ich werde eine weitere Details mit allen Details von dem, was ich tun musste, posten, da dieser Link ein paar verschiedene Lösungen enthielt. – codingmonk

Verwandte Themen