可能的解決方案是在運行作業012xx之前將stopwords.txt複製到HDFS,然後在Mapper的setup方法中將其讀入適當的數據結構中。 E.g:
MyMapper類:
...
private Map<String, Object> stopwords = null;
@Override
public void setup(Context context) {
Configuration conf = context.getConfiguration();
//hardcoded or set it in the jobrunner class and retrieve via this key
String location = conf.get("job.stopwords.path");
if (location != null) {
BufferedReader br = null;
try {
FileSystem fs = FileSystem.get(conf);
Path path = new Path(location);
if (fs.exists(path)) {
stopwords = new HashMap<String, Object>();
FSDataInputStream fis = fs.open(path);
br = new BufferedReader(new InputStreamReader(fis));
String line = null;
while ((line = br.readLine()) != null && line.trim().length() > 0) {
stopwords.put(line, null);
}
}
}
catch (IOException e) {
//handle
}
finally {
IOUtils.closeQuietly(br);
}
}
}
...
然後你可以使用禁用詞地圖中的方法。
另一個選擇是用jobrunner類中的停用詞創建地圖對象, 將其序列化爲Base64編碼的字符串,將其作爲Configuration對象中的某個鍵的值傳遞給映射器,並在設置中將其反序列化方法。
我會選擇第一個選項,不僅僅因爲它更簡單,而且因爲通過Configuration對象傳遞更多數據不是一個好主意。
我是否正確理解該設置僅被調用一次?因爲那正是我需要的。 – benehsv
是的。在每個map/reduce任務中,會發生以下情況:對於每個輸入記錄,調用一次setup(),然後調用map()/ reduce(),最後清理() –
而不是使用停用詞的Map並執行stopwords.put(line ,null),你可以使用HashSet並做stopwords.add(line)。 – Naijaba