【问题标题】:Querying Data from DBMS in Hadoop Mapper Before Mapping映射前在 Hadoop Mapper 中从 DBMS 中查询数据
【发布时间】:2013-01-15 08:59:36
【问题描述】:

我对 Hadoop 中的 MapReduce 有点陌生。我正在尝试处理来自许多日志文件的条目。 mapper 流程​​与WordCount 教程中的非常相似。

public void map(LongWritable key, Text value, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException {
    String line = value.toString();
    StringTokenizer tokenizer = new StringTokenizer(line);
    while (tokenizer.hasMoreTokens()) {
        word.set(tokenizer.nextToken());
        output.collect(word, one);
    }
}

我不想把这个词作为reducer的键,而是把一个表中的相关数据放在RDBMS中。比如处理后的文字是这样的

apple orange duck apple giraffe horse lion, lion grape

还有一张桌子

name     type
apple    fruit
duck     animal
giraffe  animal
grape    fruit
orange   fruit
lion     animal

所以,我不想计算单词,而是计算类型。输出会像

fruit 4
animal 5

假设在前面的代码中,会是这样的

public void map(LongWritable key, Text value, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException {
    String line = value.toString();
    StringTokenizer tokenizer = new StringTokenizer(line);
    while (tokenizer.hasMoreTokens()) {
        String object = tokenizer.nextToken();
        //========================================
        String type = SomeClass.translate(object);
        //========================================
        word.set(type);
        output.collect(word, one);
    }
}

SomeClass.translate 将通过从 RDBMS 查询将对象名称转换为类型。

我的问题

  1. 这可行吗? (以及如何做到这一点?)
  2. 有什么顾虑?我了解到映射器将在多台机器上运行。那么假设在多台机器上有apple字,如何减少apple的数据库查找次数?
  3. 或者有没有在映射器中不进行翻译的非常好的选择?或者也许有一种常见的方法可以做到这一点? (或者这整个问题是一个非常愚蠢的问题?)

更新

我在 Amazon Elastic MapReduce 上使用 Apache Hadoop 实现它,转换表存储在 Amazon RDS/MySQL 中。如果您能提供一些示例代码或链接,我将不胜感激。

【问题讨论】:

    标签: hadoop mapreduce


    【解决方案1】:

    如果您担心最小化 DB 查询,您可以在两个 MR 作业中执行此操作:首先进行标准字数统计,然后使用该作业的输出进行翻译以输入并重新求和。

    或者,如果您的映射表足够小以适合内存,您可以首先对其进行序列化,将其添加到 DistributedCache,然后作为 Mapper 设置方法的一部分将其加载到内存中。那么就不用担心翻译太多次了,因为它只是一个廉价的内存查找。

    【讨论】:

    • 翻译表相对于要汇总的整个数据来说确实很小,但是分布式缓存有什么限制呢?
    • DistributedCache 只是将文件从一个本地 FS 复制到另一个。所以除了磁盘空间之外,这些文件的大小可能没有限制,但是非常大的文件会影响性能。
    • 对于第一个解决方案,考虑到环境,您建议如何进行翻译工作(请参阅问题中的更新)? (忍受我,我对这个真的很陌生)
    • 作为 EMR 作业流的一部分,您可以指定一个仅运行 shell 脚本的步骤。从该脚本中,您可以运行 mysql 命令,例如 SELECT name, type FROM mytable INTO OUTFILE '/tmp/table.csv' FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n' 然后您可以将生成的文件作为普通 csv 文件读取。
    • 现在我明白了。非常感谢!
    【解决方案2】:

    总结需求,在表中的数据和文件之间进行连接,并对连接的数据进行计数。根据数据的输入大小,可以使用不同的方式(仅限 M 或 MR)连接。有关加入的更多详细信息,请参阅Data-Intensive Text Processing with MapReduce - 第 3.5 节。

    【讨论】:

    • 老实说,起初我正在寻找使用 Hadoop MapReduce 的更实用的技巧。但是,对于有关 MapReduce 的基本概念知识,这是一个很好的参考。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2019-07-03
    • 2019-08-02
    • 2017-01-27
    • 2014-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多