У меня есть следующий код внутри моей функции сокращения. Когда я пытаюсь сделать мелкую копию с помощью CollectionUtils.addAll, копия не удалась; все элементы будут иметь ссылку на элемент LAST вместо других элементов в итераторе.Итеративное значение Reducer, по-видимому, непоследовательно в Java MapReduce
Вот код из моего Reducer:
public void reduce(Text key, Iterable<ArrayListWritable<Writable>> values, Context context)
throws IOException, InterruptedException {
ArrayList<ArrayListWritable<Writable>> listOfWordPairs = new ArrayList<ArrayListWritable<Writable>>();
// CollectionUtils.addAll(listOfWordPairs, values.iterator());
// listOfWordPairs seems to all be the last item in the iterator
Iterator<ArrayListWritable<Writable>> iter = values.iterator();
// Manually do the copy
while (iter.hasNext()) {
// listOfWordPairs.add(iter.next());
//Same behaviour as CollectionUtils.addAll()
listOfWordPairs.add(new ArrayListWritable<Writable>(iter.next()));
//Only working way to do it -> deep copy :(
}
}
Кто-нибудь есть какие-либо идеи, почему это происходит? Я вижу, что если MR реализовала его таким образом, он может сэкономить довольно большой кусок памяти, но, похоже, здесь происходит какая-то магия, чтобы это произошло. Я новичок в MR так что надеюсь, вопрос не слишком глуп ...
Вот мой MAP код для людей, которые заинтересованы
@Override
public void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
Map<String, HMapStFW> stripes = new HashMap<>();
List<String> tokens = Tokenizer.tokenize(value.toString());
if (tokens.size() < 2) return;
context.getCounter(StripesPmiEnums.TOTALENTRIES).increment(tokens.size());
for (int i = 0; i < tokens.size() && i<40; i++) {
for (int j = 0;j<tokens.size() && j<40;j++){
if (j == i)
continue;
//Make Stripe if doesn't exist
if (!stripes.containsKey(tokens.get(i))){
HMapStFW newStripe = new HMapStFW();
stripes.put(tokens.get(i), newStripe);
}
HMapStFW stripe = stripes.get(tokens.get(i));
if (stripe.containsKey(tokens.get(j))){
stripe.put(tokens.get(j), stripe.get(tokens.get(j))+1.0f);
}else{
stripe.put(tokens.get(j), 1.0f);
}
}
}
for (String word1 : stripes.keySet()) {
TEXT.set(word1);
context.write(TEXT, stripes.get(word1));
}
}
А также ArrayListWritable доступна здесь https://github.com/lintool/tools/blob/master/lintools-datatypes/src/main/java/tl/lin/data/array/ArrayListWritable.java
Это кажется мне переопределить записываемый вы можете поделиться этим кодом вместе с кодом mapper. –
@siddhartha jain Я добавил его в OP – user3538310
Возможный дубликат [Hadoop MapReduce итерации по входным значениям вызова сокращения] (http://stackoverflow.com/questions/15976981/hadoop-mapreduce-iterate-over-input-values -of-а-снизить-вызов) –