内存中的 MapReduce 和 Hadoop 生态系统:第 1 章
本文的部分内容摘自《使用 Apache Ignite 进行内存高性能计算 》一书。如果对此感兴趣,请查阅此书的其余部分以获取更多有用的信息。
Hadoop 已经迅速成为建立在海量数据之上的商业智能的标准。然而,其按批调度的开销和基于磁盘的数据存储使其不适合用于分析生产环境中的实时数据。限制 Hadoop 和 MapReduce 性能扩展的主要因素之一是 Hadoop 依赖生成大量输入 / 输出(I/O)文件的文件系统。I/O 操作会增加延迟,并延迟 MapReduce 的计算。有种替代方法是将所需的分布式数据存储在内存中。将 MapReduce 与其所需的数据放在内存中就可以消除由文件 I/O 操作产生的延迟。
上图显示了 Hadoop 作业的一般流程。其中 sort,merge 和 shuffle 步骤都是 I/O 密集型的。运行以毫秒级别或秒级别的时间得出结果的实时分析时,这些步骤的开销会非常高。
通过引入多种技术,MapReduce 的内存引擎 Ignite 能在几秒钟(或更短时间)内执行 MapReduce 程序。在回避 Hadoop 的按批调度后,它可以在几毫秒内而不是在几十秒内启动作业。内存数据存储可通过消除对磁盘或网络上的数据的调动来显着地缩短访问时间。这就是在不更改代码的情况下提高 Hadoop 应用程序性能的 Ignite 方法。其主要优点是所有的操作都是高度透明的,都是能在不改变 MapReduce 代码行的情况下完成的。
Hadoop 的这一即插即用的内存加速器有三种类型。
1. 内存中的 MapReduce
它是 Hadoop 的作业和任务跟踪器的一个替代方案,可以加快作业执行的性能。它消除了标准 Hadoop 体系结构中与作业和任务跟踪器相关的开销,同时能提供低延迟的 HPC 式分布式处理功能。
2. Ignite 内存文件系统(IGFS)
它也是一个 Hadoop 文件系统的替代方案,在内部名为 IgniteHadoopFileSystem。它可以将数据集存储在内存中。这种基于内存的文件系统最大限度地减少了磁盘 I/O 开销,提高了性能。
3. Hadoop 文件系统缓存
这一方案会作为 HDFS 在之上的缓存层工作。每个读写操作都应该经过这一层,并且可以提高 MapReduce 的性能。
Ignite Hadoop 加速器的概念架构如下图所示:
当你已经启动并运行了一个现有的 Hadoop 集群并希望以最少的工作获得更高的性能时,Apache Ignite Hadoop 加速器工具会特别有用。请注意,Hadoop 在商品硬件上运行的想法就是一个谎言。大多数 Hadoop 的流程都是 I/O 密集型的,需要多部同环境的服务器还有中介服务器配合工作才能实现良好的性能。
在这篇文章中,我们将探讨内存中的 Apache Ignite MapReduce 的一些细节。
内存中的 Ignite MapReduce 引擎与 Hadoop HDFS 还有 Yarn 完全兼容。它减少了 Hadoop 作业和任务跟踪器的启动和执行的时间,还为 CPU 密集型任务提供了显着的性能提升,同时只需对现有应用程序进行最小限度的更改。该模块还提供了基于权重的 MapReduce 调度器的实现,该调度器会根据权重分配 mapper 和 reducer 这两种任务,其中这一权重描述了执行特定任务需要资源的多少。然后会有调度算法通过合理分配 mapper 任务,使得所有节点上的总体结果权重尽可能最小。
内存中的 Ignite MapReduce 的高级架构如下所示:
内存中的 Ignite 单元在所有单元节点上都有一个基于 Java 的前级执行环境,并会将其重复用于多个数据处理流程里面。此执行环境由一组 Java 虚拟机构成,而集群中的每台服务器都会有一个这样的虚拟机。如上图所示,JVM 会形成 Ignite MapReduce 引擎。另外,内存中的 Ignite 数据单元可以自动部署所有必需的可执行程序或类库,以便在整个内存单元中执行 MapReduce,从而大大缩短了启动时间,甚至能缩短到毫秒级别。
现在我们已经了解了基础知识。不妨尝试配置一个开发环境并在 Ignite MapReduce 引擎中执行一些 MapReduce 作业。
为了简单起见,我们将在单个虚拟机中安装一个 Hadoop 伪分布式集群,并且拿有名的 Hadoop 字数统计例程作为一个 MapReduce 作业来运行。Hadoop "伪分布式集群" 意味着 Hadoop 的数据节点,名称节点,任务和作业跟踪器 —— 一切都只会运行在一台虚拟(主机)机器上。
让我们来看看我们的开发环境配置,如下所示:
- 操作系统:RedHat Linux 企业版;
- CPU:双核
- RAM:2 GB。
- JVM:1.7_60。
- Ignite 版本:1.6 或以上,单节点集群。
首先,我们要安装和配置 Hadoop,还有 Apache Ignite。在此我们假设 Java 已经装好并且位于环境变量 JAVA_HOME
里面。
1. 解压 Hadoop 发行版
解压 Hadoop 发行包,然后在 /etc
里面设置 JAVA_HOME
路径:
export JAVA_HOME=JAVA_HOME_PATH
2.添加配置
往文件 etc/hadoop/core-site.xml
添加以下内容:
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value>
</property>
</configuration>
另外还要将以下数据复制策略加到这个文件中:etc/hadoop/hdfs-site.xml
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
</configuration>
3.设置无密码的 SSH
给操作系统设置无密码的 SSH 的命令如下:
$ ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa
$ cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
$ chmod 0600 ~/.ssh/authorized_keys
然后在控制台上运行以下命令来测试设置效果:
$ ssh localhost
如果设置成功,这一命令的运行就不会要求你输入密码。
4. 设置 Hadoop HDFS 文件系统
首先格式化 Hadoop HDFS 文件系统:
$ bin/hdfs namenode -format
接着通过以下命令启动 namenode / datanode 守护进程:
$ sbin/start-dfs.sh
另外,建议将环境变量 HADOOP_HOME
添加到操作系统。
5. 设置目录
在 HDFS 文件系统中创建几个目录来运行 MapReduce 作业。
bin/hdfs dfs -mkdir /user
bin/hdfs dfs -mkdir /input
以上命令将创建两个文件夹用户并输入到 HDFS文件系统里面。
然后在 input 目录中插入一些文本文件:
bin/hdfs dfs -put $HADOOP_HOME/etc/hadoop /input
6. 配置Hadoop伪集群
运行本地 Hadoop MapReduce 应用程序来计算文件的字数。
$ bin/hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.2.jar w
ordcount /input/hadoop output
可以使用以下命令查看单词统计的结果:
bin/hdfs dfs -cat output/*
就笔者的情况来说,输入的文件还蛮大的。我们来看看输出文件的一部分:
want 1 warnings. 1 when 9 where 4 which 7 while 1 who 6
will 23
window 1
window, 1
with 62
within 4
without 1
work 12
writing, 27
在这个阶段,我们的 Hadoop 伪集群已经配置好并已经可以使用了。现在我们开始配置 Apache Ignite。
7. 解压 Apache Ignite 发行包
将 Apache Ignite 的发行包解压到开发环境中的某个位置,并将路径 IGNITE_- HOME
添加到安装的根目录中。为了获得有关任务和执行的统计信息,还必须在文件 /config/default-config.xml
中添加以下属性:
<bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
....
<property name="includeEventTypes">
<list>
<util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_FAILED"/>
<util:constant static-field="org.apache.ignite.events.EventType.EVT_TASK_FINISHED"/>
<util:constant static-field="org.apache.ignite.events.EventType.EVT_JOB_MAPPED"/>
</list>
</property>
</bean>
以上配置将会启用进行统计的针对事件的任务。
注意在默认情况下,所有的事件都会处于禁用状态而不会触发。只有在启用了上述事件之后,才可以在 Ignite Visor 中使用命令 “tasks” 来获取有关任务执行的统计信息。
8.添加库
在目录 $IGNITE_HOME/libs
中添加这些类库:
asm-all-4.2.jar
ignite-hadoop-1.6.0.jar
hadoop-mapreduce-client-core-2.7.2.jar
hadoop-common-2.7.2.jar
hadoop-auth-2.7.2.jar
注意 asm-all-4.2.jar
这个类库的具体版本是取决于你所安装的 Hadoop 版本的。
9. 启动 Ignite 节点
我们将使用 Apache Ignite 默认配置文件 config/default-config.xml
来启动 Ignite 节点。
然后使用以下命令启动 Ignite 节点:
bin/ignite.sh
10. 设置 Ignite Job Tracker
再添加一些内容来使用 Ignite 作业跟踪器而不是 Hadoop。我们需要把这些东西添加到环境变量 HADOOP_CLASSPATH
里面:
export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:$IGNITE_HOME/libs/ignite-core-1.6.0.jar:$IGNITE_
HOME/libs/ignite-hadoop-1.6.0.jar:$IGNITE_HOME/libs/ignite-shmem-1.0.0.jar
11. 重写
在这个阶段,我们将会重写 Hadoop 文件。为了方便上手,不妨直接将以下 XML 片段添加到 mapred-site.xmlmapred-site.xml
:
<property>
<name>mapreduce.framework.name</name>
<value>ignite</value>
</property>
<property>
<name>mapreduce.jobtracker.address</name>
<value>127.0.0.1:11211</value>
</property>
12. 跑起来
再次运行上面的 MapReduce 单词统计例程:
$bin/hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.2.jar wo
rdcount /input/hadoop output2
程序的输出应该是十分相似的,如下图所示:
现在运行时间比使用 Hadoop 任务跟踪器的时候应该更快。让我们通过 Ignite Visor 来检查 Ignite 任务执行的统计信息。
对上图,我们应该注意到内存任务跟踪器的总执行次数和持续时间。在我们的例子中,
HadoopProtocolJobStatusTask(@t1)
任务执行总次数是24,执行时间是 12 秒。
在下一章节中,我们还将执行一些性能基准测试来演示 Ignite MapReduce 引擎的性能优势。
- JavaScript 基础(七) 箭头函数 generator Date JSON
- 初体验 Ghost : yet another WordPress?
- 浅谈MySQL的事务隔离级别
- 国内环境下前端网页开发的几个“中国特色”代码
- 从源码的角度再看 React JS 中的 setState
- Sass 与Compass 在WordPress 主题开发中的运用
- Python爬虫Scrapy入门看这篇就够了
- Clef:为你的WordPress 站点添加两步验证
- JavaScript 基础(六) 数组方法 闭包
- 【译】WordPress 中的50个过滤器(4):第21-30个过滤器
- 【译】WordPress 中的50个过滤器(3):第11-20个过滤器
- 【译】WordPress 中的50个过滤器(2):先介绍10个过滤器
- 【译】WordPress 中的50个过滤器(1):何为过滤器?
- 哪种芯片架构将成为人工智能时代的开路先锋
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 浅谈布隆过滤器
- Python 技术篇-获取图片GPS信息,锁定追踪图片拍摄地点、拍摄时间
- 测试工具 - Postman接口测试入门使用手册,Postman如何进行数据关联、自动更新cookies、简单编程
- 白盒测试工具 - sonar的安装、配置与使用入门手册,用sonar检查代码质量实战演示
- Chmod -R 777 / 误操作恢复教程
- 最全总结 | 聊聊 Python 数据处理全家桶(Redis篇)
- 虚拟机安装mikrotik-ROS
- 搬砖武士|手把手教你在容器服务 TKE 上使用 LB直通 Pod
- linux安装snmp服务-ubuntu
- 企业微信机器人
- Kubernetes 新玩法:在 YAML 中编程
- 全网最实用 Python 面试题大全(花费了整整 3 天时间整理出来的)
- paramiko模块
- Loki 和 Fluentd 的那点事儿
- Hive改表结构的两个坑|避坑指南