똑같은 실수의 반복
- Posted at 2008/11/09 19:00
- Filed under project/lucene_hadoop
의도한 대로 동작하지 않는 프로그램 때문에 토/일 집에서 계속 모티어만 뚫어지게 쳐바 보았습니다.
모두 패떳을 모면서 키득대고 있는데 지난주에 포스팅한 글이 갑자기 떠올랐습니다.
http://www.jaso.co.kr/303
Reduce에서 매번 새로운 객체를 생성하지 않고 하나 만들어서 재사용한다는 글이 있었는데 문제의 원인은 여기에 있었습니다.
map에서 여러개의 값을 넘겨주고자 별도의 사용자 정의 클래스를 하나 만들었습니다.
public class MyVO implements Writable {
HashSet<String> objects = new HashSet<String>();
public MyVO() {
}
public MyVO(HashSet<String> objects) {
this.objects = objects;
}
@Override
public void readFields(DataInput in) throws IOException {
int size = in.readInt();
for(int i = 0; i < size; i++) {
objects.add(WritableUtils.readString(in));
}
}
@Override
public void write(DataOutput out) throws IOException {
out.writeInt(objects.size());
for(String eachObject: objects) {
WritableUtils.writeString(out, eachObject);
}
}
}
Hadoop이 Reduce task를 실행시키면 reduce task는 map에서 전달된 값을 sort 하면서 reduce() 을 호출합니다. 이때 전달되는 값을 다음과 같은 로직으로 만들어서 전달합니다.(Hadoop의 WritableSerialization 클래스 중)
public Writable deserialize(Writable w) throws IOException {
Writable writable;
if (w == null) {
writable
= (Writable) ReflectionUtils.newInstance(writableClass, getConf());
} else {
writable = w;
}
writable.readFields(dataIn);
return writable;
}
이 코드에 보면 기존 value 가 null인 경우에는(w == null) 새로운 객체를 만들고 그렇지 않느면 기존 객체에 readFields()를 바로 호출해서 사용합니다. 이런 상황에서 위의 MyVO의 readFileds() 메소드의 구현을 보면 objects.add()가 호출됩니다.
deserialize()가 호출될 때 마다 값이 계속 증가하게 되어 예상하지 않은 값이 objects에 계속 add 되게 됩니다. 따라서 MyVO의 readFields 부분을 다음과 같이 수정해야 합니다.
@Override
public void readFields(DataInput in) throws IOException {
int size = in.readInt();
objects.clear();
for(int i = 0; i < size; i++) {
objects.add(WritableUtils.readString(in));
}
}
요즘 삽질을 너무 많이 하고 있다는 생각이 드네요... 슬럼픈가?
Posted by 김형준
- Response
- No Trackback , 4 Comments
Trackback URL : http://www.jaso.co.kr/trackback/308
Comments List
-
왜 이런걸 실수할까 ㅋㅋㅋ
-
예전에 저도 그거때문에 당한 적이 있어요. 객체를 모아놓고 나중에 보니 전부 같은 값이 들어있어서.. 처음엔 버그인줄 알았는데 메모리 아끼는 feature라서 당황.
객체 재사용은 코드로는 오래전부터 되어 있었는데, 문서화는 0.17.x인가 꽤 늦게 된 편이에요. hadoop이 문서화가 좀 엉망이라.. 옛날 버전 기반으로 작업한다고 해도 문제가 생긴다면 최신 문서를 참고해보는 것도 좋을 거에요. -
또 당했음 ㅋㅋㅋ.
-
ㅋㅋㅋ 눈뜨고도 당하는...
-






