2012-11-02 42 views
5

Tôi có một số dữ liệu bản đồ từ Common Crawl mà tôi đã lưu trữ ở định dạng SequenceFile. Tôi đã thử nhiều lần để sử dụng dữ liệu này "như là" với Hive vì vậy tôi có thể truy vấn và lấy mẫu ở các giai đoạn khác nhau. Nhưng tôi luôn luôn nhận được lỗi sau đây trong sản lượng công việc của tôi:Đọc Hadoop SequenceFiles với Hive

LazySimpleSerDe: expects either BytesWritable or Text object! 

Tôi thậm chí còn xây dựng một tập dữ liệu đơn giản (và nhỏ hơn) của [Lưu LongWritable,] hồ sơ, nhưng điều đó không là tốt. Nếu tôi xuất dữ liệu sang định dạng văn bản và sau đó tạo ra một bảng trên đó, nó hoạt động tốt:

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

tôi đã cố gắng sử dụng một inputformat tùy chỉnh:

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

tôi tạo ra bảng sau đó với:

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

Nhưng tôi vẫn gặp lỗi SerDer giống nhau.

Tôi chắc chắn có điều gì đó thực sự cơ bản tôi đang thiếu ở đây, nhưng tôi dường như không thể làm đúng. Ngoài ra, tôi phải có khả năng phân tích cú pháp SequenceFiles tại chỗ (nghĩa là tôi không thể chuyển đổi dữ liệu của mình thành văn bản). Vì vậy, tôi cần phải tìm ra cách tiếp cận SequenceFile cho các phần tương lai của dự án của tôi.


Giải pháp: Như @ đánh dấu grover chỉ ra dưới đây, vấn đề là Hive bỏ qua phím theo mặc định. Chỉ với một cột (tức là chỉ giá trị), thì serder không thể ánh xạ cột thứ hai của tôi.

Giải pháp là sử dụng một InputFormat tùy chỉnh phức tạp hơn nhiều so với những gì tôi đã sử dụng ban đầu. Tôi đã theo dõi một câu trả lời ở liên kết đến Git về việc sử dụng các phím thay vì các giá trị, và sau đó tôi sửa đổi nó cho phù hợp với nhu cầu của tôi: lấy khóa và giá trị từ một SequenceFile.Reader nội bộ và sau đó kết hợp chúng thành BytesWritable cuối cùng. I E. một cái gì đó như thế này (từ Reader tùy chỉnh, vì đó là nơi tất cả các công việc khó khăn xảy ra):

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

Với điều đó, tôi nhận được tất cả các cột của mình!

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

Tìm thấy một cuộc thảo luận chi tiết hơn về việc sử dụng phím thay vì các giá trị ở đây: [apache chủ đề hive] (http://mail-archives.apache.org/mod_mbox/hive-user/201204.mbox/%[email protected].com%3E), dẫn tôi đến [gist] (https://gist.github.com/2421795) có định dạng và trình đọc tùy chỉnh. Sử dụng hai liên kết đó cùng với thông tin khác đã cho phép tôi tạo cấu trúc bên trên. – codingmonk

Trả lời

0

Không chắc chắn nếu điều này ảnh hưởng đến bạn nhưng Hive bỏ qua các phím khi đọc SequenceFiles. Bạn có thể cần phải tạo ra một InputFormat tùy chỉnh (trừ khi bạn có thể tìm thấy một :-) trực tuyến)

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

+0

Đúng, dường như là vấn đề của tôi. I E. nó bỏ qua chìa khóa, sau đó tiếp tục cố gắng và tìm cột thứ hai - và không thể tìm thấy nó. Tôi sẽ đăng thêm chi tiết với tất cả chi tiết về những gì tôi phải làm, vì liên kết đó chứa một vài giải pháp khác nhau. – codingmonk

Các vấn đề liên quan