在HBase中,无论是MemStore的flush,还是HFile的Compact,都会涉及到新HFile的产生,那么HFile是如何产生的呢?我们又是如何将数据Cell写入到HFile中的呢?本文,我们将会大家简单介绍下HFile写入Cell的主体流程。
在《HFile文件格式》一文中,我们简单给大家介绍了HFile文件内容的组织形式,理解这篇文章,将会对理解本文有所帮助,请读者自行阅读。
HFile文件Cell的写入,发起的一个地方,就是MemStore flush时,StoreFlusher的performFlush()方法,如下:
/**
* Performs memstore flush, writing data from scanner into sink.
* 执行memstore的刷新,将数据从scanner写入到sink
*
* @param scanner Scanner to get data from.
* @param sink Sink to write data to. Could be StoreFile.Writer.
* @param smallestReadPoint Smallest read point used for the flush.
*/
protected void performFlush(InternalScanner scanner,
Compactor.CellSink sink, long smallestReadPoint) throws IOException {
int compactionKVMax =
conf.getInt(HConstants.COMPACTION_KV_MAX, HConstants.COMPACTION_KV_MAX_DEFAULT);
List<Cell> kvs = new ArrayList<Cell>();
boolean hasMore;
do {
hasMore = scanner.next(kvs, compactionKVMax);
if (!kvs.isEmpty()) {
// 循环Cell列表,调用Compactor.CellSink的sink方法,append数据到磁盘
for (Cell c : kvs) {
// If we know that this KV is going to be included always, then let us
// set its memstoreTS to 0. This will help us save space when writing to
// disk.
// 如果我们知道这个KV是包括总,然后让我们设置它memstoreTS为0。这将帮助我们节省空间在写入磁盘。
sink.append(c);
}
kvs.clear();
}
} while (hasMore);
}
它会循环的将Cell写入Compactor.CellSink类型的sink,那么这个sink是什么呢?在performFlush()方法的上层调用者DefaultStoreFlusher的flushSnapshot()方法中,首先会调用HStore的createWriterInTmp()方法生成一个StoreFile.Writer实例writer,然后将这个writer作为参数sink传入performFlush()方法,如下: