大数据之HDFS

一、HDFS角色

1、nameNode:负责管理整个文件系统的元数据;
2、dataNode :负责管理用户的文件数据块;
3、secondary Namenode:负责管理image镜像文件;

dataNode会定期向nameNode汇报自身所保存的文件block信息,而namenode则会负责保持文件的副本数量

二、客户端向HDFS写数据:

上传数据是,dataNode的选择策略:
1、第一个副本先考虑和客户端最近的机架;
2、第二个副本再考虑跨机架选dataNode;
3、第三个副本在第一个副本机架另外选一个dataNode;

以packet为单位上传,以chunk为单位校验;

三、nameNode管理元数据机制:

hdfs集群不适合存储大量的小文件;

若nameNode宕机,hdfs就不能正常提供服务;

若namenode硬盘损坏,可以通过secondary Namenode恢复大部分数据,

因此在配置nameNode的工作目录参数时,应配置在多块磁盘上;

nameNode的内存常态为128G。

四、java操作HDFS文件

用流的方式来操作hdfs上的文件,可以实现读取指定偏移量范围的数据

    package cn.itcast.hdfs;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.net.URI;
    import org.apache.commons.io.IOUtils;
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.fs.FSDataInputStream;
    import org.apache.hadoop.fs.FSDataOutputStream;
    import org.apache.hadoop.fs.FileSystem;
    import org.apache.hadoop.fs.Path;
    import org.junit.Before;
    import org.junit.Test;
    
    public class HdfsStreamAccess {
        
        FileSystem fs = null;
        Configuration conf = null;
        
        @Before
        public void init() throws Exception{
            
            conf = new Configuration();
            //拿到一个文件系统操作的客户端实例对象
    //        fs = FileSystem.get(conf);
            //可以直接传入 uri和用户身份
            fs = FileSystem.get(new URI("hdfs://192.168.56.103:9000"),conf,"root"); //最后一个参数为用户名
        }
        
        /**
         * 通过流的方式上传文件到hdfs
         * @throws Exception
         */
        @Test
        public void testUpload() throws Exception {
            
            FSDataOutputStream outputStream = fs.create(new Path("/angelababy.love"), true);
            FileInputStream inputStream = new FileInputStream("c:/angelababy.love");
            IOUtils.copy(inputStream, outputStream);
        }
        
        /**
         * 通过流的方式下载hdfs文件
         * @throws Exception
         */
        @Test
        public void testDownLoad() throws Exception {
            
            FSDataInputStream inputStream = fs.open(new Path("/angelababy.love"));            
            FileOutputStream outputStream = new FileOutputStream("d:/angelababy.love");
            IOUtils.copy(inputStream, outputStream);    
        }
        
        /**
         * 获取hdfs文件上指定长度内容
         */
        @Test
        public void testRandomAccess() throws Exception{
            
            FSDataInputStream inputStream = fs.open(new Path("/angelababy.love"));
            inputStream.seek(12);
            FileOutputStream outputStream = new FileOutputStream("d:/angelababy.love.part2");
            IOUtils.copy(inputStream, outputStream);    
        }
        
        /**
         * 显示hdfs上文件的内容
         */
        @Test
        public void testCat() throws IllegalArgumentException, IOException{
            
            FSDataInputStream in = fs.open(new Path("/angelababy.love"));
            IOUtils.copy(in, System.out);
    //        IOUtils.copyBytes(in, System.out, 1024);
        }
    
    }

五、hadoop中的rpc框架

1、创建一个project项目

大数据之HDFS

 

 

2、创建客户端和服务端,然后分别启动

MyHdfsClient

    package cn.itcast.client;
    import java.net.InetSocketAddress;
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.ipc.RPC;
    import cn.itcast.protocol.ClientNamenodeProtocol;
    
    public class MyHdfsClient {
    
        public static void main(String[] args) throws Exception {
            ClientNamenodeProtocol namenode = RPC.getProxy(ClientNamenodeProtocol.class, 1L,
                    new InetSocketAddress("localhost", 8888), new Configuration());
            String metaData = namenode.getMetaData("/wordcount");
            System.out.println(metaData);
        }
    
    }   

ClientNamenodeProtocol

    package cn.itcast.protocol;
    
    public interface ClientNamenodeProtocol {
        public static final long versionID=1L; //会读取这个版本号, 但可以和客户端的不一样, 没有校验
        public String getMetaData(String path);
    } 

MyNameNode

    package cn.itcast.service;
    import cn.itcast.protocol.ClientNamenodeProtocol;

    public class MyNameNode implements ClientNamenodeProtocol{
        
        //模拟namenode的业务方法之一:查询元数据
        @Override
        public String getMetaData(String path){
            
            return path+": 3 - {BLK_1,BLK_2} ....";
            
        }
}

PublishServiceUtil

	package cn.itcast.service;
	
	import org.apache.hadoop.conf.Configuration;
	import org.apache.hadoop.ipc.RPC;
	import org.apache.hadoop.ipc.RPC.Builder;
	import org.apache.hadoop.ipc.RPC.Server;
	
	import cn.itcast.protocol.ClientNamenodeProtocol;
	
	public class PublishServiceUtil {
	
		public static void main(String[] args) throws Exception {
			Builder builder = new RPC.Builder(new Configuration());
			builder.setBindAddress("localhost")
			.setPort(8888)
			.setProtocol(ClientNamenodeProtocol.class)
			.setInstance(new MyNameNode());
			Server server = builder.build();
			server.start();
		}
	}

  3、运行结果

大数据之HDFS

 

 

更多java、大数据学习面试资料,请扫码关注我的公众号:

 

大数据之HDFS

 

上一篇:GBase 8a MPP数据库HDFS问题排查(一)


下一篇:HDFS -- hadoop的FileSystem样例