HDFS: EditLog的完整性增强

本文介绍HDFS中EditLog的工作原理及其在NameNode关闭时如何避免丢失未同步到磁盘的操作记录。通过在NameNode中加入shutdownhook或使用ServicePlugin,确保即使在NameNode关闭时也能将内存中的EditLog刷新到磁盘。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[size=medium]
  用户对HDFS的每步操作都会先记录到NameNode磁盘中的EditLog文件中。为了避免频繁操作磁盘对用户操作效率的影响,HDFS为EditLog在内存中分配两个buffer:一个用于接收用户操作指令;另外一个在用户想要刷新第一个buffer内数据时开始担当接收用户指令的职责。之后两块buffer不断切换角色,进行着上述操作。[/size]
[img]http://dl.iteye.com/upload/attachment/549162/46304c9a-68f9-38c6-b867-3a99e970c363.jpg[/img]
[size=medium]
  正是因为有内存中buffer的存在,当管理员shutdown NameNode时,就会丢失用户写入buffer且还没来得及刷新到磁盘中的那些操作记录。我们需要做的就是在NameNode加入shutdown hook,希望当NameNode接收到系统的关闭信号时,能正常刷新buffer中数据到磁盘中。

  如果我们能改动NameNode的代码,那么就可以像这样加入:(HDFS0.21)[/size]

// NameNode.java
public static void main(String argv[]) throws Exception {
try {
StringUtils.startupShutdownMessage(NameNode.class, argv, LOG);
final NameNode namenode = createNameNode(argv, null);
if (namenode != null)
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
namenode.namesystem.close();
LOG.info("Close FSNameSystem successfully");
}
});
namenode.join();
} catch (Throwable e) {
LOG.error(StringUtils.stringifyException(e));
System.exit(-1);
}
}


[size=medium]
  如果不能改动代码的话,可以通过HDFS提供的Service plugin来完成。Service plugin是HDFS提供给管理员的access point,我们可以通过这个access point为HDFS提供一些扩展功能。同样地,创建一个关闭EditLog的plugin。

  创建一个EditLogPlugin的类,注意它的包名应该与NameNode在同一包下面,这是因为nameSystem只有在这个包下面才可以访问。[/size]

package org.apache.hadoop.hdfs.server.namenode;

import java.io.IOException;
import org.apache.hadoop.util.ServicePlugin;

public class EditLogPlugin implements ServicePlugin {

public void start(Object arg0) {
final NameNode nameNode = (NameNode) arg0;
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
nameNode.namesystem.close();
NameNode.LOG.info("Close FSNameSystem successfully");
}
});
}

public void stop() {
}

public void close() throws IOException {
}

}

[size=medium]
  打包这个类,然后把它放到Hadoop的lib目录下。在HDFS的配置文件中这样配:[/size]

<property>
<name>dfs.namenode.plugins</name>
<value>org.apache.hadoop.hdfs.server.namenode.EditLogPlugin</value>
</property>

[size=medium]
这样在NameNode启动后shutdown hook就会加入到系统中。

  但需要注意的是,NameNode中的shutdown hook只有在NameNode进程可以正常拦截系统进程的情况下才可以起作用。像SIGKILL(9)这样的系统信号是不能被进程接收、处理的。所以我们对EditLog正常关闭的期望是很局限的,只有尽最大可能地保证管理脚本和管理操作中不要有“kill -9 <pid>”这样的命令。[/size]
在使用Hive执行HDFS路径时,可能会遇到路径中的一些字符被意外修改的情况,例如“hdfs://”变成了“hdfs:/”。这通常是由于Hive在解析路径时对双斜杠“//”的处理方式导致的。以下是一些可能的原因和解决方法: ### 可能的原因 1. **路径解析问题**:Hive在解析HDFS路径时,可能会将双斜杠“//”简化为单斜杠“/”,导致路径格式发生变化。 2. **配置文件问题**:Hive的配置文件(如`hive-site.xml`)中可能配置了错误的HDFS路径格式。 3. **脚本问题**:如果你是通过脚本执行Hive命令,脚本中可能对路径进行了错误的处理。 ### 解决方法 1. **手动替换路径**:在执行Hive命令前,手动将路径中的“hdfs:/”替换为“hdfs://”。 2. **检查配置文件**:确保`hive-site.xml`中的HDFS路径配置正确,使用双斜杠“//”。 3. **使用绝对路径**:尽量使用绝对路径,避免相对路径带来的解析问题。 4. **调试脚本**:如果使用脚本执行Hive命令,检查脚本中路径处理的部分,确保路径格式正确。 ### 示例 假设你有一个HDFS路径`hdfs://namenode:8020/user/hive/warehouse`,你可以在执行Hive命令时这样使用: ```bash hive -f script.hql ``` 在`script.hql`中,确保使用正确的路径格式: ```sql CREATE EXTERNAL TABLE example_table ( id INT, name STRING ) STORED AS ORC LOCATION 'hdfs://namenode:8020/user/hive/warehouse/example'; ``` 如果路径被错误地解析为“hdfs:/”,可以尝试手动替换: ```bash sed -i 's|hdfs:/|hdfs://|g' script.hql ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值