亚稳定机房hbase集群配置
背景
在某些项目中,由于一些特殊原因,机房环境不是特别稳定,存在可能突然断电的情况,在这种情况下,我们需要一些额外的配置来尽量避免hbase集群数据丢失。
风险
- HLog 没有及时落地到磁盘,断电导致wal日志丢失
- HFile刷写完成,但是文件HFile
close
调用后,数据没有及时落地到磁盘,断电导致HFile文件损坏,region
open失败。
相关知识
linux 磁盘数据同步api
sync
: POSIX标准中,sync
把写操作加入到调度队列中,但不会等到实际磁盘写完成才返回。linux 1.3.20版本之后,sync
会等待写完成才返回和遍历调用fsync(fd)
语义相同.fsync
:fsync的功能是确保文件fd所有已修改的内容已经正确同步到硬盘上,该调用会阻塞等待直到设备报告IO完成。fdatasync
:fdatasync的功能与fsync类似,但是仅仅在必要的情况下才会同步metadata,因此可以减少一次IO写操作,什么是“必要的情况”呢?例来说,文件的尺寸(st_size)如果变化,是需要立即同步的,否则OS一旦崩溃,即使文件的数据部分已同步,由于metadata没有同步,依然读不到修改的内容。而最后访问时间(atime)/修改时间(mtime)是不需要每次都同步的,只要应用程序对这两个时间戳没有苛刻的要求,基本无伤大雅。
hdfs 数据同步api
public interface Syncable {
/**
* @deprecated As of HADOOP 0.21.0, replaced by hflush
* @see #hflush()
*/
@Deprecated public void sync() throws IOException;
/** Flush out the data in client's user buffer. After the return of
* this call, new readers will see the data.
* @throws IOException if any error occurs
*/
public void hflush() throws IOException;
/** Similar to posix fsync, flush out the data in client's user buffer
* all the way to the disk device (but the disk may have it in its cache).
* @throws IOException if error occurs
*/
public void hsync() throws IOException;
}
flush
: 把数据从client的缓存刷写到socket后直接返回,并不等待数据到达datanodesync
: 被hflush
代替,直接调用了hflush
hflush
:刷写所有副本的块,数据会写入到所有datanode的缓存中,该api返回后,所有新的reader可以读取到数据最新的数据。hsync
: 所有副本完成 posix对应的fsync
操作
ProtobufLogWriter
@Override
public void sync(boolean forceSync) throws IOException {
FSDataOutputStream fsdos = this.output;
if (fsdos == null) {
return; // Presume closed
}
fsdos.flush();
if (forceSync) {
fsdos.hsync();
} else {
fsdos.hflush();
}
}
默认hbase.wal.hsync
值为SYNC_WAL
,即会调用hflush
进行同步,断电前不能保证数据被写入到磁盘。
相关配置项
hdfs-site.xml
dfs.datanode.synconclose
:true
hbase-site.xml
hbase.wal.hsync
:FSYNC_WAL