开始学习Hadoop,首先搭建了一下开发环境,最开始是在单独编写Map-Reduce程序,然后在命令行编译,再通过hadoop命令运行打好的jar包,虽然也能够运行,但是总感觉这样用起来很麻烦,所以今晚又尝试了直接通过eclipse来编辑和运行Map-Reduce程序,瞎弄了一下,居然让我弄成功了,自然走了点弯路,担心以后再走弯路,所以把自己的搭建过程记录于此。
1.准备
1.1 软件
RedHat 6
Hadoop-0.20.2
java 1.6
1.2 java环境
修改环境变量,我这里是修改的用户目录下的.bash_profile文件,在该文件中添加如下内容:
Hadoop_HOME=/root/hadoop/hadoop-0.20.2 CLASSPATH=$CLASSPATH:$Hadoop_HOME/hadoop-0.20.2-core.jar PATH=$PATH:$Hadoop_HOME/bin export Hadoop_HOME export CLASSPATH export PATH |
然后执行如下命令使修改对当前环境有效:
% source /root/.bash_profile
我这里的修改仅仅对当前用户有效,如果想对所有用户都有效,则要修改/etc/profile文件。另外,修改环境变量也可以直接在终端直接执行上述命令,不过这样修改只对当前shell环境有效。
2.Hadoop安装
可以从http://Hadoop.apache.org/common/releases.html#Download下载hadoop-0.20.2,再解压到系统本地文件系统,我是解压到/root/hadoop/目录:
% tar xzf Hadoop-0.20.2.tar.gz
创建一个指向Hadoop安装目录的环境变量(HADOOP_HOME),再把hadoop的安装路径放到命令行路径上(我还是修改的/root/.bash_profile文件):
Hadoop_HOME=/root/hadoop/hadoop-0.20.2 CLASSPATH=$CLASSPATH:$Hadoop_HOME/hadoop-0.20.2-core.jar PATH=$PATH:$Hadoop_HOME/bin export Hadoop_HOME export CLASSPATH export PATH |
至此,Hadoop基本环境搭建完成,如想在独立模式(local mode)下运行,此环境已足够。可以通过在终端下输入如下命令来验证:
% Hadoop version
会输出如下内容:
Hadoop 0.20.2 Subversion https://svn.apache.org/repos/asf/Hadoop/common/branches/branch-0.20 -r 911707 Compiled by chrisdo on Fri Feb 19 08:07:34 UTC 2010 |
3.命令行环境运行
以下的例子是来自《Hadoop权威指南》。
在/root/Hadoop目录下创建java文件NewMaxTemperature.java:
// cc NewMaxTemperature Application to find the maximum temperature in
the weather dataset using the new context objects MapReduce API package ch2; import java.io.IOException; import org.apache.Hadoop.fs.Path; import org.apache.Hadoop.io.*; import org.apache.Hadoop.mapreduce.*; import org.apache.Hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.Hadoop.mapreduce.lib.output.FileOutputFormat; // vv NewMaxTemperature public class NewMaxTemperature { static class NewMaxTemperatureMapper /*[*/extends Mapper<LongWritable, Text, Text, IntWritable>/*]*/ { private static final int MISSING = 9999; public void map(LongWritable key, Text value, /*[*/Context context/*]*/) throws IOException, /*[*/InterruptedException/*]*/ { String line = value.toString(); String year = line.substring(15, 19); int airTemperature; if (line.charAt(87) == '+') { // parseInt doesn't like leading plus signs airTemperature = Integer.parseInt(line.substring(88, 92)); } else { airTemperature = Integer.parseInt(line.substring(87, 92)); } String quality = line.substring(92, 93); if (airTemperature != MISSING && quality.matches("[01459]")) { /*[*/context.write/*]*/(new Text(year), new IntWritable(airTemperature)); } } } static class NewMaxTemperatureReducer /*[*/extends Reducer<Text, IntWritable, Text, IntWritable>/*]*/ { public void reduce(Text key, /*[*/Iterable/*]*/<IntWritable> values, /*[*/Context context/*]*/) throws IOException, /*[*/InterruptedException/*]*/ { int maxValue = Integer.MIN_VALUE; for (IntWritable value : values) { maxValue = Math.max(maxValue, value.get()); } /*[*/context.write/*]*/(key, new IntWritable(maxValue)); } } public static void main(String[] args) throws Exception { if (args.length != 2) { System.err.println("Usage: NewMaxTemperature <input path> <output path>"); System.exit(-1); } /*[*/Job job = new Job(); job.setJarByClass(NewMaxTemperature.class);/*]*/ FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); job.setMapperClass(NewMaxTemperatureMapper.class); job.setReducerClass(NewMaxTemperatureReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); /*[*/System.exit(job.waitForCompletion(true) ? 0 : 1);/*]*/ } } // ^^ NewMaxTemperature |
然后使用如下命令编译该文件:
% javac -d ./ NewMaxTemperature.java
编译的结果是在/root/Hadoop/文件夹下生成了一个文件夹ch2,这是上面编译结果类的包名,文件夹里面包含如下三个.class文件:
NewMaxTemperature.class
NewMaxTemperature$NewMaxTemperatureMapper.class
NewMaxTemperature$NewMaxTemperatureReducer.class
接下来是将上面的ch2文件夹打包成可执行的jar包,方便Hadoop调用执行。为了打jar包,首先在/root/hadoop/目录下创建文本文件manifest.mf,该文件内容如下:
Main-Class: ch2.NewMaxTemperature
注意:冒号后面一定要加一个空格,否则后果自负。
然后执行如下命令:
% jar cvfm ch2.jar manifest.mf ch2
不出意外,现在在/root/Hadoop/目录下应该已经生成了ch2.jar文件,OK,大功告成,这就是我们想要的,接下来就是通过hadoop命令来执行我们的第一个Map-Reduce程序了。哦,忘了,Map-Reduce程序是用来进行离线数据处理的,我们还没有数据,无的放矢啊,既然Tom
White先生(《hadoop权威指南》的作者)贡献了他的上述程序,他当然也会为我们提供数据集啦,对,数据集和上述源码都可以从http://www.hadoopbook.com这里获取。我这里用的是源码包里的sample.txt数据集,里面内容很简单,就下面五行数据(数据的含义参考《hadoop权威指南》):
0067011990999991950051507004+68750+023550FM-12+038299999V0203301N00671220001CN9999999N9+00001+99999999999 0043011990999991950051512004+68750+023550FM-12+038299999V0203201N00671220001CN9999999N9+00221+99999999999 0043011990999991950051518004+68750+023550FM-12+038299999V0203201N00261220001CN9999999N9-00111+99999999999 0043012650999991949032412004+62300+010750FM-12+048599999V0202701N00461220001CN0500001N9+01111+99999999999 0043012650999991949032418004+62300+010750FM-12+048599999V0202701N00461220001CN0500001N9+00781+99999999999 |
我们将sample.txt数据集放到/root/Hadoop/文件夹下。OK,到这里真就大功告成了,只需要执行如下命令进行验证就可以了:
$ Hadoop jar ch2.jar sample.txt output
ok,看到了什么,是不是刷刷刷一串输出,这就是上面作业运行的输出的一些提示信息(考虑到篇幅问题,这里只是部分输出):
11/12/14 23:23:13 INFO jvm.JvmMetrics: Initializing JVM Metrics with processName
=JobTracker, sessionId= 11/12/14 23:23:14 WARN mapred.JobClient: Use GenericOptionsParser for
parsing the arguments. Applications should implement Tool for the same. 11/12/14 23:23:14 INFO input.FileInputFormat: Total input paths to process : 1 11/12/14 23:23:14 INFO mapred.JobClient: Running job: job_local_0001 11/12/14 23:23:14 INFO input.FileInputFormat: Total input paths to process : 1 11/12/14 23:23:14 INFO mapred.MapTask: io.sort.mb = 100 11/12/14 23:23:14 INFO mapred.MapTask: data buffer = 79691776/99614720 11/12/14 23:23:14 INFO mapred.MapTask: record buffer = 262144/327680 11/12/14 23:23:14 INFO mapred.MapTask: Starting flush of map output |
注意:在执行上面的Hadoop命令之前一定要保证/root/hadoop/目录下没有output文件夹,否则将不会运行成功,会提示:
Exception in thread "main" org.apache.Hadoop.mapred.FileAlreadyExistsException:
Output directory output already exists
这是Hadoop内置的保护措施,为了防止数据覆盖而丢失,想一想,一个花了几个小时运行得到的结果被意外的覆盖肯定是非常可怕的事情。
看一看/root/Hadoop/目录下发生了什么变化,是不是多了一个output文件夹,里面有个名为part-r-00000的文件,文件里面的内容就是我们通过hadoop计算得到的结果。
4.搭建Hadoop的eclipse开发环境
前面是通过命令行来编辑和运行,当然这个是基本功,但是这个确实比较麻烦。所以,如果能像普通java程序一样通过eclipse点击运行,结果就刷刷刷的出来,那确实是比较爽的事情啊,呵呵。所以,我就网上找了点资料,弄了弄,不弄不知道,弄了才知道,原来和其他许多的eclipse功能一样,只要添加个插件就可以,感谢那些无偿开发这些插件的人们,主会保佑你们的,呵呵。
前面我们已经下载了Hadoop的源码包,ok,插件就在源码包里面,contrib/eclipse-pluginhadoop-0.20.2-eclipse-plugin.jar,这就是我们想要的,将这个插件拷贝到eclipse的/plugins文件夹下,重启eclipse。
然后到‘Windows’ -> ‘Preference’ -> 'Hadoop Map/Reduce',配置Hadoop
Installation Directory,这里是/root/hadoop/hadoop-0.20.2。好了,现在,我们可以通过eclipse来开发了,新建—>项目,发现了什么:
可以直接新建Map/Reduce工程了,这不就是我们想要的吗,ok,把上面的例子再跑一遍吧,和普通的java项目一样就行了。
前面介绍了linux下Hadoop的安装和简单配置,主要是独立模式的配置,所谓独立模式是指不需要运行任何守护进程(daemon),所有程序都再单个JVM上执行,由于在独立模式下测试和调试MapReduce程序较为方便,因此该模式适合用在开发阶段。
这里主要记录了本人配置Hadoop伪分布模式的过程。所谓伪分布模式是在单机上模拟Hadoop分布式,单机上的分布式并不是真正的分布式,而是使用java进程模拟分布式运行中的各类节点,包括:NameNode,
DataNode, SecondaryNameNode, JobTracker, TaskTracker。其中,前三个概念是从分布式存储的角度来说的:集群节点由一个NameNode和若干个DataNode组成,另有一个SecondaryNameNode作为NameNode的备份;后两个概念是从分布式应用的角度来说的:集群中的节点由一个JobTracker和若干个TaskTracker组成,JobTracker负责任务的调度,TaskTracker负责并行任务执行。TaskTracker必须运行在DataNode上,这样便于数据的本地化计算,而JobTracker和NameNode则无需运行在同一台机器上。Hadoop本身是无法区分伪分布和分布式的,两种配置也很相似,唯一不同的是伪分布式是在单机上配置,DataNode和NameNode均是同一台机器。
java的安装和Hadoop的安装在前一节已经记录过了,这里略过不谈,下面主要记录伪分布模式的配置。
1.SSH无密码验证配置
在伪分布模式下运行时必须启动守护进程,而启动守护进程的前提是已经成功安装SSH。NameNode将使用SSH协议启动DataNode进程,伪分布模式下DataNode和NameNode均是本身,所以必须配置SSH
localhost的无密码验证。
首先,确保SSH已经安装,且服务器正在运行。我机器上是默认安装了的,所以这里不谈。
然后,基于空口令创建一个新SSH密钥,以启用无密码登录:
$ ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa
$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
用以下指令进行测试:
$ ssh localhost
这里测试我不知道需不需要重启机器再测试,网上的资料没说要重启,但我是重启了机器才能够通过ssh无密码登录的。
2.修改Hadoop配置文件
Hadoop的各个组件均可利用XML文件进行配置。core-site.xml文件用于配置Common组件的属性,hdfs-site.xml文件用于配置HDFS属性,mapred-site.xml文件则用于配置MapReduce属性。这些配置文件都在conf子目录下。
(1)在Hadoop-env.sh中配置Java环境
export JAVA_HOME=/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0
(2)配置core-site.xml, hdfs-site.xml及mapred-site.xml
core-site.xml:
<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <!-- Put site-specific property overrides in this file. --> <configuration> <property> <name>fs.default.name</name> <value>hdfs://localhost:9000</value> <description>HDFS的URI,文件系统://namenode标识:端口号</description> </property> <property> <name>Hadoop.tmp.dir</name> <value>/root/Hadoop/hadoop-0.20.2/hadooptmp</value> <description>namenode上本地的Hadoop临时文件夹</description> </property> </configuration> |
hdfs-site.xml:
<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <!-- Put site-specific property overrides in this file. --> <configuration> <property> <name>dfs.name.dir</name> <value>/root/Hadoop/hadoop-0.20.2/hdfs/name</value> <description>namenode上存储hdfs名字空间元数据 </description> </property> <property> <name>dfs.data.dir</name> <value>/root/Hadoop/hadoop-0.20.2/hdfs/data</value> <description>datanode上数据块的物理存储位置</description> </property> <property> <name>dfs.replication</name> <value>1</value> <description>副本个数,不配置默认是3,应小于datanode机器数量</description> </property> </configuration> |
mapred-site.xml:
<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <!-- Put site-specific property overrides in this file. --> <configuration> <property> <name>mapred.job.tracker</name> <value>localhost:9001</value> <description>jobtracker标识:端口号,不是URI</description> </property> <property> <name>mapred.local.dir</name> <value>/root/Hadoop/hadoop-0.20.2/mapred/local</value> <description>tasktracker上执行mapreduce程序时的本地目录</description> </property> <property> <name>mapred.system.dir</name> <value>/tmp/Hadoop/mapred/system</value> <description>这个是hdfs中的目录,存储执行mr程序时的共享文件</description> </property> </configuration> |
(3)配置masters文件,加入namenode的主机名
文件内容如下:
(4)配置slaves文件,加入所有datanode的主机名
文件内容如下:
3.格式化HDFS文件系统
在使用Hadoop前,必须格式化一个全新的HDFS安装,通过创建存储目录和NameNode持久化数据结构的初始版本,格式化过程创建了一个空的文件系统。由于NameNode管理文件系统的元数据,而DataNode可以动态的加入或离开集群,因此这个格式化过程并不涉及DataNode。同理,用户也无需关注文件系统的规模。集群中DataNode的数量决定着文件系统的规模。DataNode可以在文件系统格式化之后的很长一段时间内按需增加。
格式化HDFS文件系统非常方便。只需键入如下命令:
$ Hadoop namenode -format
该命令输出如下:
/************************************************************ STARTUP_MSG: Starting NameNode STARTUP_MSG: host = localhost.localdomain/127.0.0.1 STARTUP_MSG: args = [-format] STARTUP_MSG: version = 0.20.2 STARTUP_MSG: build = https://svn.apache.org/repos/asf/Hadoop/
common/branches/branch-0.20 -r 911707; compiled by 'chrisdo' on Fri Feb 19 08:07:34 UTC 2010 ************************************************************/ 11/12/17 13:44:58 INFO namenode.FSNamesystem: fsOwner=root,root,bin,daemon,sys,adm,disk,wheel 11/12/17 13:44:58 INFO namenode.FSNamesystem: supergroupsupergroup=supergroup 11/12/17 13:44:58 INFO namenode.FSNamesystem: isPermissionEnabled=true 11/12/17 13:44:58 INFO common.Storage: Image file of size 94 saved in 0 seconds. 11/12/17 13:44:58 INFO common.Storage: Storage directory /root/Hadoop/
hadoop-0.20.2/hdfs/name has been successfully formatted. 11/12/17 13:44:58 INFO namenode.NameNode: SHUTDOWN_MSG: /************************************************************ SHUTDOWN_MSG: Shutting down NameNode at localhost.localdomain/127.0.0.1 ************************************************************/ |
4.Hadoop集群启动
为启动HDFS和MapReduce守护进程,输入一下命令:
$ start-dfs.sh
输出如下(可以看出分别启动了namenode, datanode, secondarynamenode,也给出了日志的存放位置):
starting namenode, logging to /root/Hadoop/hadoop-0.20.2/bin/../
logs/hadoop-root-namenode-localhost.localdomain.out localhost: starting datanode, logging to /root/Hadoop/hadoop-0.20.2/
bin/../logs/hadoop-root-datanode-localhost.localdomain.out localhost: starting secondarynamenode, logging to /root/Hadoop/
hadoop-0.20.2/bin/../logs/hadoop-root-secondarynamenode-localhost.localdomain.out |
$ start-mapred.sh
输出如下(可以看出分别启动了jobtracker, tasktracker):
starting jobtracker, logging to /root/Hadoop/hadoop-0.20.2
/bin/../logs/hadoop-root-jobtracker-localhost.localdomain.out localhost: starting tasktracker, logging to /root/Hadoop/
hadoop-0.20.2/bin/../logs/hadoop-root-tasktracker-localhost.localdomain.out |
也可以用下面一条命令代替上面两条命令:
$ start-all.sh
实际上这个脚本里面就是调用了上面的两条命令。
本地计算机将启动三个守护进程:一个namenode,一个辅助namenode和一个datanode。可以浏览logs目录中的日志文件来检查守护进程是否成功启动,或通过Web界面:在http://localhost:50030/查看jobtracker或在http://localhost:50070/查看namenode。此外,java的jps命令也能查看守护进程是否在运行:
$ jps
6129 SecondaryNameNode 6262 JobTracker 6559 Jps 6033 DataNode 6356 TaskTracker 5939 NameNode |
终止守护进程也很容易,示例如下:
$ stop-dfs.sh
$ stop-mapred.sh
5.伪分布环境测试
在Hadoop的根目录下有几个jar文件,其中hadoop-0.20.2-examples.jar就是我们需要的,它里面包含wordcount,功能是计算输入文本中单词的数量,咱们使用命令建立测试的文件:
(1)先在本地磁盘建立两个输入文件file01和file02:
$ echo "Hello World Bye World" > file01
$ echo "Hello Hadoop Goodbye Hadoop" >
file02
(2)在hdfs中建立一个input目录:
$ Hadoop fs -mkdir input
(3)将file01和file02拷贝到hdfs中:
$ Hadoop fs -copyFromLocal /root/hadoop/file0* input
(4)执行wordcount:
$ Hadoop jar hadoop-0.20.2-examples.jar wordcount input
output
(5)完成之后,查看结果:
$ Hadoop fs -cat output/part-r-00000
执行结果为:
Bye 1 GoodBye 1 Hadoop 2 Hello 2 World 2 |
也可以进入http://localhost:50030/jobtracker.jsp查看结果:
ok,搞定,很想拿一些大的数据集玩一玩真正全分布模式,不过现在在外面帮导师做项目,机器不够,最少要三台,等回学校了,实验室搞几台机器玩玩。
前两节主要介绍了Hadoop运行环境和开发环境的搭建,有了这个,我们就可以开始hadoop的学习了,最近买了两本hadoop的书,先是买了一本《hadoop权威指南》,看了几天,感觉大部分都是在讲理论,不太适合作为hadoop入门的书籍,所以又买了本国内刘鹏写的《实战hadoop》,这本书到是写的比较浅显易懂,尤其是操作性比较强,个人觉得比较适合作为hadoop的入门书籍。这里就记录一下我学习hadoop的笔记吧。
1.Hadoop的产生
首先,hadoop是一个分布式系统基础架构,它可以让用户在不了解分布式底层细节的情况下,充分利用集群的威力,开发分布式程序,实现高速运算和存储。
2003年和2004年,google先后发表两篇论文《The Google File System》和《MapReduce:
Simplified Data Processing on Large Clusters》。在这两篇论文的驱动下,Hadoop创始人DougCutting为改善Nutch的性能,实现了DFS和MapReduce机制并将其成功应用于Nutch,说到Nutch,不得不说一说Lucene,Lucene是一个Java高性能全文索引引擎工具包,它可以方便地嵌入到各种实际应用中实现全文索引搜索功能,而Nutch是一个应用程序,它是一个以Lucene为基础实现的搜索引擎应用。Hadoop就是从Nutch项目中分离出来的一个专注于DFS和MapReduce的开源项目。
2.Hadoop架构
Hadoop是一个能够对大量数据进行分布式处理的软件框架,它主要包括两部分:用于分布式计算的MapReduce和用于分布式存储的HDFS。在分布式计算和分布式存储两个方面,Hadoop都采用了主/从(Master/Slave)架构,如下图所示:
要在一个集群中运行Hadoop,需要在集群中运行一系列的后台程序:NameNode、DataNode、Secondary
NameNode、JobTracker、TaskTracker。其中,NameNode、DataNode、Secondary
NameNode用于分布式存储,JobTracker、TaskTracker用于分布式计算(一个准备提交执行的应用程序成为作业(job),而从一个作业划分出来的、运行于各计算节点的工作单元称为任务(task))。另外,如上图所示,NameNode、Secondary
NameNode、JobTracker运行于Master节点上,每个Slave节点上都部署有一个DataNode和TaskTracker,以便于这个Slave服务器上运行的数据处理程序能尽可能直接处理本机的数据。
下面分别介绍这些后台程序:
1)NameNode
NameNode是HDFS的守护程序,负责记录文件是如何分割成数据块的,以及这些数据块分别被存储到哪些数据节点上。它的主要功能是对内存和I/O进行集中管理。
一般来说,NameNode所在的服务器不存储任何用户信息或执行计算任务,以避免这些程序降低服务器的性能。如果从服务器宕机,Hadoop集群仍旧可以继续运转。但是,由于NameNode是Hadoop集群中的一个单点,如果NameNode服务器宕机,整个系统将无法运行。
2)DataNode
集群中的每个从服务器都运行一个DataNode后台程序,这个后台程序负责把HDFS数据块读写到本地的文件系统。当需要通过客户端读/写某个数据时,先由NameNode告诉客户端去哪个DataNode进行具体的读/写操作,然后,客户端直接与这个DataNode服务器上的后台程序进行通信,并对相关的数据块进行读/写操作。
3)Secondary NameNode
Secondary NameNode是一个用来监控HDFS状态的辅助后台程序,就像NameNode一样,每个集群都有一个Secondary
NameNode,并且部署在一台单独的服务器上。Secondary NameNode不同于NameNode,它不接收或记录任何实时的数据变化,但是,它会于NameNode进行通信,以便定期地保存HDFS元数据的快照。由于NameNode是单点的,通过SecondaryNameNode的快照功能,可以将NameNode的宕机时间和数据损失降低到最小。同时,如果NameNode发生问题,Secondary
NameNode可以及时地作为备用NameNode使用。
4)JobTracker
JobTracker后台程序用来连接应用程序与Hadoop。用户代码提交到集群以后,由JobTracker决定哪个文件将被处理,并且为不同的task分配节点。同时,它还监控所有运行的task,一旦某个task失败了,JobTracker就会自动重新开启这个task,在大多数情况下,这个task会被放在不同的节点上。每个hadoop集群只有一个JobTracker,一般运行在集群的Master上。
5)TaskTracker
TaskTracker与负责存储数据的DataNode相结合。其处理结构上也遵循主/从架构,JobTracker位于主节点,统领MapReduce工作;而TaskTrackers位于从节点,独立管理各自的Task。每个TaskTracker负责独立执行具体的Task,而JobTracker负责分配task。虽然每个从节点仅有唯一的一个TaskTracker,但是每个TaskTracker可以产生多个Java虚拟机(JVM),用于并行处理多个map以及reduce任务。TaskTracker的一个重要职责就是与JobTracker交互,如果JobTracker无法准时获取TaskTracker提交的信息,JobTracker就判定TaskTracker已经崩溃,并将任务分配给其他节点处理。
3.Hadoop族群
整个hadoop族群包括很多个项目,如下:
Common:是整个Hadoop项目的核心,包括一组分布式文件系统和通用I/O的组件与接口(序列化、java
RPC和持久化数据结构)。
MapReduce:大型数据的分布式并行编程模型和程序执行框架,Google的MapReduce的开源实现。
HDFS:向应用程序提供高吞吐量访问的文件系统,是GFS的开源实现。
Avro:一种支持高效、跨语言的RPC以及永久存储数据的序列化实现。
Pig:一种数据流语言和运行环境,用以检索非常大的数据集,运行在MapReduce和HDFS的集群上。
Hive:一个分布式、按列存储的数据仓库。Hive管理HDFS中存储的数据,并提供基于SQL的查询语言(由运行时引擎翻译成MapReduce作业)用以查询数据。
HBase:一个分布式、按列存储数据库。HBase使用HDFS作为底层存储,同时支持MapReduce的批量式计算和点查询(随机读取)。
ZooKeeper:一个分布式、可用性高的协调服务。ZooKeeper提供分布式锁之类的基本服务用于构建分布式应用。
Cassandra:是一套开源分布式NoSQL数据库系统,它最初由Facebook开发,用于存储收件箱等简单格式数据,集Google
BigTable的数据模型与Amazon Dynamo的完全分布式的架构于一身。
Mahout:是一个在Hadoop上运行的机器学习类库(例如分类和聚类算法)。 |