中 文 登 录 ( 或 注 册 ) 技 术 主 题 软 件 下 载 社 区 技 术 讲 座 搜 索 developerworks developerworks 技 术 主 题 Java technology 文 档 库 Java 开 发 2.0: 用 Hadoop MapReduce 进 行 大 数 据 分 析 成 堆 的 数 据 如 何 变 成 信 息 金 矿 Andrew Glover, 作 家 和 开 发 人 员, Beacon50 简 介 : Apache Hadoop 是 目 前 分 析 分 布 式 数 据 的 首 选 工 具, 和 大 多 数 Java 2.0 技 术 一 样, 是 可 扩 展 的 从 Hadoop 的 MapReduce 编 程 建 模 开 始, 学 习 如 何 用 它 来 分 析 数 据, 满 足 大 大 小 小 的 商 业 信 息 需 求 查 看 本 系 列 更 多 内 容 发 布 日 期 : 2011 年 4 月 18 日 级 别 : 中 级 原 创 语 言 : 英 文 访 问 情 况 6926 次 浏 览 建 议 : 标 记 本 文! Google 在 2001 年 发 布 图 像 搜 索 功 能 时, 只 有 2.5 亿 索 引 图 像, 不 到 10 年, 这 个 巨 大 的 搜 索 功 能 已 经 可 以 检 索 超 过 100 亿 个 图 像 了, 每 分 钟 有 35 小 时 的 内 容 上 传 到 YouTube 据 称,Twitter 每 天 平 均 处 理 5500 万 tweet 今 年 早 些 时 候, 搜 索 功 能 每 天 记 录 6 亿 条 查 询 记 录 这 就 是 我 们 讨 论 大 数 据 的 意 义 所 在 如 此 大 规 模 的 数 据 一 度 仅 限 于 大 企 业 学 校 和 政 府 机 构 这 些 机 构 有 能 力 购 买 昂 贵 的 超 级 计 算 机 能 够 雇 用 员 工 保 障 其 运 行 今 天, 由 于 存 储 成 本 的 降 低 和 处 理 能 力 的 商 品 化, 一 些 小 公 司, 甚 至 个 人 都 可 以 存 储 和 挖 掘 同 样 的 数 据, 推 动 新 一 轮 的 应 用 程 序 创 新 大 数 据 革 命 技 术 之 一 是 MapReduce, 一 个 编 程 模 式, 是 Google 针 对 大 规 模 分 布 式 数 据 而 开 发 的 在 本 文 中, 我 将 介 绍 Apache 的 开 源 MapReduce 实 现,Hadoop, 也 有 人 将 其 称 之 为 云 计 算 的 杀 手 应 用 程 序 关 于 Hadoop 关 于 本 系 列 从 Java 技 术 首 次 亮 相 以 来,Java 开 发 的 格 局 已 经 发 生 了 巨 大 的 变 化 得 益 于 成 熟 的 开 源 框 架 和 可 靠 的 租 用 式 部 署 基 础 设 施, 现 在 已 经 可 以 迅 速 经 济 地 汇 编 测 试 运 行 和 维 护 Java 应 用 程 序 了 在 本 系 列 中,Andrew Glover 将 探 索 使 这 种 全 新 开 发 范 例 成 为 可 能 的 各 种 技 术 和 工 具 内 容 关 于 Hadoop 数 据, 无 处 不 在 的 数 据! 使 用 opencsv 进 行 数 据 解 析 Hadoop 的 map 和 reduce 定 义 一 个 Hadoop Job 编 写 另 一 个 Mapper 结 束 语 参 考 资 料 关 于 作 者 建 议 Apache 的 Hadoop 框 架 本 质 上 是 一 个 用 于 分 析 大 数 据 集 的 机 制, 不 一 定 位 于 数 据 存 储 中 Hadoop 提 取 出 了 MapReduce 的 大 规 模 数 据 分 析 引 擎, 更 易 于 开 发 人 员 理 解 Hadoop 可 以 扩 展 到 无 数 个 节 点, 可 以 处 理 所 有 活 动 和 相 关 数 据 存 储 的 协 调 Hadoop 的 众 多 特 性 和 配 置 使 其 成 为 一 个 十 分 有 用 且 功 能 强 大 的 框 架, 其 用 途 和 功 能 令 人 惊 讶 Yahoo! 以 及 其 他 许 多 组 织 已 经 找 到 了 一 个 高 效 机 制 来 分 析 成 堆 的 字 节 数 在 单 个 节 点 上 运 行 Hadoop 也 很 容 易 ; 您 所 需 要 的 只 是 一 些 需 要 分 析 的 数 据, 以 及 熟 悉 一 般 的 Java 代 码 Hadoop 也 可 和 Ruby Python 以 及 C++ 一 起 使 用 作 为 处 理 大 数 据 集 的 概 念 框 架,MapReduce 对 于 使 用 许 多 计 算 机 来 解 决 分 布 式 问 题 而 言 是 高 度 优 化 的 顾 名 思 义, 这 个 框 架 由 两 个 函 数 构 成 map 函 数 专 用 于 获 取 大 数 据 输 入, 并 将 其 分 成 小 片 段, 然 后 交 由 其 他 进 程 进 行 操 作 reduce 函 数 整 理 map 收 集 的 各 个 回 应, 然 后 显 示 最 后 的 输 出 在 Hadoop 中, 您 可 以 通 过 扩 展 Hadoop 自 身 的 基 类 来 定 义 map 和 reduce 实 现 实 现 和 输 入 输 出 格 式 被 一 个 指 定 它 们 的 配 置 联 系 在 一 起 Hadoop 非 常 适 合 处 理 包 含 结 构 数 据 的 大 型 文 件 Hadoop 可 以 对 输 入 文 件 进 行 原 始 解 析, 这 一 点 特 别 有 用, 这 样 您 就 可 以 每 次 处 理 一 行 定 义 一 个 map 函 数 实 际 上 只 是 一 个 关 于 确 定 您 从 即 将 输 入 的 文 本 行 中 捕 获 什 么 内 容 的 问 题 数 据, 无 处 不 在 的 数 据! 了 解 更 多 MapReduce 如 果 您 是 本 系 列 的 读 者, 您 可 能 已 经 见 过 MapReduce 一 两 次 了 在 通 过 CouchDB 和 Groovy 的 RESTClient 实 现 REST 中, 我 介 绍 了 CouchDB 如 何 利 用 MapReduce 进 行 查 看, 接 着 在 MongoDB: 拥 有 RDBMS 特 性 的 NoSQL 数 据 存 储 中 我 再 次 提 到 MapReduce, 处 理 MongoDB 文 档 的 机 制 美 国 政 府 产 生 大 量 数 据, 只 有 一 部 分 是 普 通 民 众 所 感 兴 趣 的 各 种 政 府 机 构 免 费 发 布 关 于 US 经 济 健 康 状 况 和 更 改 社 会 人 口 统 计 资 料 的 数 据 U.S. Geological Survey (USGS) 发 布 国 内 外 地 震 数 据 世 界 各 地 每 天 都 有 很 多 个 小 型 地 震 发 生 其 中 大 多 数 发 生 在 地 壳 深 处, 没 有 人 能 感 觉 到, 尽 管 如 此, 但 是 监 听 站 仍 然 会 进 行 记 录 USGS 以 CSV( 或 逗 号 分 隔 值 ) 文 件 的 格 式 发 布 每 周 地 震 数 据 每 周 文 件 平 均 不 是 很 大 只 有 大 约 100 KB 左 右 但 是, 它 可 以 作 为 学 习 Hadoop 的 基 础 记 住,Hadoop 有 能 力 处 理 更 大 的 数 据 集 跟 踪 震 动 我 近 期 从 USGS 网 站 下 载 的 CSV 文 件 有 大 约 920 多 行 如 清 单 1 所 示 : 清 单 1. 清 单 1. 一 个 USGS 地 震 数 据 文 件 的 行 数 统 计 $> wc -l eqs7day-m1.txt 920 eqs7day-m1.txt CVS 文 件 内 容 如 清 单 2 所 示 ( 这 是 前 两 行 ): 清 单 2. 清 单 2. CVS 文 件 的 前 两 行 $> head -n 2 eqs7day-m1.txt Src,Eqid,Version,Datetime,Lat,Lon,Magnitude,Depth,NST,Region ci,14896484,2,"sunday, December 12, 2010 23:23:20 UTC",33.3040,-116.4130,1.0,11.70,22, "Southern California" 这 就 是 我 称 之 为 信 息 丰 富 的 文 件, 尤 其 是 当 您 想 到 它 总 共 有 920 行 记 录 时 然 而 我 只 想 知 道 在 该 文 件 报 告 的 这 一 周 内 每 一 天 有 多 少 次 地 震 发 生 我 想 知 道 在 这 7 天 内 哪 个 区 域 是 地 震 频 发 区 我 第 一 个 想 到 的 就 是 使 用 简 单 的 grep 命 令 来 搜 索 每 天 的 地 震 数 看 看 这 个 文 件, 我 发 现 数 据 记 录 是 从 12 月 12 开 始 的 因 此 我 对 该 字 符 串 执 行 了 一 次 grep -c, 其 结 果 如 清 单 3 所 示 :
清 单 3. 清 单 3. 12 月 12 有 多 少 次 地 震 发 生? $> grep -c 'December 12' eqs7day-m1.txt 98 现 在, 我 知 道 在 12 月 12 日 有 98 条 记 录, 也 就 是 说 有 98 次 地 震 我 只 能 沿 着 这 条 记 录 向 下, 对 12 月 10 日 的 记 录 执 行 一 次 grep, 接 着 是 11 号, 等 等 这 听 起 来 有 点 乏 味 更 糟 糕 的 是, 我 还 需 要 知 道 在 该 文 件 中 的 是 哪 几 天 我 确 实 不 关 心 这 些, 甚 至 有 时 候 我 可 能 无 法 获 取 该 信 息 事 实 上, 我 只 想 知 道 在 七 天 这 样 一 个 时 间 段 内 任 何 一 天 的 地 震 次 数, 使 用 Hadoop 我 就 可 以 很 容 易 的 获 取 这 一 信 息 Hadoop 只 需 要 几 条 信 息 就 可 以 回 答 我 的 第 一 个 和 第 二 个 问 题 : 即, 要 处 理 哪 条 输 入 以 及 如 何 处 理 map 和 reduce 我 也 必 须 提 供 了 一 个 可 以 将 每 件 事 都 联 系 起 来 的 作 业 在 我 开 始 处 理 这 些 代 码 之 前, 我 需 要 花 点 时 间 确 定 我 的 CSV 数 据 整 齐 有 序 安 装 Hadoop 如 果 您 之 前 没 有 安 装 Hadoop, 那 么 现 在 就 装 第 一 步, 下 载 最 新 版 二 进 制 文 件, 解 压, 然 后 在 您 的 路 径 上 设 置 Hadoop 的 bin 目 录 完 成 这 些 您 就 可 以 直 接 执 行 hadoop 命 令 了 使 用 Hadoop 要 求 您 执 行 它 的 hadoop 命 令, 而 不 是 像 您 所 见 到 的 那 样 调 用 java 命 令 您 可 以 向 hadoop 命 令 传 选 项, 诸 如 在 哪 里 可 以 找 到 您 的 Java 二 进 制 文 件 ( 例 如, 表 示 您 的 map 和 reduce 实 现 ) 在 我 的 示 例 中, 我 创 建 了 一 个 jar 文 件, 告 诉 Hadoop 我 想 在 我 的 jar 文 件 内 运 行 哪 个 任 务 我 也 向 Hadoop 类 路 径 添 加 了 一 些 运 行 我 的 应 用 程 序 所 需 的 附 加 二 进 制 文 件 使 用 opencsv 进 行 数 据 解 析 除 了 地 震 CSV 文 件 的 第 一 行 之 外, 第 一 行 是 文 件 头, 每 一 行 都 是 一 系 列 逗 号 分 隔 数 据 值 我 只 对 数 据 的 3 个 部 分 感 兴 趣 : 日 期 地 点 和 震 级 为 了 获 取 这 些 资 料, 我 将 使 用 一 个 很 棒 的 开 源 库 opencsv, 它 将 会 帮 助 我 分 析 CSV 文 件 作 为 一 个 测 试 优 先 的 工 具, 我 首 先 编 写 一 个 快 捷 JUnit 测 试, 确 认 我 可 以 从 CSV 文 件 的 一 个 样 例 行 获 取 的 我 所 需 要 的 信 息, 如 清 单 4 所 示 : 清 单 4. 清 单 4. 解 析 一 个 CSV 行 public class CSVProcessingTest { private final String LINE = "ci,14897012,2,\"monday, December 13, 2010 " + "14:10:32 UTC\",33.0290,-115." + "5388,1.9,15.70,41,\"Southern California\""; @Test public void testreadingoneline() throws Exception { String[] lines = new CSVParser().parseLine(LINE); assertequals("should be Monday, December 13, 2010 14:10:32 UTC", "Monday, December 13, 2010 14:10:32 UTC", lines[3]); assertequals("should be Southern California", "Southern California", lines[9]); assertequals("should be 1.9", "1.9", lines[6]); 正 如 您 在 清 单 4 中 所 看 到 的,opencsv 处 理 逗 号 分 隔 值 非 常 容 易 该 解 析 器 仅 返 回 一 组 String, 所 以 有 可 能 获 取 位 置 信 息 ( 别 忘 了, 在 Java 语 言 中 数 组 和 集 合 的 访 问 是 从 零 开 始 的 ) 转 换 日 期 格 式 当 使 用 MapReduce 进 行 处 理 时,map 函 数 的 任 务 是 选 择 一 些 要 处 理 的 值, 以 及 一 些 键 这 就 是 说,map 主 要 处 理 和 返 回 两 个 元 素 : 一 个 键 和 一 个 值 回 到 我 之 前 的 需 求, 我 首 先 想 知 道 每 天 会 发 生 多 少 次 地 震 因 此, 当 我 在 分 析 地 震 文 件 时, 我 将 发 布 两 个 值 : 键 是 日 期, 值 是 一 个 计 数 器 reduce 函 数 将 对 计 数 器 ( 只 是 一 些 值 为 1 的 整 数 ) 进 行 总 计 因 此, 提 供 给 我 的 是 在 目 标 地 震 文 件 中 某 一 个 日 期 出 现 的 次 数 由 于 我 只 对 24 小 时 时 段 内 的 信 息 感 兴 趣, 我 得 剔 除 每 个 文 件 中 的 日 期 的 时 间 部 分 在 清 单 5 中, 我 编 写 了 一 个 快 速 测 试, 验 证 如 何 将 一 个 传 入 文 件 中 的 特 定 日 期 信 息 转 换 成 一 个 更 一 般 的 24 小 时 日 期 : 清 单 5. 清 单 5. 日 期 格 式 转 换 @Test public void testparsingdate() throws Exception { String datest = "Monday, December 13, 2010 14:10:32 UTC"; SimpleDateFormat formatter = new SimpleDateFormat("EEEEE, MMMMM dd, yyyy HH:mm:ss Z"); Date dt = formatter.parse(datest); formatter.applypattern("dd-mm-yyyy"); String dtstr = formatter.format(dt); assertequals("should be 13-12-2010", "13-12-2010", dtstr); 在 清 单 5 中, 我 使 用 了 SimpleDateFormat Java 对 象, 将 CSV 文 件 中 格 式 为 Monday, December 13, 2010 14:10:32 UTC 的 日 期 String 转 换 成 了 更 一 般 的 13-12-2010 Hadoop 的 map 和 reduce 现 在 我 已 经 找 到 了 处 理 CSV 文 件 以 及 其 日 期 格 式 的 解 决 方 法 我 要 开 始 在 Hadoop 中 实 施 我 的 map 和 reduce 函 数 了 这 个 过 程 需 要 理 解 Java 泛 型, 因 为 Hadoop 选 择 使 用 显 式 类 型, 为 了 安 全 起 见 当 我 使 用 Hadoop 定 义 一 个 映 射 实 现 时, 我 只 扩 展 Hadoop 的 Mapper 类 然 后 我 可 以 使 用 泛 型 来 为 传 出 键 和 值 指 定 显 式 类 类 型 子 句 也 指 定 了 传 入 键 和 值, 这 对 于 读 取 文 件 分 别 是 字 节 数 和 文 本 行 数 EarthQuakesPerDateMapper 类 扩 展 了 Hadoop 的 Mapper 对 象 它 显 式 地 将 其 输 出 键 指 定 为 一 个 Text 对 象, 将 其 值 指 定 为 一 个 IntWritable, 这 是 一 个 Hadoop 特 定 类, 实 质 上 是 一 个 整 数 还 要 注 意,class 子 句 的 前 两 个 类 型 是 LongWritable 和 Text, 分 别 是 字 节 数 和 文 本 行 数
由 于 类 定 义 中 的 类 型 子 句, 我 将 传 入 map 方 法 的 参 数 类 型 设 置 为 在 context.write 子 句 内 带 有 该 方 法 的 输 出 如 果 我 想 指 定 其 他 内 容, 将 会 出 现 一 个 编 译 器 问 题, 或 Hadoop 将 输 出 一 个 错 误 消 息, 描 述 类 型 不 匹 配 的 消 息 清 单 6. 清 单 6. 一 个 映 射 实 现 public class EarthQuakesPerDateMapper extends Mapper<LongWritable, Text, Text, IntWritable> { @Override protected void map(longwritable key, Text value, Context context) throws IOException, InterruptedException { if (key.get() > 0) { try { CSVParser parser = new CSVParser(); String[] lines = parser.parseline(value.tostring()); SimpleDateFormat formatter = new SimpleDateFormat("EEEEE, MMMMM dd, yyyy HH:mm:ss Z"); Date dt = formatter.parse(lines[3]); formatter.applypattern("dd-mm-yyyy"); String dtstr = formatter.format(dt); context.write(new Text(dtstr), new IntWritable(1)); catch (ParseException e) { 清 单 6 中 的 map 实 现 比 较 简 单 : 本 质 上 是,Hadoop 为 在 输 入 文 件 中 找 到 的 每 一 行 文 本 调 用 这 个 类 为 了 避 免 除 了 CSV 头 部, 首 先 检 查 是 否 字 节 数 (key 对 象 ) 为 零 然 后 执 行 清 单 4 和 5 中 的 步 骤 : 捕 获 传 入 日 期, 进 行 转 换, 然 后 设 置 为 传 出 键 我 也 提 供 了 一 个 数 :1 就 是 说, 我 为 每 个 日 期 编 写 一 个 计 数 器, 当 reduce 实 现 被 调 用 时, 获 取 一 个 键 和 一 系 列 值 在 本 例 中, 键 是 日 期 及 其 值, 如 清 单 7 所 示 : 清 单 7. 清 单 7. 一 个 map 输 出 和 reduce 输 入 的 逻 辑 视 图 "13-12-2010":[1,1,1,1,1,1,1,1] "14-12-2010":[1,1,1,1,1,1] "15-12-2010":[1,1,1,1,1,1,1,1,1] 注 意,context.write(new Text(dtstr), new IntWritable(1))( 在 清 单 6 中 ) 构 建 了 如 清 单 7 所 示 的 逻 辑 集 合 正 如 您 所 了 解 的,context 是 一 个 保 存 各 种 信 息 的 Hadoop 数 据 结 构 context 被 传 递 到 reduce 实 现,reduce 获 取 这 些 值 为 1 的 值 然 后 总 和 起 来 因 此, 一 个 reduce 实 现 逻 辑 上 创 建 如 清 单 8 所 示 的 数 据 结 构 : 清 单 8. 清 单 8. 一 个 reduce 输 出 视 图 "13-12-2010":8 "14-12-2010":6 "15-12-2010":9 我 的 reduce 实 现 如 清 单 9 所 示 与 Hadoop 的 Mapper 一 样,Reducer 被 参 数 化 了 : 前 两 个 参 数 是 传 入 的 键 类 型 (Text) 和 值 类 型 (IntWritable), 后 两 个 参 数 是 输 出 类 型 : 键 和 值, 这 在 本 例 中 是 相 同 的 清 单 9. 清 单 9. reduce 实 现 public class EarthQuakesPerDateReducer extends Reducer<Text, IntWritable, Text, IntWritable> { @Override protected void reduce(text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int count = 0; for (IntWritable value : values) { count++; context.write(key, new IntWritable(count)); 我 的 reduce 实 现 非 常 简 单 正 如 我 在 清 单 7 中 所 指 出 的, 传 入 的 是 实 际 上 是 一 个 值 的 集 合, 在 本 例 中 是 1 的 集 合, 我 所 做 的 就 是 将 它 们 加 起 来, 然 后 写 出 一 个 新 键 值 对 表 示 日 期 和 次 数 我 的 reduce 代 码 可 以 挑 出 您 在 清 单 8 中 所 见 到 的 这 几 行 逻 辑 流 程 看 起 来 像 这 样 : "13-12-2010":[1,1,1,1,1,1,1,1] -> "13-12-2010":8 当 然, 这 个 清 单 的 抽 象 形 式 是 map -> reduce 定 义 一 个 Hadoop Job 现 在 我 已 经 对 我 的 map 和 reduce 实 现 进 行 了 编 码, 接 下 来 所 要 做 的 是 将 所 有 这 一 切 链 接 到 一 个 Hadoop Job 定 义 一 个 Job 比 较 简 单 : 您 需 要 提 供 输 入 和 输 出 map 和 reduce 实 现 ( 如 清 单 6 和 清 单 9 所 示 ) 以 及 输 出 类 型 在 本 例 中 我 的 输 出 类 型 和 reduce 实 现 所 用 的 是 同 一 个 类 型 清 单 10. 清 单 10. 一 个 将 map 和 redece 绑 在 一 起 的 Job public class EarthQuakesPerDayJob { public static void main(string[] args) throws Throwable { Job job = new Job(); job.setjarbyclass(earthquakesperdayjob.class); FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1]));
job.setmapperclass(earthquakesperdatemapper.class); job.setreducerclass(earthquakesperdatereducer.class); job.setoutputkeyclass(text.class); job.setoutputvalueclass(intwritable.class); System.exit(job.waitForCompletion(true)? 0 : 1); 在 清 单 10 中, 我 使 用 一 个 main 方 法 将 所 有 这 一 切 绑 在 一 起, 该 方 法 有 两 个 参 数 : 地 震 CSV 文 件 的 目 录, 以 及 生 成 报 告 的 输 出 目 录 (Hadoop 更 喜 欢 创 建 该 目 录 ) 为 了 执 行 这 个 小 框 架, 我 需 要 将 这 些 类 打 包 我 还 需 要 告 知 Hadoop 在 哪 里 可 以 找 到 opencsv 二 进 制 文 件 然 后 可 以 通 过 命 令 行 执 行 Hadoop, 如 清 单 11 所 示 : 清 单 11. 清 单 11. 执 行 Hadoop $> export HADOOP_CLASSPATH=lib/opencsv-2.2.jar $> hadoop jar target/quake.jar com.b50.hadoop.quake.earthquakesperdayjob ~/temp/mreduce/in/ ~/temp/mreduce/out 运 行 这 些 代 码,Hadoop 开 始 运 行 时 您 将 可 以 看 到 一 堆 文 本 在 屏 幕 上 一 闪 而 过 我 所 用 的 CSV 文 件 相 比 专 门 用 于 处 理 这 种 情 况 的 Hadoop, 那 真 是 小 巫 见 大 巫!hadoop 应 该 可 以 在 几 秒 钟 内 完 成, 具 体 取 决 于 您 的 处 理 功 能 完 成 这 些 后, 您 可 以 使 用 任 何 编 辑 器 查 看 输 出 文 件 内 容 还 可 以 选 择 直 接 使 用 hadoop 命 令 正 如 清 单 12 所 示 : 清 单 12. 清 单 12. 读 取 Hadoop 输 出 $> hadoop dfs -cat part-r-00000 05-12-2010 43 06-12-2010 143 07-12-2010 112 08-12-2010 136 09-12-2010 178 10-12-2010 114 11-12-2010 114 12-12-2010 79 如 果 您 像 我 一 样, 在 清 单 12 中 首 先 会 注 意 到 的 就 是 每 天 地 震 数 12 月 9 日 就 有 178 次 地 震 希 望 您 也 会 注 意 到 Hadoop 实 现 了 我 所 想 要 的 : 整 齐 地 列 出 我 的 研 究 范 围 内 每 天 的 地 震 次 数 编 写 另 一 个 Mapper 接 下 来, 我 想 找 到 地 震 发 生 在 哪 里, 以 及 如 何 快 速 计 算 出 在 我 的 研 究 范 围 内 记 录 地 震 次 数 最 多 的 是 哪 个 区 域 当 然, 您 已 经 猜 到 了, Hadoop 可 以 轻 松 地 做 到 在 这 个 案 例 中, 键 不 再 是 日 期 而 是 区 域 因 此, 我 编 写 了 一 个 新 的 Mapper 类 清 单 13. 清 单 13. 一 个 新 的 map 实 现 public class EarthQuakeLocationMapper extends Mapper<LongWritable, Text, Text, IntWritable> { @Override protected void map(longwritable key, Text value, Context context) throws IOException, InterruptedException { if (key.get() > 0) { String[] lines = new CSVParser().parseLine(value.toString()); context.write(new Text(lines[9]), new IntWritable(1)); 和 之 前 获 取 日 期 然 后 进 行 转 换 相 比, 在 清 单 13 中 我 所 作 的 是 获 取 位 置, 这 是 CSV 阵 列 中 的 最 后 一 个 条 目 相 比 一 个 庞 大 的 位 置 和 数 字 列 表, 我 将 结 果 限 制 在 那 些 7 天 内 出 现 10 次 的 区 域 清 单 14. 清 单 14. 哪 里 的 地 震 较 多? public class EarthQuakeLocationReducer extends Reducer<Text, IntWritable, Text, IntWritable> { @Override protected void reduce(text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int count = 0; for (IntWritable value : values) { count++; if (count >= 10) { context.write(key, new IntWritable(count)); 清 单 14 中 的 代 码 和 清 单 9 中 的 代 码 非 常 类 似 ; 然 而, 在 本 例 中, 我 限 制 了 输 出 大 于 或 等 于 10 接 下 来, 我 将 map 和 reduce, 以 及 其 他 Job 实 现 绑 在 一 起, 进 行 打 包, 然 后 和 平 常 一 样 执 行 Hadoop 获 取 我 的 新 答 案 使 用 hadoop dfs 目 录 显 示 我 所 请 求 的 新 值 : 清 单 15. 清 单 15. 地 震 区 域 分 布 $> hadoop dfs -cat part-r-00000 Andreanof Islands, Aleutian Islands, Alaska 24 Arkansas 40 Baja California, Mexico 101 Central Alaska 74 Central California 68 Greater Los Angeles area, California 16 Island of Hawaii, Hawaii 16 Kenai Peninsula, Alaska 11 Nevada 15 Northern California 114
San Francisco Bay area, California 21 Southern Alaska 97 Southern California 115 Utah 19 western Montana 11 从 清 单 15 还 可 以 得 到 什 么? 首 先, 北 美 洲 西 海 岸, 从 墨 西 哥 到 阿 拉 斯 加 是 地 震 高 发 区 其 次, 阿 肯 色 州 明 显 位 于 断 带 层 上, 这 是 我 没 有 意 识 到 的 最 后, 如 果 您 居 住 在 北 部 或 者 是 南 加 州 ( 很 多 软 件 开 发 人 员 都 居 住 于 此 ), 您 周 围 的 地 方 每 隔 13 分 钟 会 震 动 一 次 结 束 语 使 用 Hadoop 分 析 数 据 轻 松 且 高 效, 对 于 它 对 数 据 分 析 所 提 供 的 支 持, 我 只 是 了 解 皮 毛 而 已 Hadoop 的 设 计 旨 在 以 一 种 分 布 式 方 式 运 行, 处 理 运 行 map 和 reduce 的 各 个 节 点 之 间 的 协 调 性 作 为 示 例, 本 文 中 我 只 在 一 个 JVM 上 运 行 Hadoop, 该 JVM 仅 有 一 个 无 足 轻 重 的 文 件 Hadoop 本 身 是 一 个 功 能 强 大 的 工 具, 围 绕 它 还 有 一 个 完 整 的 不 断 扩 展 的 生 态 系 统, 可 以 提 供 子 项 目 至 基 于 云 计 算 的 Hadoop 服 务 Hadoop 生 态 系 统 演 示 了 项 目 背 后 丰 富 的 社 区 活 动 来 自 社 区 的 许 多 工 具 证 实 了 大 数 据 分 析 作 为 一 个 全 球 业 务 活 动 的 可 行 性 有 了 Hadoop, 分 布 式 数 据 挖 掘 和 分 析 对 所 有 软 件 创 新 者 和 企 业 家 都 是 可 用 的, 包 括 但 不 限 于 Google 和 Yahoo! 这 类 大 企 业 参 考 资 料 学 习 Java 开 发 2.0: 这 个 dw 系 列 讨 论 重 定 义 Java 开 发 格 局 的 技 术 ; 近 期 话 题 包 括 MongoDB( 2010 年 9 月 );CouchDB (2009 年 11 月 ) 和 Objectify AppEngine(2010 年 11 月 ) 用 Hadoop 进 行 分 布 式 数 据 处 理, 第 1 部 分 : 入 门 (M. Tim Jones,developerWorks,2010 年 5 月 ): 这 篇 文 章 系 列 的 第 一 篇 介 绍 了 Hadoop 框 架, 包 括 Hadoop 文 件 系 统 (HDFS) 和 常 用 的 节 点 类 型 介 绍 了 如 何 按 装 和 配 置 一 个 单 节 点 Hadoop 集 群 并 深 入 研 究 了 MapReduce 应 用 程 序 最 后, 发 现 了 使 用 其 核 心 Web 接 口 监 控 和 管 理 Hadoop 的 方 法 另 外 请 参 阅 第 2 部 分 和 第 3 部 分 在 云 中 使 用 MapReduce 和 负 载 平 衡 (Kirpal A. Venkatesh,et. al.,developerworks,2010 年 7 月 ): 了 解 Hadoop MapReduce 和 虚 拟 化 如 何 改 进 节 点 性 能 A profile of Apache Hadoop MapReduce computing efficiency, Part 1 (Paul Burkhardt,Cloudera Development Center,2010 年 12 月 ): 一 个 关 于 MapReduce 应 用 程 序 如 何 高 效 地 使 用 计 算 资 源 的 两 部 分 系 列 文 章, 第 一 部 分 是 对 计 算 效 率 的 一 个 概 述, 因 为 这 涉 及 到 评 估 Hadoop MapReduce 应 用 程 序 Hadoop companies everywhere (Alex Handy,SD Times,2009 年 7 月 ): 公 司 每 天 都 产 生 很 多 数 据, 但 是 很 多 都 不 能 从 其 中 获 取 业 务 智 能 这 创 造 了 机 会 浏 览 Java 技 术 书 店 阅 读 关 于 这 些 和 其 他 技 术 主 题 的 图 书 developerworks Java 技 术 专 区 : 这 里 有 数 百 篇 关 于 Java 编 程 各 个 方 面 的 文 章 获 得 产 品 和 技 术 下 载 Hadoop MapReduce: 一 个 Apache Software Foundation 项 目 Get opencsv: 从 SourceForge 下 载 它 讨 论 加 入 developerworks 中 文 社 区 查 看 开 发 人 员 推 动 的 博 客 论 坛 组 和 维 基, 并 与 其 他 developerworks 用 户 交 流 关 于 作 者 Andrew Glover 是 具 有 行 为 驱 动 开 发 持 续 集 成 和 敏 捷 软 件 开 发 激 情 的 开 发 人 员 作 家 演 说 家 和 企 业 家 他 是 easyb 行 为 驱 动 开 发 (Behavior-Driven Development,BDD) 框 架 的 创 建 者 和 三 本 书 的 合 著 者 : 持 续 集 成 Groovy 在 行 动 和 Java 测 试 模 式 您 可 以 通 过 他 的 博 客 与 他 保 持 一 致 并 在 Twitter(http://twitter.com/aglover) 上 关 注 他 建 议 打 印 此 页 面 分 享 此 页 面 关 注 developerworks 技 术 主 题 查 找 软 件 社 区 关 于 developerworks IBM AIX and UNIX Java technology IBM 产 品 群 组 反 馈 意 见 解 决 方 案 Information Management Lotus Rational WebSphere Cloud computing Linux Open source SOA and web services Web development XML 更 多... 评 估 方 式 ( 下 载, 在 线 试 用,Beta 版, 云 ) 行 业 技 术 讲 座 博 客 Wiki 文 件 使 用 条 款 与 条 件 报 告 滥 用 更 多... 在 线 投 稿 投 稿 指 南 网 站 导 航 请 求 转 载 内 容 相 关 资 源 ISV 资 源 ( 英 语 ) 软 件 支 持 门 户 产 品 文 档 红 皮 书 ( 英 语 ) 隐 私 条 约 浏 览 辅 助 IBM 教 育 学 院 教 育 培 养 计 划
选 择 语 言 : English 中 文 日 本 語 한국어 Русский Português (Brasil) Español Việt