长治制作网站,网站改版后 搜索不到,wordpress文章转移,新媒体运营论文最近在学大模型的分布式训练和存储#xff0c;自己的分布式相关基础比较薄弱#xff0c;基于深度学习的一切架构皆来源于传统#xff0c;我总结了之前大数据的分布式解决方案即Hadoop#xff1a;
Why Hadoop
Hadoop 的作用非常简单#xff0c;就是在多计算机集群环境中营…最近在学大模型的分布式训练和存储自己的分布式相关基础比较薄弱基于深度学习的一切架构皆来源于传统我总结了之前大数据的分布式解决方案即Hadoop
Why Hadoop
Hadoop 的作用非常简单就是在多计算机集群环境中营造一个统一而稳定的存储和计算环境并能为其他分布式应用服务提供平台支持。
Hadoop 在某种程度上将多台计算机组织成了一台计算机做同一件事那么 HDFS 就相当于这台计算机的硬盘而 MapReduce 就是这台计算机的 CPU 控制器。
Trouble
由于 Hadoop 是为集群设计的软件所以我们在学习它的使用时难免会遇到在多台计算机上配置 Hadoop 的情况这对于学习者来说会制造诸多障碍主要有两个
昂贵的计算机集群。多计算机构成的集群环境需要昂贵的硬件.难以部署和维护。在众多计算机上部署相同的软件环境是一个大量的工作而且非常不灵活难以在环境更改后重新部署。
为了解决这些问题我们有一个非常成熟的方式Docker。
Docker 是一个容器管理系统它可以向虚拟机一样运行多个虚拟机容器并构成一个集群。因为虚拟机会完整的虚拟出一个计算机来所以会消耗大量的硬件资源且效率低下而 Docker 仅提供一个独立的、可复制的运行环境实际上容器中所有进程依然在主机上的内核中被执行因此它的效率几乎和主机上的进程一样接近100%。
Hadoop 整体设计
Hadoop 框架是用于计算机集群大数据处理的框架所以它必须是一个可以部署在多台计算机上的软件。部署了 Hadoop 软件的主机之间通过套接字 (网络) 进行通讯。
Hadoop 主要包含 HDFS 和 MapReduce 两大组件HDFS 负责分布储存数据MapReduce 负责对数据进行映射、规约处理并汇总处理结果。
Hadoop 框架最根本的原理就是利用大量的计算机同时运算来加快大量数据的处理速度。例如一个搜索引擎公司要从上万亿条没有进行规约的数据中筛选和归纳热门词汇就需要组织大量的计算机组成集群来处理这些信息。如果使用传统数据库来处理这些信息的话那将会花费很长的时间和很大的处理空间来处理数据这个量级对于任何单计算机来说都变得难以实现主要难度在于组织大量的硬件并高速地集成为一个计算机即使成功实现也会产生昂贵的维护成本。
Hadoop 可以在多达几千台廉价的量产计算机上运行并把它们组织为一个计算机集群。
一个 Hadoop 集群可以高效地储存数据、分配处理任务这样会有很多好处。首先可以降低计算机的建造和维护成本其次一旦任何一个计算机出现了硬件故障不会对整个计算机系统造成致命的影响因为面向应用层开发的集群框架本身就必须假定计算机会出故障。
HDFS
Hadoop Distributed File SystemHadoop 分布式文件系统简称 HDFS。
HDFS 用于在集群中储存文件它所使用的核心思想是 Google 的 GFS 思想可以存储很大的文件。
在服务器集群中文件存储往往被要求高效而稳定HDFS同时实现了这两个优点。
HDFS 高效的存储是通过计算机集群独立处理请求实现的。因为用户 (一半是后端程序) 在发出数据存储请求时往往响应服务器正在处理其他请求这是导致服务效率缓慢的主要原因。但如果响应服务器直接分配一个数据服务器给用户然后用户直接与数据服务器交互效率会快很多。
数据存储的稳定性往往通过多存几份的方式实现HDFS 也使用了这种方式。HDFS 的存储单位是块 (Block) 一个文件可能会被分为多个块储存在物理存储器中。因此 HDFS 往往会按照设定者的要求把数据块复制 n 份并存储在不同的数据节点 (储存数据的服务器) 上如果一个数据节点发生故障数据也不会丢失。
HDFS 的节点
HDFS 运行在许多不同的计算机上有的计算机专门用于存储数据有的计算机专门用于指挥其它计算机储存数据。这里所提到的计算机我们可以称之为集群中的节点。
命名节点 (NameNode)
命名节点 (NameNode) 是用于指挥其它节点存储的节点。任何一个文件系统(File System, FS) 都需要具备根据文件路径映射到文件的功能命名节点就是用于储存这些映射信息并提供映射服务的计算机在整个 HDFS 系统中扮演管理员的角色因此一个 HDFS 集群中只有一个命名节点。
数据节点 (DataNode)
数据节点 (DataNode) 使用来储存数据块的节点。当一个文件被命名节点承认并分块之后将会被储存到被分配的数据节点中去。数据节点具有储存数据、读写数据的功能其中存储的数据块比较类似于硬盘中的扇区概念是 HDFS 存储的基本单位。
副命名节点 (Secondary NameNode)
副命名节点 (Secondary NameNode) 别名次命名节点是命名节点的秘书。这个形容很贴切因为它并不能代替命名节点的工作无论命名节点是否有能力继续工作。它主要负责分摊命名节点的压力、备份命名节点的状态并执行一些管理工作如果命名节点要求它这样做的话。如果命名节点坏掉了它也可以提供备份数据以恢复命名节点。副命名节点可以有多个。 MapReduce
MapReduce 的含义就像它的名字一样浅显Map 和 Reduce (映射和规约) 。
大数据处理
大量数据的处理是一个典型的道理简单实施复杂的事情。之所以实施复杂主要是大量的数据使用传统方法处理时会导致硬件资源 (主要是内存) 不足。
现在有一段文字 (真实环境下这个字符串可能长达 1 PB 甚至更多) 我们执行一个简单的数字符统计即统计出这段文字中所有出现过的字符出现的数量 AABABCABCDABCDE 统计之后的结果应该是 A 5 B 4 C 3 D 2 E 1 统计的过程实际上很简单就是每读取一个字符就要检查表中是否已经有相同的字符如果没有就添加一条记录并将记录值设置为 1 如果有的话就直接将记录值增加 1。
但是如果我们将这里的统计对象由字符变成词那么样本容量就瞬间变得非常大以至于一台计算机可能难以统计数十亿用户一年来用过的词。
在这种情况下我们依然有办法完成这项工作——我们先把样本分成一段段能够令单台计算机处理的规模然后一段段地进行统计每执行完一次统计就对映射统计结果进行规约处理即将统计结果合并到一个更庞大的数据结果中去最终就可以完成大规模的数据规约。
在以上的案例中第一阶段的整理工作就是映射把数据进行分类和整理到这里为止我们可以得到一个相比于源数据小很多的结果。第二阶段的工作往往由集群来完成整理完数据之后我们需要将这些数据进行总体的归纳毕竟有可能多个节点的映射结果出现重叠分类。这个过程中映射的结果将会进一步缩略成可获取的统计结果。
MapReduce 概念
示例
假设有 5 个文件每个文件包含两列分别记录一个城市的名称以及该城市在不同测量日期记录的相应温度。城市名称是键 (Key) 温度是值 (Value) 。例如(厦门20)。现在我们要在所有数据中找到每个城市的最高温度 (请注意每个文件中可能出现相同的城市)。
使用 MapReduce 框架我们可以将其分解为 5 个映射任务其中每个任务负责处理五个文件中的一个。每个映射任务会检查文件中的每条数据并返回该文件中每个城市的最高温度。
例如对于以下数据
城市温度厦门12上海34厦门20上海15北京14北京16厦门24
打个比方你可以把 MapReduce 想象成人口普查人口普查局会把若干个调查员派到每个城市。每个城市的每个人口普查人员都将统计该市的部分人口数量然后将结果汇总返回首都。在首都每个城市的统计结果将被规约到单个计数(各个城市的人口)然后就可以确定国家的总人口。这种人到城市的映射是并行的然后合并结果(Reduce)。这比派一个人以连续的方式清点全国中的每一个人效率高得多。
Hadoop 三种模式单机模式、伪集群模式和集群模式
单机模式Hadoop 仅作为库存在可以在单计算机上执行 MapReduce 任务仅用于开发者搭建学习和试验环境。伪集群模式此模式 Hadoop 将以守护进程的形式在单机运行一般用于开发者搭建学习和试验环境。集群模式此模式是 Hadoop 的生产环境模式也就是说这才是 Hadoop 真正使用的模式用于提供生产级服务。
HDFS 配置和启动
HDFS 和数据库相似是以守护进程的方式启动的。使用 HDFS 需要用 HDFS 客户端通过网络 (套接字) 连接到 HDFS 服务器实现文件系统的使用。
配置好 Hadoop 的基础环境容器名为 hadoop_single启动并进入该容器。
进入该容器后确认一下 Hadoop 是否存在
hadoop version如果结果显示出 Hadoop 版本号则表示 Hadoop 存在。
接下来我们将进入正式步骤。
新建 hadoop 用户
新建用户名为 hadoop
adduser hadoop安装一个小工具用于修改用户密码和权限管理
yum install -y passwd sudo设置 hadoop 用户密码
passwd hadoop接下来两次输入密码一定要记住
修改 hadoop 安装目录所有人为 hadoop 用户
chown -R hadoop /usr/local/hadoop然后用文本编辑器修改 /etc/sudoers 文件在
root ALL(ALL) ALL之后添加一行
hadoop ALL(ALL) ALL然后退出容器。
关闭并提交容器 hadoop_single 到镜像 hadoop_proto
docker stop hadoop_single
docker commit hadoop_single hadoop_proto创建新容器 hdfs_single
docker run -d --namehdfs_single --privileged hadoop_proto /usr/sbin/init这样新用户就被创建了。
启动 HDFS
现在进入刚建立的容器
docker exec -it hdfs_single su hadoop现在应该是 hadoop 用户
whoami应该显示 “hadoop”
生成 SSH 密钥
ssh-keygen -t rsa这里可以一直按回车直到生成结束。
然后将生成的密钥添加到信任列表
ssh-copy-id hadoop172.17.0.2查看容器 IP 地址
ip addr | grep 172从而得知容器的 IP 地址是 172.17.0.2你们的 IP 可能会与此不同。
在启动 HDFS 以前我们对其进行一些简单配置Hadoop 配置文件全部储存在安装目录下的 etc/hadoop 子目录下所以我们可以进入此目录
cd $HADOOP_HOME/etc/hadoop这里我们修改两个文件core-site.xml 和 hdfs-site.xml
在 core-site.xml 中我们在 标签下添加属性
propertynamefs.defaultFS/namevaluehdfs://你的IP:9000/value
/property在 hdfs-site.xml 中的 标签下添加属性
propertynamedfs.replication/namevalue1/value
/property格式化文件结构
hdfs namenode -format然后启动 HDFS
start-dfs.sh启动分三个步骤分别启动 NameNode、DataNode 和 Secondary NameNode。
运行 jps 查看 Java 进程
到此为止HDFS 守护进程已经建立由于 HDFS 本身具备 HTTP 面板我们可以通过浏览器访问http://你的容器IP:9870/来查看 HDFS 面板以及详细信息。
HDFS 使用
HDFS Shell
回到 hdfs_single 容器以下命令将用于操作 HDFS
# 显示根目录 / 下的文件和子目录绝对路径
hadoop fs -ls /
# 新建文件夹绝对路径
hadoop fs -mkdir /hello
# 上传文件
hadoop fs -put hello.txt /hello/
# 下载文件
hadoop fs -get /hello/hello.txt
# 输出文件内容
hadoop fs -cat /hello/hello.txtHDFS 最基础的命令如上所述除此之外还有许多其他传统文件系统所支持的操作。
HDFS API
HDFS 已经被很多的后端平台所支持目前官方在发行版中包含了 C/C 和 Java 的编程接口。此外node.js 和 Python 语言的包管理器也支持导入 HDFS 的客户端。
以下是包管理器的依赖项列表
Maven
dependencygroupIdorg.apache.hadoop/groupIdartifactIdhadoop-client/artifactIdversion3.1.4/version
/dependencyGradle
providedCompile group: org.apache.hadoop, name: hadoop-hdfs-client, version: 3.1.4NPM
npm i webhdfs pip
pip install hdfsJava 连接 HDFS 的例子修改 IP 地址
实例
package com.zain;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
public class Application {public static void main(String[] args) {try {// 配置连接地址Configuration conf new Configuration();conf.set(fs.defaultFS, hdfs://172.17.0.2:9000);FileSystem fs FileSystem.get(conf);// 打开文件并读取输出Path hello new Path(/hello/hello.txt);FSDataInputStream ins fs.open(hello);int ch ins.read();while (ch ! -1) {System.out.print((char)ch);ch ins.read();}System.out.println();} catch (IOException ioe) {ioe.printStackTrace();}}
}