Hive读取Flume正在写入的HDFS

Hive的表创建为外部分区表,例如:

 
  1. USE mydb;
  2. CREATE EXTERNAL TABLE mytable
  3. (
  4. c1 String,
  5. c2 INT,
  6. c3 INT,
  7. create_time String
  8. )
  9. PARTITIONED BY (dt STRING)
  10. ROW FORMAT DELIMITED FIELDS TERMINATED BY '|||';

然后创建分区,如:

 
  1. ALTER TABLE mytable ADD PARTITION (dt = '2013-09-25') LOCATION '/data/mytable/2013-09-25/';
  2. ALTER TABLE mytable ADD PARTITION (dt = '2013-09-26') LOCATION '/data/mytable/2013-09-26/';
  3. ALTER TABLE mytable ADD PARTITION (dt = '2013-09-27') LOCATION '/data/mytable/2013-09-27/';

即Hive的表按天进行分区。指定到相应目录。

删除分区

alter table mytable drop partition (dt=’2012-03-06’)

注意hdfs的起始路径,从hdfs的根目录开始,不然会加载不到数据。

分区可以写成脚本每天自动执行。处理昨天的数据

 
  1. yesterday=$(date -d '-1 day' '+%Y-%m-%d')
  2. $HIVE_HOME/bin/hive -e "use mydb;ALTER TABLE mytable ADD PARTITION (dt = '$yesterday') LOCATION '/user/hive/warehouse/tail/$yesterday/';"

而Flume中配置将数据保存到HDFS中,即HDFS sink。计划每天一个文件,进行日切。如2013-09-25对应的文件就保存在:

hdfs:///data/mytable/2013-09-25/FlumeData.xxx

这样,只要文件生成,就能直接通过操作Hive的mytable表来对文件进行统计了。

业务上要求统计工作是按照小时进行,考虑到按照小时进行分区过于细化,而且会导致过多的文件给NameNode造成内存压力,所以如上Hive层面按天进行划分。

统计执行时首先指定天分区,然后根据create_time(mm:hh:ss)指定统计时间段,如:

 
  1. SELECT c1,
  2. SUM(c2),
  3. SUM(c3)
  4. FROM mytable
  5. WHERE dt = ’2013-09-25′
  6. AND create_time BETWEEN ’22:00:00′ AND ’22:59:59′
  7. GROUP BY c1;

在实践的过程中遇到如下两个问题:

1.对于正在写入的文件,通过hadoop fs -ls 命令查看,其大小始终是0,即使通过hadoop fs -cat可以看到实际已经有内容存在!通过hive处理的话也看不到其中的数据。

2.Flume正在写入的文件,默认会有.tmp后缀。如果Hive在执行过程中,Flume切换文件,即将xxx.tmp重命名为xxx,这时Hive会报错如file not found xxx.tmp。

针对问题1

首先了解HDFS的特点:

HDFS中所有文件都是由块BLOCK组成,默认块大小为64MB。在我们的测试中由于数据量小,始终在写入文件的第一个BLOCK。而HDFS与一般的POSIX要求的文件系统不太一样,其文件数据的可见性是这样的:

 
  1. 如果创建了文件,这个文件可以立即可见;
  2. 写入文件的数据则不被保证可见了,哪怕是执行了刷新操作(flush/sync)。只有数据量大于1个BLOCK时,第一个BLOCK的数据才会被看到,后续的BLOCK也同样的特性。正在写入的BLOCK始终不会被其他用户看到!
  3. HDFS中的sync()保证数据持久化到了datanode上,然后可以被其他用户看到。

针对HDFS的特点,可以解释问题1中的现象,正在写入无法查看。但是使用Hive统计时Flume还在写入那个BLOCK(数据量小的时候),那岂不是统计不到信息?

解决方案:

每天再按小时切分文件——这样虽然每天文件较多,但是能够保证统计时数据可见!Flume上的配置项为hdfs.rollInterval。

如果文件数多,那么还可以考虑对以前的每天的小时文件合并为每天一个文件!

针对问题2

原因比较明显,Hive处理前获取了对应分区下的所有文件信息,其中包含xxx.tmp文件,而传递给MapReduce处理时,由于Flume进行了切换,导致原来的xxx.tmp变成了xxx,新的.tmp名称又变成了yyy.tmp,这样自然找不到xxx.tmp了。

解决方案:

解决这个问题想法之一是想控制Hive的处理时机,但是显然不是那么好控制。

进一步了解到HDFS的Java API读取HDFS文件时,会忽略以”.”和”_”开头的文件!类似于Linux中默认.xx是隐藏的一样,应用程序读取HDFS文件时默认也不读取.xxx和_xxx这样名称的文件!

这样就产生了针对问题2的处理方案一)配置Flume,针对正在写入的文件,以.号开头。涉及Flume配置项hdfs.inUsePrefix。

 
  1. # The configuration file needs to define the sources,
  2. # the channels and the sinks.
  3. # Sources, channels and sinks are defined per agent,
  4. # in this case called 'a
  5. #agent section
  6. producer.sources = s
  7. producer.channels = c
  8. producer.sinks = r
  9. #producer.sources.s.type = seq
  10. producer.sources.s.channels = c
  11. producer.sources.s.type = exec
  12. producer.sources.s.command=tail -n 0 -F /usr/local/nginx/nginxlog/access.log
  13. producer.sources.s.deletePolicy=never
  14. #producer.sources.s.type = avro
  15. #producer.sources.s.bind = localhost
  16. #producer.sources.s.port = 10000
  17. # Each sink's type must be defined(给谁了)
  18. #producer.sinks.r.type = avro
  19. #producer.sinks.r.hostname = 10.1.1.100
  20. #producer.sinks.r.port = 20000
  21. producer.sources.source1.interceptors = i1
  22. producer.sources.source1.interceptors.i1.type = timestamp
  23. producer.sinks.r.type = hdfs
  24. producer.sinks.r.hdfs.path = hdfs://localhost:8010/user/hive/warehouse/tail/%Y-%m-%d
  25. producer.sinks.r.hdfs.inUsePrefix = .
  26. producer.sinks.r.hdfs.maxOpenFiles = 5000
  27. producer.sinks.r.hdfs.batchSize= 1000
  28. producer.sinks.r.hdfs.fileType = DataStream
  29. producer.sinks.r.hdfs.writeFormat =Text
  30. producer.sinks.r.hdfs.rollSize = 128000000
  31. producer.sinks.r.hdfs.rollCount = 0
  32. producer.sinks.r.hdfs.rollInterval = 3600
  33. producer.sinks.r.hdfs.useLocalTimeStamp = true
  34. producer.sinks.r.request.required.acks=1
  35. producer.sinks.r.max.message.size=1000000
  36. producer.sinks.r.producer.type=sync
  37. producer.sinks.r.custom.encoding=UTF-8
  38. #Specify the channel the sink should use
  39. producer.sinks.r.channel = c
  40. # Each channel's type is defined.
  41. producer.channels.c.type = memory
  42. producer.channels.c.capacity = 1000000
  43. producer.channels.c.transactionCapacity = 1000
  44. #producer.channels.c.type=file
  45. #producer.channels.c.checkpointDir=/usr/local/flumeng/checkpointdir/tcpdir/example_agent
  46. #producer.channels.c.dataDirs=/usr/local/flumeng/datadirs/tddirs/example_agen

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340