HDFS的追加/刷新/读设计

本文探讨了HDFS中未关闭文件与已关闭文件的数据持久性差异。未关闭文件仅提供最大努力持久化,NameNode仅持久化元数据信息;而关闭后的文件则提供强持久化,确保数据块副本数与复制因子一致。此外,还讨论了fsync方法更名至hflush的变化。

hdfs将在0.21版(尚未发布),把DFSOutputStream中的fsync操作(实际上是sync方法)更名为hflush, 因为之前的fsync做的工作实际上不是同步数据到磁盘,而是刷新(flush)缓存。fsync功能可能会在以后的版本中添加。

 

DFS对于未关闭文件的数据提供最大努力持久:
1. NameNode持久化文件元数据信息,但不持久化文件由哪些块组成的信息。重启NameNode可能会导致数据丢失。
2. DFS不保证各数据块的副本数和文件的复制因子一致。如果一个数据块没有一个有效副本被写入,则写失败。

 

DFS对于已关闭文件的数据提供强持久:
1. NameNode持久化文件和数据块元数据信息。重启NameNode不会导致数据丢失。
2. DFS保证各数据块的副本数和文件的复制因子一致。
3. 文件关闭不保证数据已经到达磁盘。如果数据未到达磁盘,重启DataNode会导致数据丢失。

对于未关闭文件的数据,只有已完成块的数据对readers是可见的。正在写的块中的数据,对reader来说是不可见的。

任务描述 本关任务:配置 Flume 相关配置内容,完成采集目录下所有文件至 HDFS 中。 相关知识 为了完成本关任务,你需要掌握: Exec Source; Memory Channel; HDFS Sink; 采集示例。 Exec Source Fluem Exec Source 介绍及属性详解如下所述: Exec Source 在启动时运行一个给定的 Unix 命令,并期望该进程在标准输出上不断地生成数据(除非将属性 logStdErr 设置为 true,否则将直接丢弃 stderr)。如果进程出于任何原因退出,源也将退出,并且不会产生进一步的数据。这意味着像cat [named pipe]或tail - f [file]这样的配置将产生预期的结果,而as date可能不会产生这种结果——前两个命令将产生数据流,而后者将产生单个事件并退出。 属性详解 必要属性: agent.sources=xx //当前source的名称 agent.sources.xx.channels=xxx //当前source连接的channel的名称,因为一个source可以连接多个channel,所以这的属性为channels agent.sources.xx.type=exec //当前source的类型 agent.sources.xx.command=xxxx //当前source在exec类型下的执行命令 其他属性: shell //用于运行命令的shell调用。例如/bin/sh - c。仅适用于依赖于通配符、反勾号、管道等shell特性的命令。 restartThrottle //尝试重新启动前等待的时间(以毫秒为单位) 默认值:10000 restart //如果执行的cmd死亡,是否应该重新启动它 默认值:false logStdErr //是否应该记录命令的stderr 默认值:false batchSize //一次取和发送到通道的最大行数 默认值:20 batchTimeout //如果没有达到缓冲区大小,则在数据被向下推送之前等待的时间(以毫秒为单位) 默认值:3000 selector.type //replicating(复用) 或者 multiplexing(多路复用) interceptors //以空格分隔的拦截器列表 ExecSource和其他异步源的问题是,如果无法将事件放入客户机知道的通道中,则源不能保证该事件。在这种情况下,数据将丢失。例如,最常见的请求特性之一是tail -F [file]类用例,在这种用例中,应用程序向磁盘上的日志文件写入数据,Flume 跟踪文件,将每一行作为一个事件发送。虽然这是可能的,但有一个明显的问题;如果通道被填满,Flume 不能发送事件,会发生什么? Flume 无法向编写日志文件的应用程序表明它需要保留日志,或者由于某种原因没有发送事件。如果这没有意义,您只需要知道这一点:当使用单向异步接口(如 ExecSource )时,您的应用程序永远不能保证数据已被接收!作为此警告的扩展(而且要完全清楚),在使用此源时绝对没有事件交付的保证。要获得更强的可靠性保证,可以考虑使用假脱机目录源、Taildir 源或通过 SDK 与 Flume 直接集成。 Memory Channel Memory Channel 介绍及属性详解如下所述: Events 存储在 Java Heap,即内存队列中(内存的大小是可以指定的)。对于流量较高和由于 Agent 故障而准备丢失数据的流程来说,这是一个理想的选择; 属性详解 //必有属性 agent.channels=xx //指定当前channel的名称 agent.channels.xx.type=memory //其他属性 capacity //存储在通道中的最大事件数量 默认值:100 transactionCapacity //通道在每个事务中将从源获取或提供给接收器的最大事件数 默认值:100 keep-alive //超时(以秒为单位),用于添加或删除事件 默认值:3 byteCapacityBufferPercentage //定义字节码容量与估计的通道中所有事件的总大小之间的缓冲区百分比,以解释报头中的数据。 默认值:20 byteCapacity //允许的最大内存字节数,作为该通道中所有事件的总和。实现只计算事件体,这也是提供bytecapacitybufferpercent配置参数的原因。默认计算值等于JVM可用的最大内存的80%(即在命令行上传递的-Xmx值的80%)。请注意,如果您在一个JVM上有多个内存通道,并且它们碰巧包含相同的物理事件(例如,如果您使用来自单个源的复制通道选择器),那么出于通道字节码的目的,这些事件大小可能会被重复计算。将该值设置为0将导致该值回落到大约200gb的硬内部限制。 HDFS Sink File Channel 介绍及属性详解如下所述: 这个接收器将事件写入 Hadoop 分布式文件系统( HDFS )。它目前支持创建文本和序列文件。它支持这两种文件类型的压缩。可以根据经过的时间、数据大小或事件数量定期滚动文件(关闭当前文件并创建一个新文件)。它还根据时间戳或事件起源的机器等属性对数据进行存储/分区。 HDFS 目录路径可能包含格式化转义序列,这些转义序列将被 HDFS 接收器替换,以生成一个目录/文件名来存储事件。使用这个接收器需要安装 Hadoop ,以便 Flume 可以使用Hadoop jar 与 HDFS 集群通信。注意,需要一个支持 sync() 调用的 Hadoop 版本。 属性详解 必有属性: agent.sinks=xx //当前sink的名称 agent.sinks.xx.type = hdfs //当前sink的类型 agent.sinks.xx.channel=xxx //与当前sink连接的channel的名称,因为一个sink只能连接一个channel,所以当前的属性为channel agent.sinks.xx.hdfs.path=$HDFS_PATH //hdfs上的目录路径 其他属性: hdfs.filePrefix //Flume在hdfs创建的目录中创建的文件路径的上一级 hdfs.fileSuffix //附加到文件的后缀(例如:.avro -注意:句点不会自动添加) hdfs.inUsePrefix //前缀,用于flume主动写入的临时文件 hdfs.inUseSuffix //后缀,用于flume主动写入的临时文件 默认值:.tmp hdfs.emptyInUseSuffix //if false,在编写输出时使用inUseSuffix中设置的参数,关闭输出hdfs之后。从输出文件名中删除inUseSuffix设置的参数。if true,则inUseSuffix参数被忽略,取而代之的是一个空字符串。 默认值:false hdfs.rollInterval //在滚动当前文件之前等待的秒数(0 =根据时间间隔永不滚动) 默认值:30 hdfs.rollSize //要触发滚动的文件大小,以字节为单位(0:永远不要基于文件大小进行滚动) 默认值:1024 hdfs.rollCount //滚前写入文件的事件数(0 =从不基于事件数滚) 默认值:10 hdfs.idleTimeout //关闭非活动文件的超时(0 =禁用自动关闭空闲文件) 默认值:0 hdfs.batchSize //在将文件刷新HDFS之前写入文件的事件数 默认值:100 hdfs.codeC //压缩编解码器:gzip, bzip2, lzo, lzop, snappy hdfs.fileType //文件格式:SequenceFile, DataStream或CompressedStream (1)DataStream不会压缩输出文件,请不要设置codeC (2)CompressedStream需要设置hdfs。带有可用编解码器的编解码器 默认值:SequenceFile hdfs.maxnOpenFiles //只允许这个开放文件的数量。如果超过这个数字,则关闭最古老的文件。 默认值:5000 hdfs.minBlockReplicas //指定每个HDFS块的最小复制数。如果没有指定,它来自类路径中的默认Hadoop配置 hdfs.writeFormat //序列文件(SequenceFile)记录的格式。Text或Writable在使用Flume创建数据文件之前设置为Text,否则这些文件不能被Apache Impala(孵化)或Apache Hive取。 默认值:Writable hdfs.threadsPoolSize //用于HDFS IO操作(打开、写入等)的每个HDFS接收器的线程数 默认值:10 hdfs.rollTimerPoolSize //每个HDFS接收器用于调度定时文件滚动的线程数 默认值:1 hdfs.kerberosPrincipal //访问安全HDFS的Kerberos用户主体 hdfs.kerberosKeytab //Kerberos keytab用于访问安全的HDFS hdfs.round //是否应该将时间戳四舍五入(如果为真,则影响除%t之外的所有基于时间的转义序列) 默认值:false hdfs.roundUnit //四舍五入的单位,时间,分钟,或小时 默认值:second hdfs.roundValue //将此(在使用hdfs.roundUnit配置的单元中)分为以上多个(在单元配置的单元中),小于当前时间 默认值:1 hdfs.timeZone //用于解析目录路径的时区的名称,例如:America/Los Angeles。 默认值:Local Time hdfs.useLocalTimeStamp //在替换转义序列时,使用本地时间(而不是事件头的时间戳) 默认值:false hdfs.closeTries //设置为0:有节点挂掉后,不会给file重命名,并且文件可能一直处于打开状态,并且后缀为自己设置的后缀;设置为1:有节点挂掉后,会尝试给file重命名,但是次数有限制;如果尝试失败,文件会保持开启,但会在flume再次启动时关闭. 默认值:0 hdfs.retryInterval //在连续试图关闭文件之间的时间。每个关闭调用都要花费多个RPC往返于Namenode,因此设置太低会导致名称节点上的大量负载。如果设置为0或更少,sink将不会试图关闭该文件 默认值:180 serializer //其他可能的选项包括avro_event或EventSerializer.BUilder实现的完全限定类名 默认值:TEXT 采集示例 接下来让我们通过一个简单采集示例来了解本实训 Flume 采集方案案例的编写。 案例分析 案例流程图如下: 案例流程如下: 创建符合条件的flume配置文件; 执行配置文件,开启监控; 向flumedata目录中文件写入数据; exec source 实时监控文件是否有追加数据写入; 将取到的数据,通过 Hdfs Sink 方式输出到 HDFS。 Exec Source 常用配置如下: Property Name Default Description channels - type - exec command - 运行的linux命令 shell - 指定shell类型 batchSize 20 每次取并传送给channel的最大行数 selector.type replicating replicating or multiplexing;选择器类型,默认将源数据复制发送给所有channel 配置文件内容如下: # Name the components on this agent a1.sources = r1 a1.sinks = k1 a1.channels = c1 # Describe/configure the source a1.sources.r1.type = exec a1.sources.r1.spoolDir = tail -F /opt/flume/flumedata/test.log # Describe the sink a1.sinks.k1.type = hdfs a1.sinks.k1.hdfs.path = hdfs://hadoop101:9000/user/root/flume/splogs/%Y%m%d #上传文件的前缀 a1.sinks.k1.hdfs.filePrefix = logs- a1.sinks.k1.hdfs.fileSuffix = hdfs #是否按照时间滚动文件夹 a1.sinks.k1.hdfs.round = true #多少时间单位创建一个新的文件夹 a1.sinks.k1.hdfs.roundValue = 1 #重新定义时间单位 a1.sinks.k1.hdfs.roundUnit = hour #是否使用本地时间戳 a1.sinks.k1.hdfs.useLocalTimeStamp = true #积攒多少个 Event 才 flush 到 HDFS 一次,到了一定时间了也会去flush a1.sinks.k1.hdfs.batchSize = 1000 #设置文件类型,可支持压缩 a1.sinks.k1.hdfs.fileType = DataStream #多久生成一个新的文件,60s a1.sinks.k1.hdfs.rollInterval = 60 #设置每个文件的滚动大小 a1.sinks.k1.hdfs.rollSize = 134117700 #文件的滚动与 Event 数量无关 a1.sinks.k1.hdfs.rollCount = 0 # Use a channel which buffers events in memory a1.channels.c1.type = memory a1.channels.c1.capacity = 1000 a1.channels.c1.transactionCapacity = 100 # Bind the source and sink to the channel a1.sources.r1.channels = c1 a1.sinks.k1.channel = c1 注意:对于所有与时间相关的转义序列,Event Header 中必须存在以 timestamp 的 key(除非 hdfs.useLocalTimeStamp 设置为 true,此方法会使用 TimestampInterceptor 自动添 timestamp)。 启动监控文件夹命令: bin/flume-ng agent --conf conf/ --name a1 --conf-file job/flume-file-hdfs.conf 参数说明: --conf/-c:表示配置文件存储在 conf/目录 --name/-n:表示给 agent 起名为 a1 --conf-file/-f:Flume 本次启动取的配置文件是在 job 文件夹下的 flume-file-hdfs.conf 文件。 说明:在使用 Spooling Directory Source 时,不要在监控目录中创建并持续修改文件(无法动态取文件内容);上传完成的文件会以.COMPLETED 结尾(默认,可以修改);被监控文件夹每 500 毫秒扫描一次文件变动。 向 data 文件夹中添加文件 在/opt/flume 目录下创建 data 文件夹 [educoder@hadoop101 flume]$ mkdir data 向 data 文件夹中添加文件 [educoder@hadoop101 flume]$ touch 1.txt [educoder@hadoop101 flume]$ touch 2.txt [educoder@hadoop101 flume]$ touch 3.txt 查看 HDFS 上的数据 打开 HDFS 的 web 界面,到配置文件中指定的目录下查看 编程要求 根据提示,将 /opt/flume/flumedata 目录下的 aa.txt (平台已经帮你创建完毕) 采集到 Hdfs,你只需在Begin-End区域内配置配置文件即可,其余步骤后台会自动完成(平台后台向 aa.txt 文件中发送一条消息 From introduction to mastery,因为本实训中 source 源为 exec,学员在自己电脑环境中可以使用命令行发送,命令为echo " From introduction to mastery" >> /opt/flume/flumedata/aa.txt)。 aa.txt文件中的内容如下: Hadoop JAVA Flume 配置文件要求 : Agent命名为 a1 ; source选用 exec 采集所有文件; Channel选用 memery; 文件保存到 hdfs有如下要求 : hdfs路径名称: hdfs://localhost:9000; 保存到 flume 目录下; 文件前缀命名为 wcm; 文件后缀命名为 .wsy; 每 6s 回滚一次文件; 文件格式使用DataStream。 测试说明 本次评测最后查看 HDFS 中 /flume 目录是否存在传递过来的数据。 预期输出: Hadoop JAVA Flume From introduction to mastery 开始你的任务吧,祝你成功!
最新发布
10-28
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值