Bunu hadoop kullanıcı posta listesine çapraz gönderme konusunda üzgünüm ve bu benim için acil bir konu oluyor. aşağıdaki gibiHesaplama kesişimi ve hadoop ile iki dosyanın kayıtlarının farkını ayarlama
Benim sorundur: Ben iki giriş dosyaları var ve ben belirlemek istiyorum
- a) yalnızca) 1
- b dosyasındaki satır sayısını meydana hatlarının sayısı hangi: sadece dosyanın 2
- c) Her iki (örneğin ip eşitliği açısından) içerisinde
Örnek ortak hat sayısı ile meydana 210
File 1:
a
b
c
File 2:
a
d
her durum için
İstenilen çıktı:
lines_only_in_1: 2 (b, c)
lines_only_in_2: 1 (d)
lines_in_both: 1 (a)
Temelde yaklaşımım şu şekildedir: mapper hattı (metin) ve byte oluşan bir çift alır böylece, kendi LineRecordReader yazdı Kaynak dosyayı gösterir (0 veya 1). Eşleştirici, eşleştirmeyi yalnızca tekrar döndürür, böylece hiçbir şey yapmaz. Ancak, yan etki, birleştirici alan olduğu bir
Map<Line, Iterable<SourceId>>
(sourceid, 0 veya 1).
Şimdi, her hat için ben kaynaklarının setini alabilirsiniz içeri. Bu nedenle, her vaka için sayar bir birleştirici (Liste 1) hatların (a, b, c) numarayı
yazabiliriz görünürBirleştirici, daha sonra, yalnızca temizlikte bir 'özet' çıkarır (bu güvenli midir?). Sonra sadece bu özetleri değerlerini özetlemek redüktör olarak
lines_only_in_1 2531
lines_only_in_2 3190
lines_in_both 901
: gibi Yani bu özet görünüyor. (Bu nedenle redüktörün çıkışı, birleştiricininki gibi görünür).
Ancak, asıl sorun ben formu (hat, sourceid) verimi kayıtları // sourceid ya 0 ya
1 Ve ben tek bir sanal dosya olarak hem kaynak dosyaları tedavi etmek gerek yani, Bunu nasıl elde edeceğimi bilmiyorum. Soru şu ki, ön işleme ve dosyaların önceden birleştirilmesini önleyip durduramam ve bunu sanal olarak birleştirilen dosya okuyucusu ve özel kayıt okuyucusu gibi bir şeyle anında gerçekleştirebiliyorum. Herhangi bir kod örneği çok takdir edilmektedir.
Saygılarımızla, Claus
İlanı 1:
public static class SourceCombiner
extends Reducer<Text, ByteWritable, Text, LongWritable> {
private long countA = 0;
private long countB = 0;
private long countC = 0; // C = lines (c)ommon to both sources
@Override
public void reduce(Text key, Iterable<ByteWritable> values, Context context) throws IOException, InterruptedException {
Set<Byte> fileIds = new HashSet<Byte>();
for (ByteWritable val : values) {
byte fileId = val.get();
fileIds.add(fileId);
}
if(fileIds.contains((byte)0)) { ++countA; }
if(fileIds.contains((byte)1)) { ++countB; }
if(fileIds.size() >= 2) { ++countC; }
}
protected void cleanup(Context context)
throws java.io.IOException, java.lang.InterruptedException
{
context.write(new Text("in_a_distinct_count_total"), new LongWritable(countA));
context.write(new Text("in_b_distinct_count_total"), new LongWritable(countB));
context.write(new Text("out_common_distinct_count_total"), new LongWritable(countC));
}
}
Merhaba, biraz belirsiztim: Buradaki nokta, birleştiricilerin yalnızca özetlemeyi (1, 2 ve ortak satır sayısı) redüktöre vermesini istediğimdir - tüm satırlara gerek yoktur redüktöre geri gönderilir. Ancak bunun çalışması için, birleştiriciler her iki dosyanın kayıtlarını birlikte görmelidir (benim RecordReader zaten üretir (line, fileId) çiftleridir, dosya adından fileId'ye eşleme, config nesnesine iletilir). Ancak, dosyaları iki FileInputFormat.addInputPath (iş, dosya) deyimleriyle eklerken, dosyalar tek tek işlenir, böylece birleştiriciler "sendikalarını" görmezler. –
bazı gerçekten garip "optimizasyon" dır. Ama iyi bir nokta. Geç yanıt için –
Sry; Bu benim düşüncem mümkün değil: Kaynak dosya ayrıldı ve bölmeler düğümlere gönderilir. Düğümler daha sonra ilgili bölümlerden kayıtları okuyor. Bu nedenle, kaynak dosyasındaki yinelenen kayıtlar birkaç bölüme yerleştirilebilir ve dolayısıyla çeşitli düğümlere yayılabilir. Bu nedenle çiftlerin gruplandırılması sadece redüktörde mümkündür. Bu doğru mu? –