저는 Hadoop 프로젝트에서 일하고 있습니다. 내 감축 단계는 매우 비쌉니다. 현재 HashMap을 사용하고 있지만 Reduce에서 거대한 해시 맵 (데이터 세트가 32GB)을 만들기 때문에 Error: Java Heap space
이 표시됩니다. 이 솔루션은 디스크 폴백 (fallback) 기능이있는 메모리 내 (in-memory) Hashmap이 될 수 있으며 MapDB는 내 필요에 맞는 것 같습니다. 하지만 사용법에 대해서는 잘 모르겠습니다. diskMap은 각 Reduce Task마다 고유하며, inMemory 맵은 각 단축키마다 고유합니다. 테스트를 위해 expireMaxSize(3)
을 설정하더라도 onDisk 맵이 사용되는시기와 논리가 올바른지 잘 모르겠습니다. 다시 말하지만, 테스트를 위해 hashmap을 20 개의 가짜 항목으로 채 웁니다. 기본적으로 힙 오버플로를 방지하려면 inMemory 맵 증가를 제어해야합니다.디스크 폴백을 통한 MapDB 메모리 내
public class TestReducer extends Reducer<LongWritable, BytesWritable, String, IntWritable> {
private int id;
DB dbDisk;
protected void setup(Context context) throws IOException, InterruptedException {
id = context.getTaskAttemptID().getTaskID().getId();
File diskmap = new File("tmp/diskmap"+id);
diskmap.delete();
dbDisk = DBMaker
.fileDB("tmp/diskmap"+id)
.make();
}
@Override
protected void reduce(LongWritable key, Iterable<BytesWritable> values, Context context)
throws IOException, InterruptedException {
DB dbMemory = DBMaker
.memoryDB()
.make();
HTreeMap<Long,Integer> onDisk = dbDisk
.hashMap("onDisk")
.keySerializer(Serializer.LONG)
.valueSerializer(Serializer.INTEGER)
.createOrOpen();
// fast in-memory collection with limited size
HTreeMap<Long,Integer> inMemory = dbMemory
.hashMap("inMemory")
.expireMaxSize(3)
.keySerializer(Serializer.LONG)
.valueSerializer(Serializer.INTEGER)
//this registers overflow to `onDisk`
.expireOverflow(onDisk)
.createOrOpen();
for(int k=0;k<20;k++){
inMemory.put((long)k,k*2);
}
Set set = inMemory.entrySet();
Iterator it = set.iterator();
while(it.hasNext()) {
Map.Entry<Long,Integer> entry = (Map.Entry<Long,Integer>)it.next();
System.out.print("Key is: "+entry.getKey() + " & ");
System.out.println("Value is: "+entry.getValue());
}
}
protected void cleanup(Context context) throws IOException,InterruptedException {
dbDisk.close();
}
}
나는 MapDB를 사용한 적이 없지만 SQLite를 사용하기 쉽습니다. 사용하기 쉽고 올바른 작업을 수행해야합니다. – vgunnu