Hadoop官网翻译 FileSystem/OutputStream
Posted 油纸雨伞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hadoop官网翻译 FileSystem/OutputStream相关的知识,希望对你有一定的参考价值。
介绍
OutputStream是一个标准接口,文档介绍它如何在HFDS上实现。
HDFS增加实现了标准接口之外的Syncable和StreamCapabilities
数据写入文件系统
- 通常写入是通过FileSystem.create,FileSystem.append,FileDataOutputStreamBuilder.build()得到OutputStream。
- 通过write写入outputStream中,如果close方法调用了。需要其他客户端可见。
- 和写数据一起,Hadoop outputStream通过Sync接口提供了flush方法,让数据可以对其他的客户端可见。
- 接口:StreamCapabilities,允许探测Stream的能力
输出流模型
- 输出流可以被视为存储在客户机中的字节列表,hsync和hrush是操作。让数据传输到其他读者可以看到的地方,并持久化。
- open可以追踪输出流是否打开。
- 输出流可以通过一个三元组定位 (path,open,buffer)
刷新数据的可见性
Syncable操作之后,path中的数据需要和buffer一致。hsync和hrush区别点在于持久化的方式不同,而不是可见性的不同。
Stream状态
- FileSystem.create
返回一个空的缓存的stream
Stream = (path,true,[]) - FileSystem.append
返回 Stream = (path,true,data(Fs,path)) 默认填充缓冲区
持久化数据
当close时,当前buffer会替换file的内容,进行持久化。
close是幂等的,但是不能重复写。
FSDataOutputStream
OutputStream可以被Syncable,CanSetDropBehind和StreamCapabilities包装。
HDFS的FileSystem实现,DistributedFileSystem,返回了HdfsDataOutputStream.它实现了两个没有被Java显示声明的行为。
1.多个线程可以往同一个OutputStream里面写入,HBase依赖这一项。
咋实现的?
2.OutputStream.flush在文件关闭时禁止写入。
由于write是HDFS的很重要的API,所以write线程安全非常重要。
OutputStream
Java OutputStream允许应用写bytes到目的文件。
- write(Stream, data)
- write(Stream,byte[] data,int offset,int len)
- write(byte[] data)
- flush
- close
close时要释放锁
close需要阻塞到write数据完成
close只能一次,后续的close要异常
有些close非常慢,比如对象存储要在close时上传全部数据。可能阻塞线程很长时间。
close需要保证一致性,持久化,还要保证文件状态是closed。
- hdfs的实现上,没有保证close的时候已经完成数据持久化了,所以需要先调用sync来持久化数据。
Syncable
目的是保证数据写入到文件系统即可见,有持久。具有hflush和hsync接口。
Syncable除了被OutputStream的子类实现外,还被其他类比如说Sequence.Writer实现。
FSDataOutputStream实现Syncable,仅仅是看它包裹的OutStream是不是实现了Sync接口,如果没有的话,会降级hflush到flush。
hflush
hflush和flush区别?
flush是should,hflush是阻塞确保刷新的。
hflush可以调用hsync。
通常文件系统只提供hsync,那么时间可能更长。
除非WAL,否则不要每一行都hsync.
hsync
hsync提供持久性和可见性.要求存磁盘。
StreamCapabilities
目的是让调用者动态的决定Stream的行为,比如是否支持HSYNC,HFLUSH等,readAhead,unbuffer,readbytebuffer,preadbytebuffer等。
CanSetDropBehind
改变hdfs的策略,用来判断是否丢弃cache
Output Stream 的 持久性,并发性,一致性和可见性
系统行为的几个方面,文件系统模型没有直接设计,但是在生产中可以看到。
持久化
- write
可以同步或者异步的持久化数据 - flush
flush数据到目的地,没有持久化要求 - hflush
确保结束之后,所有读取新流的客户端可以看到,不保证持久性。 - hsync
语义和hflush一致,但是要求持久化存储 - close
语义和hflush一致,需要关闭流
并发性
- 多个线程写入同一个文件的结果未定义。
这里面不用锁吗?hbase是如何支持多个线程公用一个流的?
- 一个读一个写的时候,啥时候可以读取到新数据。
- DFSOutputStream具有强的线程安全模型。
DFSOutputStrem他所有的操作都是加锁的了。
一致性和可见性
- 没有要求数据立即可见,除非是使用了fush等操作。
- create(path,overwrite==true),那么路径会立刻不可见。
- 文件的元数据应该在flush和sync或者close以后和内容一致。
Hadoop Output Stream 模型的问题
问题点主要在于何时写入和持久化数据,以及何时同步元数据。HDFS和本地文件系统的实现在某些部分不遵从outputStream的设计规范。
HDFS
- HDFS: hsync只同步最后一个块。
WAL要求在提交标志刷新之前,前面字节必须被保存。因此用HDFS实现WAL时,要注意如果上次同步之后写入的数据很多,跨越了block边界,只会同步最后一个块。
如果一个大的写任务要求同步,那么需要定时同步。 - HDFS: 元数据通常是滞后的,比如说getFileStatus获取的文件长度通常是过时的。
需要注意的一点是getFileStatus(Fs,path).getLen()==0并不能说明文件是空的。
localFileSystem
localfilesystem是通过file.crc文件来确保块的完整性的。所以,只有完整块才可以hflush。
所以如果不禁用校验和,不能随时hsync。hdfs是通过一个DataBlockScanner周期性校验。
对象存储
对象存储可能一直到close才put输出。
对象存储不能保准outputStream创建后可见。
对象存储和POSIX文件系统也很不一样,对象存储不能保证close之后,数据可以持久的保存。比较有利的是,PUT操作可以保证原子性。
优化建议
1.实现Syncable接口,或者是抛出不支持。
2.元数据更新
3.close持久化数据。
2-Hadoop集群搭建(官网翻译)
以下仅是译者,抽出闲暇时间进行翻译,由于本身能力有限,难免会有译错或者误解原作者意思,还请大家互相指正,互相学习。
目的
这个文档描述了如何用千台的节点来安装和配置Hadoop集群,如果你仅仅是为了体验尝试下Hadoop,你可以在单台的机器上去安装它(具体参看Single Node Setup)
这个文档没有涵盖一些高级的主题,例如安全和高可用方面。
需要软件
安装Java,参看Hadoop Wiki
从Apache Mirrors 中下载一个稳定版本的Hadoop
安装
安装Hadoop集群,那么在集群中的所有机器都必须包含解压了的那个软件,对于适合你操作系统的打包系统来进行安装它,它对分割硬件的功能是相当重要的。
在非安全模式下配置Hadoop
Hadoop的Java配置主要由两类型型的配置文件进行驱动:
只读的默认配置 - core-default.xml, ++hdfs-default.xml, yarn-default.xml 和 mapred-default.xml.
指定的配置 - etc/hadoop/core-site.xml, etc/hadoop/hdfs-site.xml, etc/hadoop/yarn-site.xml 和 etc/hadoop/mapred-site.xml.
此外,你可以bin目录中找到这些脚本,通过 etc/hadoop/hadoop-env.sh 和 etc/hadoop/yarn-env.sh. 来设置特定的值。为了配置Hadoop集群,除了需要配置Hadoop守护进程的参数之外,还需要你配置Hadoop守护进程执行的环境变量。
HDFS守护进程有名称节点,辅助名称节点和数据节点。YARN守护进程有资源管理器,节点管理器和WebAppProxy。如果需要使用MapReduce,那么MapReduce Job History Server 也是要运行的,在大型设施中,这些通常是在单独的主机上运行。
配置Hadoop守护进程环境变量
管理员应该使用etc/hadoop/hadoop-env.sh 和 可选的the etc/hadoop/mapred-env.sh 及etc/hadoop/yarn-env.sh 脚本来自定义Hadoop守护进程执行的环境变量。
至少,你必须设置JAVA_HOME环境变量,让每台远程节点都正确的定义。
管理员可以使用下面表格中的可选项,来配置守护进程:
守护进程 | 环境变量 |
---|---|
NameNode | HDFS_NAMENODE_OPTS |
DataNode | HDFS_DATANODE_OPTS |
Secondary NameNode | HDFS_SECONDARYNAMENODE_OPTS |
ResourceManager | YARN_RESOURCEMANAGER_OPTS |
NodeManager | YARN_NODEMANAGER_OPTS |
WebAppProxy | YARN_PROXYSERVER_OPTS |
Map Reduce Job History Server | MAPRED_HISTORYSERVER_OPTS |
例如,为了配置名称节点使用并行的GC和4GB的java堆,按照如下应该在hadoop-env.sh脚本添加如下:
export HDFS_NAMENODE_OPTS="-XX:+UseParallelGC -Xmx4g"
其他的你可以自定义配置有用的参数包括如下:
HADOOP_PID_DIR - 守护进程的ID,文件存储目录。
HADOOP_LOG_DIR - 守护进程日志文件存储目录,如果不存在则日志目录会自动创建。
HADOOP_HEAPSIZE_MAX - Java堆的最大值,被JVM支持的单位在这里也能被支持。如果单位不指定,它将会默认为MB为单位。默认情况下,Hadoop会让JVM决定使用多少。这个值默认会被结尾为_OPTS的变量覆盖。++例如,设置了HADOOP_HEAPSIZE_MAX=1g 和HADOOP_NAMENODE_OPTS="-Xmx5g" 将会用用5GB堆来配置名称节点++。
大部分情况下,你应该指定HADOOP_PID_DIR和HADOOP_LOG_DIR目录,让他们可以被运行了Hadoop守护进程的用户所写。否则,它会潜在符号链接攻击可能性。
通常在系统的shell环境中配置HADOOP_HOME变量。例如,/etc/profile.d中:
HADOOP_HOME=/path/to/hadoop
export HADOOP_HOME
配置Hadoop守护进程
这个部分解决了配置文件中指定的一些重要参数:
etc/hadoop//core-site.xml
参数 | 值 | 注释 |
---|---|---|
fs.defaultFS | 名称节点的URI | hdfs://host:port/ |
io.file.buffer.size | 131072 | 在序列文件中使用读/写缓冲区的大小 |
etc/hadoop/hdfs-site.xml
名称节点的配置
参数 | 值 | 注释 |
---|---|---|
dfs.namenode.name.dir | 在本地文件系统中名称节点的本地存储路径 | 如果这个是以逗号分割的目录列表,那么在名称信息在所有的目录都会被复制。 |
dfs.hosts / dfs.hosts.exclude | 排除/包括 数据节点列表 | 如果需要,使用这个来控制可用的数据节点列表 |
dfs.blocksize | 268435456 | 对于大文件系统HDFS块大小是256MB |
dfs.namenode.handler.count | 100 | 用更多的名称节点服务线程来处理大量数据节点的RPC请求。 |
数据节点配置
参数 | 值 | 注释 |
---|---|---|
dfs.datanode.data.dir | 以逗号分割数据节点在本地文件系统中的路径列表 | 如果这是以逗号分割的目录列表,那么在所有的目录中都会存储。 |
etc/hadoop/yarn-site.xml
资源管理器和节点管理器的配置
参数 | 值 | 注释 |
---|---|---|
yarn.acl.enable | true/false | 启动ACL,默认为false |
yarn.admin.acl | Admin ACL | 在集群上设置管理员的ACL,ACL的值要以逗号分割用户和用户组。默认指定*,意味着任何人都有访问权限。 |
yarn.log-aggregation-enable | false | 配置 启动/禁用 日志聚合 |
资源管理器配置
参数 | 值 | 注释 |
---|---|---|
yarn.resourcemanager.address | 提交作业的客户端口 | 如果设置成host:port 会覆盖设yarn.resourcemanager.hostname属性 |
yarn.resourcemanager.scheduler.address | 应用程序与调度程序进行通信的端口,以获取资源 | 如果设置成host:port,会覆盖设yarn.resourcemanager.hostname属性 |
yarn.resourcemanager.resource-tracker.address | 节点管理器端口 | 如果设置成host:port,会覆盖设yarn.resourcemanager.hostname属性 |
yarn.resourcemanager.admin.address | 管理命令的端口 | 如果设置成host:port,会覆盖设yarn.resourcemanager.hostname属性 |
yarn.resourcemanager.webapp.address | web-ui端口 | 如果设置成host:port,会覆盖设yarn.resourcemanager.hostname属性 |
yarn.resourcemanager.hostname | 资源管理器主机名 | 设置单个主机名称,替代yarn.resourcemanager*address中默认的主机名,结果是使用资源管理组件默认的端口。 |
yarn.resourcemanager.scheduler.class | 资源管理器调度程序的类 | 有限容量的调度程序(推荐),公平的调用程序(也是推荐)或者先进先出的调度程序,使用一个全类路径的名称,例如:org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler |
yarn.scheduler.minimum-allocation-mb | 资源管理器中,分配给每个容器请求的内存最小限额 | 单位用MB |
yarn.scheduler.maximum-allocation-mb | 资源管理器中,分配给每个容器请求的内存最大限额 | 单位用MB |
yarn.resourcemanager.nodes.include-path / yarn.resourcemanager.nodes.exclude-path | 节点管理器允许/排除列表 | 如果需要,使用这个来控制可用的节点管理器列表 |
节点管理器配置
参数 | 值 | 注释 |
---|---|---|
yarn.nodemanager.resource.memory-mb | 给资源管理的可用物理内存,用MB | 定义节点管理器总的可用资源 |
yarn.nodemanager.vmem-pmem-ratio | 任务的虚拟内存可能超过物理内存最大比率。 | 每个任务使用的虚拟内存可能超过这个物理内存比率,虚拟内存的总大小在节点管理器上被每个任务所使用可以超过它物理内存的使用最大比率。 |
yarn.nodemanager.local-dirs | 在写入中间数据的本地文件系统中,以逗号分割的路径。 | 多个路径帮助扩展磁盘IO |
yarn.nodemanager.log.retain-seconds | 10800 | 如果日志聚合是禁用的,在只有可用的节点管理器中保留日志文件的默认时长。 |
yarn.nodemanager.remote-app-log-dir | /logs | 应用日志在应用完成之后移动到HDFS的目录.适当的权限。只有日志聚合功能开启才可用。 |
yarn.nodemanager.remote-app-log-dir-suffix | logs | 后缀附加到远程日志目录.日志将会聚合到{user}/${thisparam},只有日志聚合功能开启才可以使用。 |
yarn.nodemanager.aux-services | mapreduce_shuffle | 需要设置MapReduce应用的Shuffle服务。 |
yarn.nodemanager.env-whitelist | 环境变量从节点管理器的容器中继承。 | 对于mapreduce应用除了默认值HADOOP_MAPRED_HOME应该要添加,JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME这些变量 |
历史服务器配置(需要迁移到其他地方)
参数 | 值 | 注释 |
---|---|---|
yarn.log-aggregation.retain-seconds | -1 | 在删除他们之前,聚合日志留存的时间。-1 表示禁用,当心,设置这个值太小的话将会变成垃圾 |
yarn.log-aggregation.retain-check-interval-seconds | -1 | 聚合日志留存检查,如果设置0或者负数那么值将会计算为日志留存时间的十分之一。当心,这个值如果设置太小那么将会变成垃圾。 |
etc/hadoop/mapred-site.xml
Mapreduce应用配置
参数 | 值 | 注释 |
---|---|---|
mapreduce.framework.name | yarn | 执行框架设置为Hadoop YARN |
mapreduce.map.memory.mb | 1536 | maps最大资源限制 |
mapreduce.map.java.opts | -Xmx2014M | maps子jvm的最大堆大小 |
mapreduce.reduce.memory.mb | 3072 | reduces最大资源限制 |
mapreduce.reduce.java.opts | -Xmx2560M | reduces子jvm的最大堆大小 |
mapreduce.task.io.sort.mb | 512 | 当有效排序数据最高的内存限制 |
mapreduce.task.io.sort.factor | 100 | 当在排序文件时更多的流会马上合并 |
mapreduce.reduce.shuffle.parallelcopies | 50 | 并行复制被reduces运行,从maps非常大数据的抓取输出到目录下。 |
MapReduce JobHistory Server配置
参数 | 值 | 注释 |
---|---|---|
mapreduce.jobhistory.address | MapReduce JobHistory Server host:port | 默认端口 10020. |
mapreduce.jobhistory.webapp.address | MapReduce JobHistory Server Web UI host:port | 默认端口:19888. |
mapreduce.jobhistory.intermediate-done-dir | /mr-history/tmp | 历史文件被MapReduce jobs写入的目录 |
mapreduce.jobhistory.done-dir | /mr-history/done | 历史文件被MR JobHistory Server管理的目录. |
监测节点管理器的健康情况
Hadoop提供了一个可通过配置节点管理器,周期性运行一个管理员支持的脚本来检测节点是否健康的机制。
通过执行脚本就可以断定节点的健康状态。如果脚本检测到节点是一个不健康的状态,它会输出以ERROR为开头的错误信息。节点管理器周期性的执行脚本和检查它的输出内容。按照以上的描述,如果脚本输出内容包含了ERROR信息,节点的状态会被报告为不健康的状态那么节点会被资源管理器列入黑名单列表中。没有任务将会分配给这个节点。然而,节点管理器会继续运行这个脚本,以致于如果这个节点再次恢复正常,资源管理器将会自动把它从黑名单列表中移除。节点健康与输出的目录紧密相连,如果它是不健康的,在资源管理的WEB UI 仍然是可用的,节点健康所经历过的时间在WEB UI 仍然显示着。
下面 参数可以用于控制监控脚本的节点健康,在 etc/hadoop/yarn-site.xml
参数 | 值 | 注释 |
---|---|---|
yarn.nodemanager.health-checker.script.path | Node health script | 脚本检查节点健康状态 |
yarn.nodemanager.health-checker.script.opts | Node health script options | 检查节点健康状态的脚本可选项 |
yarn.nodemanager.health-checker.interval-ms | Node health script interval | 运行健康脚本的时间间隔 |
yarn.nodemanager.health-checker.script.timeout-ms | Node health script timeout interval | 用于健康脚本执行超时的时间 |
如果只有一些本地磁盘变坏,那么健康脚本不会给出ERROR的信息。节点管理器定期的去检查本地磁盘的健康状态(尤其是检查nodemanager-local-dirs和nodemanager-log-dirs)如果文件坏的数量达到了配置属性 yarn.nodemanager.disk-health-checker.min-healthy-disks的临界值之后。所有的节点会被标记为不健康且这个消息也会告知资源管理器。这个启动磁盘要么是被袭击了要么是检查健康脚本断定为失败的 |
从机文件
Hadoop 的机架感知
很多Hadoop的组件是有机架感知和利用网络拓扑来实现性能和安全。Hadoop守护进程通过调用管理配置模块来获取集群中工作机架的相关信息。对于更多的信息参看Rack Awareness文档。
在启动HDFS之前,极力推荐配置机架感知。
日志
Hadoop对于日志,使用了Apache log4j,编辑etc/hadoop/log4j.properties文件去自定义Hadoop守护进程的日志配置(日志格式化等等..)
操作Hadoop集群
一旦所有需要的配置都完成,就可以在所用的机器上分发文件到HADOOP_CONF_DIR目录汇总去,这个在所有机器上应该都是同一个目录。
通常情况下极力推荐HDFS和YARN用独立的用户去运行。大多数的安装中,HDFS进程用hdfs去执行.YARN通常使用yarn用户。
Hadoop 启动
为了启动Hadoop集群,你需要启动HDFS和YARN集群。
第一次打开HADFS,你需要格式化.以hdfs用户去格式化一个新的分布式文件系统:
$HADOOP_HOME/bin/hdfs namenode -format <cluster_name>
以hdfs用户,在指定的节点上用如下命令去启动HDFS的名称节点:
$HADOOP_HOME/bin/hdfs --daemon start namenode
以hdfs用户,用如下的命令去启动每台HDFS的数据节点:
$HADOOP_HOME/bin/hdfs --daemon start datanode
如果etc/hadoop/workers 中所有都配置了免密的登录,那么HDFS的所有进程可以用一个通用的脚本进行启动:
[hdfs]$ $HADOOP_HOME/sbin/start-dfs.sh
按照如下的命令启动YARN,以yarn用户在指定节点启动资源管理器:
$HADOOP_HOME/bin/yarn --daemon start resourcemanager
以yarn用户,在每台指定的主机运行脚本启动节点管理器:
$HADOOP_HOME/bin/yarn --daemon start nodemanager
开始一个独立模式的WebAppProxy 服务。用yarn用户,启动运行WebAppProx服务.如果有多台要使用与负载均衡,那么应该在每台上面运行这些命令。
$HADOOP_HOME/bin/yarn --daemon start proxyserver
如果有etc/hadoop/works和免密登录配置了,可以以yarn用户,用一个通用的脚本来启动所有的yarn进程:
$HADOOP_HOME/sbin/start-yarn.sh
用如下命令来启动MapReduce JobHistory Server ,以mapred用户在指定的机器上运行:
$HADOOP_HOME/bin/mapred --daemon start historyserver
关闭Hadoop
用如下命令关闭名称节点,以hdfs用户在指定的名称节点上运行:
$HADOOP_HOME/bin/hdfs --daemon stop namenode
以hdfs用户运行脚本关闭数据节点:
$HADOOP_HOME/bin/hdfs --daemon stop datanode
如果etc/hadoop/workers有且ssh信任访问配置了,可以以hdfs用户,用一个通用的脚本去停止所有hdfs进程:
$HADOOP_HOME/sbin/stop-dfs.sh
用如下的命令来关闭资源管理器,以yarn用户在指定的资源管理器上运行:
$HADOOP_HOME/bin/yarn --daemon stop resourcemanager
Run a script to stop a NodeManager on a worker as yarn:
[yarn]$ $HADOOP_HOME/bin/yarn --daemon stop nodemanager
If etc/hadoop/workers and ssh trusted access is configured (see Single Node Setup), all of the YARN processes can be stopped with a utility script. As yarn:
[yarn]$ $HADOOP_HOME/sbin/stop-yarn.sh
Stop the WebAppProxy server. Run on the WebAppProxy server as yarn. If multiple servers are used with load balancing it should be run on each of them:
[yarn]$ $HADOOP_HOME/bin/yarn stop proxyserver
Stop the MapReduce JobHistory Server with the following command, run on the designated server as mapred:
[mapred]$ $HADOOP_HOME/bin/mapred --daemon stop historyserver
Web Interfaces
一旦Hadoop集群启动,就可以通过如下几项WEB-UI去检查集群的各个模块:
守护进程 | Web Inteface | 注释 |
---|---|---|
名称节点 | http://nn_host:port/ | 默认端口是9870 |
资源管理器 | httP://rm_host:port/ | 默认端口是8088 |
MapReduce JobHistory Server | http://jhs_host:port | 默认端口是19888 |
关于搭建完全分布式模式集群的更多信息,请参看Cluster Setup
↓↓↓ 点击"阅读原文" 【进入官网】
以上是关于Hadoop官网翻译 FileSystem/OutputStream的主要内容,如果未能解决你的问题,请参考以下文章
Hadoop官网翻译 FileSystem/OutputStream