0

以下是我对处理文本文件的hadoop框架的看法。如果我在某个地方出错,请纠正我。

每个映射器都作用于包含一些记录的输入拆分。对于每个输入拆分,都会创建一个记录读取器,它开始从输入拆分中读取记录。如果输入拆分中有 n 条记录,则映射器中的 map 方法被调用 n 次,然后使用记录读取器读取键值对。

现在进入数据库透视图,我在单个远程节点上有一个数据库。我想从这个数据库的表中获取一些数据。我将使用 DBConfigure 配置参数并使用 DBInputFormat 提及输入表。现在假设我的表总共有 100 条记录,我执行一个 SQL 查询,在输出中生成 70 条记录。

我想知道 :

在上述案例(数据库)中如何创建 InputSplits?

输入拆分创建取决于什么,我的 sql 查询生成的记录数或表(数据库)中的记录总数?

在上述情况(数据库)中创建了多少 DBRecordReader?

4

3 回答 3

2

在上述案例(数据库)中如何创建 InputSplits?

// Split the rows into n-number of chunks and adjust the last chunk
// accordingly
  for (int i = 0; i < chunks; i++) {
    DBInputSplit split;
    if ((i + 1) == chunks)
      split = new DBInputSplit(i * chunkSize, count);
    else
      split = new DBInputSplit(i * chunkSize, (i * chunkSize)
          + chunkSize);
    splits.add(split);
  }

有方法,但要了解它取决于什么,让我们看一下 chunkSize:

statement = connection.createStatement();
results = statement.executeQuery(getCountQuery());
results.next();

long count = results.getLong(1);

int chunks = job.getConfiguration().getInt("mapred.map.tasks", 1);
long chunkSize = (count / chunks);

所以 chunkSize 采用 count =SELECT COUNT(*) FROM tableName并将其除以 chunks =mapred.map.tasks或 1 如果未在配置中定义。

最后,每个输入拆分都将RecordReader创建一个来处理您正在读取的数据库类型,例如:MySQLDBRecordReader对于 MySQL 数据库。

有关更多信息,请查看来源

于 2013-04-27T16:03:37.727 回答
1

看来@Engineiro 通过采用实际的 hadoop 源很好地解释了它。只是为了回答,DBRecordReader 的数量等于地图任务的数量。

为了进一步解释,Hadoop Map 端框架为每个 Map 任务创建一个 DBRecordReader 实例,以防子 JVM 不被重用于进一步的 Map 任务。换句话说,在 DBInputFormat 的情况下,输入拆分的数量等于 map.reduce.tasks 的值。因此,每个 map Task 的记录 Reader 都有元信息来构造查询以从表中获取数据子集。每个 Record Reader 都执行类似于下面的分页类型的 SQL。

SELECT * FROM (SELECT a.*,ROWNUM dbif_rno FROM ( select * from emp ) a WHERE rownum <= 6 + 7 ) WHERE dbif_rno >= 6

上述 SQL 用于第二个 Map 任务返回 6 到 13 之间的行

为了概括任何类型的输入格式,记录读取器的数量等于地图任务的数量。

于 2013-04-29T03:05:42.803 回答
0

这篇文章谈论你想要的一切:http: //blog.cloudera.com/blog/2009/03/database-access-with-hadoop/

于 2013-04-27T15:28:44.800 回答