当前位置: 代码迷 >> 综合 >> doit19-day04-hadoop01
  详细解决方案

doit19-day04-hadoop01

热度:34   发布时间:2023-11-30 10:43:44.0

更多资料点击此处

1 基础知识回顾 

1.1 IO 

在程序中IO流是阻塞的 , 支持随机读取数据 , 不支持修改数据

1 复习  文件复制 

2 随机读取数据  

3 不能随机写数据

/*** FileName: TestIo* Author:   多易教育-DOIT* Date:     2020/11/12 0012* Description: 测试IO的随机读取数据* 1 作业  复制文件*/
public class TestIo {public static void main(String[] args) throws Exception {// 1   获取一个文件的输入流FileInputStream fis = new FileInputStream("d://word.txt");// 输出流没有类似于skip的方法 不能随机写数据FileOutputStream fout = new FileOutputStream("");// 2   读取数据// int read1 = fis.read();  // a  97// int read2 = fis.read();  // 98// 跳过指定的字节fis.skip(2L); // 2k 1024*2*1024   1k=1024byteint read3 = fis.read();// 3   打印// System.out.println(read1);// System.out.println(read2);System.out.println(read3); //101}
}

1.2 序列化

将内存中的对象数据存储在磁盘上 ,或者是将对象通过网络传输 ! 需要对象实现序列化 ,

本质:就是对象转二进制的规则 , 反序列化 怎么将二进制转换成对像规则

java中有自己的序列化机制实现接口

将对象持久化到磁盘  持久化 钝化

将磁盘上的对象数据反序列化成java对象 活化

1.2.1 java的序列化

/*** FileName: TestSer* Author:   多易教育-DOIT* Date:     2020/11/12 0012* Description:* 思考 :   User类能不能不直接实现序列化接口 *         但是能将数据存储在磁盘上 : 保证存储的数据比Serializable方式存储的数据少*         网络传输节省资源*/
public class TestSer {public static void main(String[] args) throws Exception {// 将内存对象持久化到磁盘// 写出对象流ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d://user.user"));User user = new User();user.set(1,"王奔",20000);// 在磁盘中存储的任何数据都是二进制oos.writeObject(user);// 110长度   1  王奔   20000/*** java中的Serializable接口的序列化在磁盘中存储的数据有*  包名  类名  属性名  数据类型  ...  方便通过反射反序列化方便*  有很多的冗余数据*/oos.close();// 将磁盘中的对象数据  反序列化成内存java对象ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d://user.user"));User u = (User)ois.readObject();System.out.println(u);}

1.2.2 将对象转换成JSON (String)

https://mvnrepository.com/search  maven仓库下载jar包

/*** FileName: JsonToDisc* Author:   多易教育-DOIT* Date:     2020/11/12 0012* Description:* 将java对象转换成Json串 --->写到磁盘*/
public class JsonToDisc {public static void main(String[] args) throws Exception {User user = new User();user.set(1,"benB",20000);String str = JSON.toJSONString(user);ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d://user.json"));oos.writeUTF(str);oos.close();}
}

1.2.3 直接写属性到磁盘(简单的类型)

/*** FileName: FieldsToDisc* Author:   多易教育-DOIT* Date:     2020/11/12 0012* Description:* 灵活* 方便 * 数据小* 注意 写和读的顺序*/
public class FieldsToDisc {public static void main(String[] args) throws  Exception {/*User user = new User();user.set(1,"benB",20000);ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d://user.f"));// 写出属性oos.writeInt(user.getId());oos.writeUTF(user.getName());oos.writeDouble(user.getSal());oos.close();*/ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d://user.f"));// 读取数据    按照写的顺序读  Int  UTF  Doubleint id = ois.readInt();String name = ois.readUTF();double sal = ois.readDouble();System.out.println();User user = new User();user.set(id,name,sal) ;System.out.println(user);}
}

1.2.4 自定义序列化规则

 1 定义一个接口  有读写方法

 2 要序列化的java类实现接口  重写读写规则(序列化规则)

 3 测试使用  调用读写方法实现序列化和反序列化

接口

/*** FileName: Writable* Author:   多易教育-DOIT* Date:     2020/11/12 0012* Description: 接口* 定义两个方法 写  读*  作用 : 以后 有类要序列化  实现这个接口*    重写里面的读写方法   (指定了序列化和反序列化的规则)*/
public interface Writable {public void write(ObjectOutputStream oos) throws  Exception;public void read(ObjectInputStream ois)throws  Exception;
}

实现类 

/*** FileName: Teacher* Author:   多易教育-DOIT* Date:     2020/11/12 0012* Description:  要进行序列化和反序列化* 实现接口 重写方法*/
public class Teacher implements  Writable{private int  tid ;private  String name ;private String gender ;private double faceValue ;public void set (int tid, String name, String gender, double faceValue) {this.tid = tid;this.name = name;this.gender = gender;this.faceValue = faceValue;}public int getTid() {return tid;}public void setTid(int tid) {this.tid = tid;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public double getFaceValue() {return faceValue;}public void setFaceValue(double faceValue) {this.faceValue = faceValue;}@Overridepublic String toString() {return "Teacher{" +"tid=" + tid +", name='" + name + '\'' +", gender='" + gender + '\'' +", faceValue=" + faceValue +'}';}/*** 序列化* @param oos* @throws Exception*/@Overridepublic void write(ObjectOutputStream oos) throws Exception {oos.writeInt(this.tid);oos.writeUTF(this.name);oos.writeUTF(this.gender);oos.writeDouble(this.faceValue);oos.close();}/*** 反序列化* @param ois* @throws Exception*/@Overridepublic void read(ObjectInputStream ois) throws Exception {this.tid = ois.readInt();this.name = ois.readUTF() ;this.gender = ois.readUTF() ;this.faceValue = ois.readDouble() ;ois.close();}
}

测试

/*** FileName: TestMyWrite* Author:   多易教育-DOIT* Date:     2020/11/12 0012* Description:*/
public class TestMyWrite {public static void main(String[] args) throws Exception {Teacher teacher = new Teacher();// teacher.set(1,"wangben","M",99.99);// 写出去  序列化//teacher.write(new ObjectOutputStream(new FileOutputStream("d://teacher2.txt")));// 读回来  反序列化teacher.read(new ObjectInputStream(new FileInputStream("d://teacher2.txt"))) ;System.out.println(teacher);}
}

1.3 迭代器

在不知道数据结构和数据条数的情况下使用

比如: 公司中有自己的数据 1#zss:23@M  ,提供迭代器  hasNext   -- next  --> User

package com._51doit.cn.hdp.day01.iter;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Iterator;/*** FileName: MyIteratable* Author:   多易教育-DOIT* Date:     2020/11/12 0012* Description:*/
public class MyIteratable implements Iterator<User> {BufferedReader br;String line = null;User user = new User();{try {br = new BufferedReader(new FileReader("d://user.txt"));} catch (Exception e) {e.printStackTrace();}}/*** 当这个方法返回true的时候  才会执行next方法** @return*/@Overridepublic boolean hasNext() {boolean flag = false;try {line = br.readLine();if (line != null) {flag = true;} else {flag = false;}} catch (Exception e) {e.printStackTrace();}return flag;}@Overridepublic User next() {// 处理每行数据  封装结果到User中 返回//8#fengjie:53@FString uid = line.split("#")[0];String name = line.split("#")[1].split(":")[0];String age = line.split("#")[1].split(":")[1].split("@")[0];String gender = line.split("#")[1].split(":")[1].split("@")[1];user.set(uid,name,age,gender);return user;}
}
package com._51doit.cn.hdp.day01.iter;/*** FileName: User* Author:   多易教育-DOIT* Date:     2020/11/12 0012* Description:*/
public class User {private  String  uid ;private  String  name ;private  String  age ;private  String  gender ;public void set(String uid, String name, String age, String gender) {this.uid = uid;this.name = name;this.age = age;this.gender = gender;}public String getUid() {return uid;}public void setUid(String uid) {this.uid = uid;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}@Overridepublic String toString() {return "User{" +"uid='" + uid + '\'' +", name='" + name + '\'' +", age='" + age + '\'' +", gender='" + gender + '\'' +'}';}
}
/*** FileName: Test1* Author:   多易教育-DOIT* Date:     2020/11/12 0012* Description:*/
public class Test1 {public static void main(String[] args) {MyIteratable mi = new MyIteratable();while(mi.hasNext()){// 返回的数据始终是一个对象来接收的System.out.println(mi.next());}}
}

大数据背景

 

hadoop简介

hadoop是一个大数据的技术(框架) 

主要大数据的问题 1) 海量数据的存储   2) 海量的数据的运算 3)多台机器的资源调配(存储资源 , 运算资源)

1 海量数据的存储  HDFS  hadoop  distribute  filesystem

2 海量的数据的运算   MapReduce运算框架

3 运算资源调度和任务监控平台  Yarn

4  工具包 Commons

特点 

   1 高容错 高可用 

   2 极易扩容   集群规模扩展   增强存储能力和计算能力

   3 廉价性

 

HDFS 简介 

分布式文件系统   hadoop  distribute  filesystem   

文件系统:  读写 读取数据 上传数据 删除数据 创建文件夹 移动  复制.....  提供虚拟的访问目录  类似于百度云盘

mysql是文件系统   关系型数据  条数据单位   

linuxwindows操作系统中的文件系统

分布式文件系统 :  

    将数据存储在不同的机器上  ,提供数据的操作

基本功能:

HDFS安装

1 上传

[root@linux01 apps]# pwd
/opt/apps

2 解压 

 tar -zxvf hadoop-3.1.1.tar.gz 

3 配置

vi  /opt/apps/hadoop-3.1.1/etc/hadoop/hadoop-env.sh

 # variable is REQUIRED on ALL platforms except OS X!export JAVA_HOME=/opt/apps/jdk1.8.0_141/

vi  /opt/apps/hadoop-3.1.1/etc/hadoop/hdfs-site.xml

 <!-- 集群的namenode的位置  datanode能通过这个地址注册-->
<property><name>dfs.namenode.rpc-address</name><value>linux01:8020</value>
</property><!-- namenode存储元数据的位置 -->
<property><name>dfs.namenode.name.dir</name><value>/opt/hdpdata/name</value>
</property><!-- datanode存储数据的位置 -->
<property><name>dfs.datanode.data.dir</name><value>/opt/hdpdata/data</value>
</property><!-- secondary namenode机器的位置-->
<property><name>dfs.namenode.secondary.http-address</name><value>linux02:50090</value>
</property>

vi /opt/apps/hadoop-3.1.1/etc/hadoop/core-site.xml

<property>
<name>fs.defaultFS</name>
<value>hdfs://linux01:8020</value>
</property>

4 分发 

scp -r  hadoop-3.1.1  linux02:$PWD

scp -r  hadoop-3.1.1  linux03:$PWD

5 初始化(bin)

在bin目录下执行

./hadoop  namenode -format

在/opt/hdpdata/name

6 启动(sbin)

在sbin目录下执行

./hadoop-daemon.sh   start  namenode  

jps  出现Namenode进程

访问页面   http://linux01:9870

分别在linux01 linux02  linux03 的sbin目录下执行

./hadoop-daemon.sh   start  datanode

7 配置系统环境变量

vi  /etc/profile 

export  JAVA_HOME=/opt/apps/jdk1.8.0_141
export  HADOOP_HOME=/opt/apps/hadoop-3.1.1
export  PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

source  /etc/profile

 

8 一键启停

 

在  etc/hadoop/workers 配置 需要启动DataNode的机器名

linux01

linux02

linux03

在启停脚本中声明用户   sbin/start-dfs.sh sbin/stop-dfs.sh

#!/usr/bin/env bash
HDFS_DATANODE_USER=root
HADOOP_SECURE_DN_USER=hdfs
HDFS_NAMENODE_USER=root
HDFS_SECONDARYNAMENODE_USER=root

start-dfs.sh

stop-dfs.sh

HDFS客户端

hdfs  dfs  -

[root@linux01 bin]# hdfs dfs 
Usage: hadoop fs [generic options][-appendToFile <localsrc> ... <dst>][-cat [-ignoreCrc] <src> ...][-checksum <src> ...][-chgrp [-R] GROUP PATH...][-chmod [-R] <MODE[,MODE]... | OCTALMODE> PATH...][-chown [-R] [OWNER][:[GROUP]] PATH...][-copyFromLocal [-f] [-p] [-l] [-d] [-t <thread count>] <localsrc> ... <dst>][-copyToLocal [-f] [-p] [-ignoreCrc] [-crc] <src> ... <localdst>][-count [-q] [-h] [-v] [-t [<storage type>]] [-u] [-x] [-e] <path> ...][-cp [-f] [-p | -p[topax]] [-d] <src> ... <dst>][-createSnapshot <snapshotDir> [<snapshotName>]][-deleteSnapshot <snapshotDir> <snapshotName>][-df [-h] [<path> ...]][-du [-s] [-h] [-v] [-x] <path> ...][-expunge][-find <path> ... <expression> ...][-get [-f] [-p] [-ignoreCrc] [-crc] <src> ... <localdst>][-getfacl [-R] <path>][-getfattr [-R] {-n name | -d} [-e en] <path>][-getmerge [-nl] [-skip-empty-file] <src> <localdst>][-head <file>][-help [cmd ...]][-ls [-C] [-d] [-h] [-q] [-R] [-t] [-S] [-r] [-u] [-e] [<path> ...]][-mkdir [-p] <path> ...][-moveFromLocal <localsrc> ... <dst>][-moveToLocal <src> <localdst>][-mv <src> ... <dst>][-put [-f] [-p] [-l] [-d] <localsrc> ... <dst>][-renameSnapshot <snapshotDir> <oldName> <newName>][-rm [-f] [-r|-R] [-skipTrash] [-safely] <src> ...][-rmdir [--ignore-fail-on-non-empty] <dir> ...][-setfacl [-R] [{-b|-k} {-m|-x <acl_spec>} <path>]|[--set <acl_spec> <path>]][-setfattr {-n name [-v value] | -x name} <path>][-setrep [-R] [-w] <rep> <path> ...][-stat [format] <path> ...][-tail [-f] <file>][-test -[defsz] <path>][-text [-ignoreCrc] <src> ...][-touchz <path> ...][-truncate [-w] <length> <path> ...][-usage [cmd ...]]

 

 

 

 

 

 

 

 

 

 

 

HDFS原理