hadoop,用户制定类

mapreduce是一个很精巧的构思和设计,对于很多计算问题,程序员通常可以使用默认设置取处理诸多底层的细节,但是,这并不意味着在解决复杂问题时,程序员就可以完全使用这二个函数就可以搞定一切,它还需要更加复杂和灵活的处理机制以及高级的编程技术和方法。本节介绍hadoop中mapreduce比较高级的方法---用户制定类。为什么要用户自定义类,一种直观的猜测就是基本的mapreduce处理不了或者处理的效果不好,才有可能用到用户制定,随着深入的学习,这些问题到处可见。比如文档的倒排索引,制定(优化)的目的就是减少中间键,从而减少每次的读写I/O和网络的压力。

1.  用户自定义数组类型

    虽然hadoop中内置8种数据类型,我见过8种,但不一定就8种,这里就认为是8种吧,他们都实现了WritableComparable接口,这种好处就是可以被序列化进行网路传输和文件存储。BooleanWritable, ByteWritable, FloatWritable, IntWritable,LongWritable,Text, NullWritble,前几种大家都可以猜到表示是什么数据类型,Text表示使用UTF格式的存储的文本。好像visual stdio 中text控件,也是对String类型的一种包装。

    自定义类型必须符合二个条件,第一:实现Writable接口。第二:如果该函数需要作为主键Key使用,或者要比较数值大小时,则要实现WritableComparable接口。下例子是一个圆为例。circle

复制代码
 1 public class Cricle implements Writable<Circle>{
 2     private float radius,x,y;
 3     public float GetRadius(){return radius;}
 4     public float GetX(){return x;}
 5     public float GetY(){return y;}
 6     public void readFields(DataInput in)throws IOException{
 7         radius=in.readFloat();
 8         x=in.readFloat();
 9         y=in.readFloat();
10     }
11     public void write(DataOutput out)throws IOException{
12         out.writeFloat(radius);
13         out.writeFloat(x);
14         out.writeFloat(y);
15     }
16     public int CompareTo(Circle cl){
17         if(cl.radius==this.radius)
18             return 0;
19         if(cl.x>this.x)
20             return 1;
21         if(cl.y<this.y)
22             return -1;
23     }
24 }
复制代码

以上代码就是手写的,没有进行测试,肯定还有错误,只是向说明问题。readFields() 和write()实现Writable接口中定义的二中方法。

 

2. 用户制定输入/输出

尽管Hadoop提供了较为丰富的数据输入/输出格式,可以满足很多应用的需要,但是,对于特殊的要求,还是要用户自己制定。比如说,Hadoop默认的数据输入格式为TextInputFormat,可以将文本文件分块并逐行读入以便Map节点进行处理,每行所产生的Key是文本的字节位置的偏移量,而value就是该行的内日内个。但现在需要文件名@文本偏移量作为key,所以就需要制定输入类,假定现在制定一个数据输入格式FileNameInputFormat和fileNameRecordReader,比便直接产生FileName@lineoffset.

复制代码
public class FileNameInputFormat extends FileInputForamt<Text,Text>{
    public RecordReader<Text,Text>createRecordReader(InputSplit split,TaskAttemptContext context)throws IOException{
        FileNameRecordReader fnrr = new FileNameRecordReader();
        fnrr.initialize(split,context);
    }
}

public class FileNameRecordReader extends
            RecordReader<Text, Text> {
        String FileName;
        LineRecordReader lrr = new LineRecordReader();

        public Text getCurrentKey() throws IOException {
            return new Text("(" + FileName + "@" + lrr.getCurrentKey() + ")");
        }

        public Text getCurrentValue() throws IOException, InterruptedException {
            return new Text(lrr.getCurrentKey().toString());
        }

        public void initialize(InputSplit arg0, TaskAttemptContext arg1)
                throws IOException {
            lrr.initialize(arg0, arg1);
            FileName = ((FileSplit) arg0).getPath().getName();
        }
}
复制代码

 没事什么好讲的,仔细看都能看的懂,输出就不讲了,和输入差不多。

 

3. 用户制定Patritioner和Combiner

   Patritioner来完成中间结果向Reduce节点分区处理,通常是利用hash进行分配,hash划分主要是靠主键进行划分,即相同的主键划分到相同桶中,在mapreduce中就是划分到相同的reduce中。那么现在设想一个问题,我需要将这样的数据划分到一个reduce中,该怎么办? 数据为 hello:1, hello:2,hello:3,hello:4,......., 显然,用hash直接划分是不行的,这是我们可以观察到这些数据都具有一个hello,我们只需要在提取hello作为主键,在用hash划分,就可以把这些数据都划分到同一个reduce中,下面就个例子,给出Patritioner代码:

复制代码
public class NParterioner extends HashPartitioner<Text,Text>
{
    public getPartition(Text key,Text value, int numReduceTasks){
        
        String t=key.toString().split(":")[0];
        Text term;
        term.set(t);
        super.getPartition(term,value,numReduceTasks);
    }
}
复制代码

还有像map,reduce, combiner的制定都是一样的道理。

 

总结:

      用户类的制定主要取决于特定的应用的场合,但其目标都是不变的(减少中间结果来减小I/O和网络传输数据的压力)。


### 找回被误删的 Hadoop 用户账户 在分布式存储系统中,Hadoop用户管理和权限控制是非常重要的部分。如果用户的账户被误删除,则需要根据具体的情况采取不同的措施来进行恢复。 #### 1. **检查 Kerberos 配置** 如果 Hadoop 使用了 Kerberos 进行身份认证,那么用户账户可能是在 Kerberos KDC 中定义的。此时可以通过以下方式尝试恢复: - 登录到 Kerberos Key Distribution Center (KDC),并查看是否存在备份的日志记录或者历史操作记录。 - 利用 `kadmin` 工具重新创建用户账户。命令如下所示: ```bash kadmin.local -q "addprinc username" ``` 上述命令中的 `username` 是指需要恢复的用户名[^1]。 #### 2. **检查 HDFS 权限配置** 即使用户账户本身被删除,在 HDFS 文件系统的元数据中仍然可能存在与该用户相关的权限设置。这些信息通常保存在 NameNode 的编辑日志 (`edits`) 和 FsImage 文件中。以下是具体的解决办法: - 查看 HDFS 日志文件,确认是否有针对此用户的最近修改记录。 - 如果存在相关记录,可以手动调整 HDFS 权限以匹配原始状态。例如: ```bash hdfs dfs -chown user:group /path/to/directory ``` #### 3. **利用 DataNode 副本机制** 当某个 DataNode 出现故障时,HDFS 自动从其他正常工作的 DataNode 复制丢失的数据块以维持冗余度[^2]。因此即使某些节点上的数据暂时不可访问,只要大多数副本完好无损,就可以通过集群内的同步过程逐步修复受影响的部分。 此外还可以关注以下几个关键指标来判断当前健康状况以及潜在风险点: - 待处理复制请求数量(`pendingReplicationBlocksCount`) - 缺少足够副本次数的区块数目(`underReplicatedBlocksCount`) - 损坏副本总数目(`corruptReplicaBlocksCount`) 下面展示了一段 Java 方法片段用于更新上述统计数值逻辑示例代码: ```java public void updateState() { this.pendingReplicationBlocksCount = pendingReplications.size(); this.underReplicatedBlocksCount = neededReplications.size(); this.corruptReplicaBlocksCount = corruptReplicas.size(); } ``` #### 4. **管理平台的手工干预** 对于像 ManageOne 这样的综合管理系统来说,在发生异常情况下的确有可能需要管理员介入完成特定任务才能恢复正常运作流程[^4]。这意味着即便基础服务层面已经具备一定程度自动化能力但仍不可避免地依赖外部输入辅助决策制定过程。 --- ### 总结 综上所述,要成功找回因意外事件而消失掉的那个 hadoop 客户端账号主要取决于几个方面因素共同作用的结果;包括但不限于kerberos域控制器内部留存痕迹挖掘、namenode持久化结构解析还原路径探索等方面工作都需要逐一落实到位才行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值