一、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项目
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、运行结果
更多java、大数据学习面试资料,请扫码关注我的公众号: