我们目前在HDFS集群上有一些数据,我们使用Hive在该集群上生成报告。基础设施正处于退役的过程中,我们剩下的任务是找到生成数据报告的替代方案(我们将数据作为tab分隔的文件导入到新环境中)
假设我们有一个包含以下字段的表。
- 查询
- IPAddress
- LocationCode
我们用来在Hive上运行的原始SQL查询是(好吧,不完全是…但类似的东西)
select
COUNT(DISTINCT Query, IPAddress) as c1,
LocationCode as c2,
Query as c3
from table
group by Query, LocationCode
我想知道是否有人可以为我提供一个最有效的脚本,使用标准的unix/linux工具,如sort, uniq和awk,可以作为上述查询的替代品。
假设脚本的输入是一个文本文件目录。该目录将包含大约2000个文件。每个文件将包含任意数量的以制表符分隔的记录,格式为:
Query <TAB> LocationCode <TAB> IPAddress <NEWLINE>
一旦你有了一个包含所有唯一的
的排序文件Query <TAB> LocationCode <TAB> IPAddress <NEWLINE>
你可以:
awk -F 't' 'NR == 1 {q=$1; l=$2; count=0}
q == $1 && l == $2{count++}
q != $1 || l != $2{printf "%st%st%dn", q, l, count; q=$1; l=$2; count=1}
END{printf "%st%st%dn", q, l, count}' sorted_uniq_file
要得到这个sorted_uniq_file
,朴素的方法可以是:
sort -u dir/* > sorted_uniq_file
但是这可能会很长且占用内存。
一个更快的选择(和更少的内存消耗)可能是尽快消除重复,先排序,然后合并。这需要一个临时空间来存放已排序的文件,让我们使用一个名为sorted
的目录:
mkdir sorted;
for f in dir/*; do
sort -u $f > sorted/$f
done
sort -mu sorted/* > sorted_uniq_file
rm -rf sorted
如果上述解达到壳极限或排序极限(dir/*
的展开式,或sorted/*
的展开式,或sort
的参数个数):
mkdir sorted;
ls dir | while read f; do
sort -u dir/$f > sorted/$f
done
while [ `ls sorted | wc -l` -gt 1 ]; do
mkdir sorted_tmp
ls sorted | while read f1; do
if read f2; then
sort -mu sorted/$f1 sorted/$f2 > sorted_tmp/$f1
else
mv sorted/$f1 sorted_tmp
fi
done
rm -rf sorted
mv sorted_tmp sorted
done
mv sorted/* sorted_uniq_file
rm -rf sorted
上面的解决方案可以优化为同时合并两个以上的文件
不是直接回答你原来的问题(你已经得到),但如果你有一堆平面文件数据,你想以不同的方式查询,你可以考虑使用NoSQL
:
这个NoSQL项目与最近被称为"NoSQL数据库"的项目完全不同(并且早了许多年)。相反,这种NoSQL将以Awk为核心的Unix工具捆绑在一起,以简化它们在访问和维护格式化文本文件数据库时的使用。