基於hadoop搜尋引擎實踐——二級索引檔案(五)
public class SplitFilePartitioner<K, V> extends Partitioner<K, V> { public static int lastID = 0; @Override public int getPartition(K key, V value, int partitionNum) { this.lastID++; lastID = (this.lastID % partitionNum); return lastID; } }
2.生成二級索引檔案 分割後的倒排字表檔案中都互不重複地儲存了倒排檔案的部分資訊。然而,在執行一個查詢TERM的命令時,系統並不知道"TERM_RECORD"儲存在哪個字表中。因此,需要建立一個索引檔案,該檔案儲存每個TERM與其所在字表(包括在字表中位置)的對映關係,具體格式定義如下: (1)索引檔案(INDEX_FILE)由若干詞及其索引資訊組成。每個詞及其索引資訊是由一個索引詞(TERM)和該詞的索引資訊(INDEX_INFO)組成的,其中TERM和INDEX_INFO之間用空格隔開。索引詞記錄按照順序最佳的方式存放,之間用製表符分隔,表示格式如下: TERM+'\t'+INDEX_INFO+'\n'; (2)每個詞的索引資訊(INDEX_INFO)由子表編號(TABLE_ID),這條索引記錄相在該子表中德偏移量(OFFSET)組成,其間用空格隔開。表示如下: INDEX_INFO=TABLE_ID+空格+OFFSET 程式碼如下:
public static class TokenIndexMapper extends Mapper<LongWritable, Text, Text, Text> { @Override protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { String line = value.toString(); FileSplit split = (FileSplit) context.getInputSplit(); context.write(new Text(line.split("\t")[0]), new Text(split .getPath().toString() + " " + key.get())); } } public static class TokenIndexReducer extends Reducer<Text, Text, Text, Text> { @Override protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException { boolean flag = true; while (values.iterator().hasNext()) { if (flag) { context.write(key, values.iterator().next()); flag = false; }else{ values.iterator().next(); } } } }
在經過過濾原始檔資料,建立倒排表檔案,生成二級索引檔案等一系列工作之後,整個系統的核心離線工作部分就全部完成了。此後,每當從前臺接收到一個TERM查詢時,本系統首先從索引檔案(INDEX_FILE)中找出這個TERM儲存在什麼子表的位置(INDEX_INFO);然後開啟對應的子表文件並定位相應的位置,讀出這個TERM及其對應的MULTI_INFO;最後分析MULTI_INFO中每個SINGLE_INFO的資訊,從過濾後的原始檔(FlITERED_SOURCE_FILE)中找出相應的帖子資訊返回即可。 參考文獻: 1.劉鵬,hadoop實戰,電子工業出版社,2011.9