1

我们目前在 HDFS 集群上有一些数据,我们使用 Hive 在其上生成报告。基础设施正在退役,我们的任务是提出生成数据报告的替代方案(我们将其作为制表符分隔的文件导入到我们的新环境中)

假设我们有一个包含以下字段的表。

  • 询问
  • IP地址
  • 位置代码

我们曾经在 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>
4

2 回答 2

1

一旦你有一个包含所有唯一的排序文件

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 "%s\t%s\t%d\n", q, l, count; q=$1; l=$2; count=1}
END{printf "%s\t%s\t%d\n", 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

上面的解决方案可以优化为同时合并超过 2 个文件。

于 2011-08-15T19:59:45.500 回答
1

不是对您的原始问题(您已经得到)的直接答案,但是如果您有一堆要以不同方式查询的平面文件数据,您可能会考虑使用NoSQL

http://www.strozzi.it/cgi-bin/CSA/tw7/I/en_US/nosql/Home%20Page

这个 NoSQL 项目与最近被称为“NoSQL 数据库”的项目(并且早很多年)完全不同。相反,这个 NoSQL 将 Unix 工具结合在一起,以 Awk 为核心,以简化它们在访问和维护格式化文本文件数据库时的使用。可以很容易地做很多漂亮的事情,例如表连接。

于 2011-08-26T23:58:10.403 回答