原文章作者:简书作者heamon7 文章地址:http://www.jianshu.com/users/1e2553eec992/latest_articles
本文是第一篇,记录了如何在 Ubuntu14.04搭建Hadoop 2.6 伪分布环境,以及运行自带的wordcount实例的详细步骤。
本文假设读者对Hadoop并无太多了解,对Ubuntu的常见操作有一定了解,会对部分操作予以了较为详细的解释或给予有助于更深入理解的链接。
主要分为以下几步:
- 安装Java 8 环境
- 新建Hadoop专用账户
- 配置本地ssh免登陆
- 安装并配置Hadoop伪分布模式
- 测试运行wordcount实例
Java 8 正式版 于 2014 年 3 月发布,该版本是一个有重大改变的版本,对 JAVA 带来了诸多新特性。详细信息可以参看 Java 8 新特性概述
安装Ubuntu下的基础开发套件,其中包括接下来 1.2 中要用到的 add-apt-repository 命令:
sudo apt-get install software-properties-common sudo apt-get install python-software-properties
关于ppa(Personal Package Archives)的解释可以参考什么是Ubuntu PPA以及为什么要用它
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update sudo apt-get install oracle-java8-installer
在根据以上的步骤安装了Java之后,可以通过以下命令检测是否安装成功,及安装的版本:
java -version
1.2中添加的Webupd8 ppa 仓库提供了一个包来设置Java的环境变量,通过以下命令安装:
sudo apt-get install oracle-java8-set-default
完成以上步骤后即已经成功的配置了安转Hadoop所需的Java开发环境。
为了营造一个更加独立的Hadoop运行环境,我们可以为系统新建一个Hadoop账户,以后执行Hadoop相关操作时都以该用户的身份登陆。
sudo useradd -m hadoop #-m参数表示同时创建用户的家目录
sudo usermod -s /bin/bash hadoop # 指定默认登陆shell
sudo passwd hadoop #修改用户默认的密码
sudo命令可以让你切换身份来执行命令,其执行过程是:
- 当用户执行sudo时,系统于/etc/sudoers文件中查找该用户是否具有sudo的权限;
- 当用户具有可执行sudo的权限后,便让用户输入用户自己的密码来确认;
- 若密码输入成功,便开始进行sudo后续接得命令(但root执行sudo时不需要输入密码, 若欲切换的身份与执行者的身份相同,则也不需要输入密码);
因此我们需要编辑/etc/sudoers文件,将我们的hadoop用户添加进去:
sudo chmod u+w /etc/sudoers #为当前用户添加对/etc/sudoers文件的写权限,该文件默认root只读
sudo vim /etc/sudoers
在文件中找到这两行:
# User privilege specification
root ALL=(ALL:ALL) ALL
在其下面添加一行
hadoop ALL=(ALL:ALL) ALL
这里解释一下这一行四个参数的意思,第一个是用户的账号,表示系统中得哪个账户可以使用sudo命令,默认是root,第二个是登录者的来源主机名,默认值root可以来自任何一台网络主机,第三个参数是可切换的身份,默认root可以切换成任何用户,若添加冒号,则表示的是用户组;第四个参数是可执行的命令,需使用绝对路径,默认root可以执行任何命令。其中ALL是特殊的关键字,表示任何主机、用户,或命令。
所以添加上面一行之后,我们的hadoop用户今后也具有和root一样的权限。
最后
最后我们撤销文件的写权限:
sudo chmod u-w /etc/sudoers
#合并操作 sudo chmod u+w /etc/sudoers && sudo vim /etc/sudoers && sudo chmod u-w /etc/sudoers
因为Hadoop是通过ssh管理各个组件,并实现通信的,为了避免每次需要输入密码,我们可以配置本地ssh免登陆。关于ssh的登陆方式及原理可以参考这里 SSH原理与运用
su hadoop
ssh-keygen -t rsa #用RSA算法生成公钥和密钥
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys #授权本机ssh免登陆
可以通过以下命令测试是否配置成功:
ssh localhost
若配置成功,则应该不需要输入密码。接着退出ssh登陆:
exit
上面是假设已经安装了SSH,如果没有安装,可以通过以下命令安装并启动:
sudo apt-get install openssh-server sudo /etc/init.d/ssh start
这里直接从官网下载Hadoop并放到hadoop用户主目录:
cd ~
wget http://apache.claz.org/hadoop/common/hadoop-2.6.0/hadoop-2.6.0.tar.gz
解压并简化路径:
tar xzf hadoop-2.6.0.tar.gz
mv hadoop-2.6.0 hadoop
首先设置Hadoop运行所需要的环境变量,我们编辑 ~/.bashrc 文件,添加我们的环境变量
#注意此处的路径和你的hadoop文件最后解压存放的位置是一致的
export HADOOP_HOME=/home/hadoop/hadoop
export HADOOP_INSTALL=$HADOOP_HOME
export HADOOP_MAPRED_HOME=$HADOOP_HOME
export HADOOP_COMMON_HOME=$HADOOP_HOME
export HADOOP_HDFS_HOME=$HADOOP_HOME
export YARN_HOME=$HADOOP_HOME
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
export PATH=$PATH:$HADOOP_HOME/sbin:$HADOOP_HOME/bin
然后我们重新导入~/.bashrc文件中的内容到shell中:
$ source ~/.bashrc
关于上面这条命令的执行原理,请查看这里和这里
接着我们编辑文件$HADOOP_HOME/etc/hadoop/hadoop-env.sh ,为Hadoop设置 Java环境变量:
vim $HADOOP_HOME/etc/hadoop/hadoop-env.sh
修改其中JAVA_HOME的值为:
export JAVA_HOME=/usr/lib/jvm/java-8-oracle #如果按照前面安装Java 8 的方法,则Java应该在此路径,也可以通过 echo $JAVA_HOME 命令来查看
Hadoop在目录 $HADOOP_HOME/etc/hadoop 下有很多配置文件,我们在此配置伪分布式,需要修改其中四个配置文件。首先进入配置文件目录:
$ cd $HADOOP_HOME/etc/hadoop
然后编辑 core-site.xml 文件:
vim core-site.xml
在 configuration 标签里添加属性,这里需要添加的是HDFS的NameNode的地址,修改成以下值:
<configuration>
<property>
<name>fs.default.name</name>
<value>hdfs://localhost:9000</value>
</property>
</configuration>
接着修改 hdfs-site.xml 文件:
vim hdfs-site.xml
修改为以下值:
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.name.dir</name>
<value>file:///home/hadoop/hadoopdata/hdfs/namenode</value>
</property>
<property>
<name>dfs.data.dir</name>
<value>file:///home/hadoop/hadoopdata/hdfs/datanode</value>
</property>
</configuration>
上面的 dfs.replication 属性是指定副本数量,这里数据只保存一份,默认是三份;而 dfs.name.dir 属性指定的是NameNode在本地的保存地址,dfs.data.dir 属性指定的是DataNode在本地的保存地址。
然后修改 mapred-site.xml 文件,但是默认Hadoop只提供了该配置的模板文件,我们需要复制模板编辑:
cp mapred-site.xml.template mapred-site.xml
vim mapred-site.xml
将该文件修改为以下值:
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
从字面意义也可以看出这里指定了MapReduce运行在Hadoop的Yarn框架上。
最后修改 yarn-site.xml 文件:
vim yarn-site.xml
修改为以下值:
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>
这里 yarn.nodemanager.aux-services 属性指定了Yarn的NodeManager获取数据的方式是shuffle,关于shuffle的介绍可以看这里MapReduce:详解shuffle过程
在使用HDFS文件系统前,我们需要先将其格式化:
hdfs namenode -format
此时应该有大量日志输出......
然后启动HDFS:
start-dfs.sh
此时应该有大量日志输出......
最后启动Yarn:
start-yarn.sh
此时应该有大量日志输出......
此时通过jps命令,应该可以看到除了jps本身外,还有5个Java进程,如下:
hadoop@ubuntu:~$ jps
14049 Jps
13811 ResourceManager
13459 DataNode
13642 SecondaryNameNode
13931 NodeManager
13342 NameNode
Hadoop自带有很多MapReduce的例子,其中一个比较和编程语言领域的 Hello World 齐名的是wordcount,能够统计出文件中每个单词出现的次数,我们可以用wordcount示例测试Hadoop环境。
首先我们在本地文件系统新建几个文本文件:
cd ~
mkdir input
echo "hello hadoop" > input/f1.txt
echo "hello world" > input/f2.txt
echo "hello wordcount" > input/f3.txt
然后通过以下命令上传这三个文件到HDFS:
hdfs dfs -mkdir -p /home/hadoop/input
hdfs dfs -put input/* /home/hadoop/input
可以通过以下命令查看上传的文件:
hdfs dfs -ls /home/hadoop/input/
Hadoop 通过把MapReduce代码捆绑到 jar 文件上,然后使用以下命令运行Streaming作业:
hadoop jar <jar> [mainClass] args..
在 目录 $HADOOP_HOME/share/hadoop/mapreduce/ 下有一些运行MapReduce任务所需的已编译好的jar包,其中 hadoop-mapreduce-examples-2.6.0.jar 包含了一些示例程序,wordcount便在其中,我们可以通过上面的命令来运行wordcount:
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.0.jar wordcount /home/hadoop/input /home/hadoop/output
注意此处的output文件夹不应该事先存在,应该由hadoop自己创建,否则会执行失败。
稍后片刻,待程序运行结束,我们可以通过以下命令来查看产生的结果文件:
hdfs dfs -ls /home/hadoop/output
这里的输出是:
hadoop@ubuntu:~$ hdfs dfs -ls /home/hadoop/output
15/06/18 02:47:10 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Found 2 items
-rw-r--r-- 1 hadoop supergroup 0 2015-06-18 02:13 /home/hadoop/output/_SUCCESS
-rw-r--r-- 1 hadoop supergroup 32 2015-06-18 02:13 /home/hadoop/output/part-r-00000
可以通过以下命令查看最后的输出结果:
hdfs dfs -cat /home/hadoop/output/part-r-00000
这里看到的结果是:
hadoop@ubuntu:~$ hdfs dfs -cat /home/hadoop/output/part-r-00000
15/06/18 02:49:38 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
hadoop 1
hello 3
java 1
world 1
hadoop@ubuntu:~$
至此,Hadoop的单机伪分布环境搭建成功。
已经按照此方法搭建了三次,写完本文后,又在一个全新的 Ubuntu 14.04 上一步步搭建了一次,一切正常。
最后,学习Hadoop到现在,虽然谈不上已经入门,但感受是:Hadoop入门过程困难的部分不是环境的搭建,而在于出现错误时对日志的分析,和问题的定位,然后还有就是出现性能问题时解决方案的搜寻。
扩展阅读:
- Apache Hadoop 2.7.0 Docs
- How to Setup Hadoop 2.6.0 (Single Node Cluster) on CentOS/RHEL and Ubuntu
- Hadoop安装教程_单机/伪分布式配置
- Hadoop第一个样例Wordcount运行笔记
- Hadoop集群(第6期)_WordCount运行详解
- Hadoop Troubleshooting
- Hadoop 0.18 中文文档
原文章作者:简书作者heamon7 文章地址:http://www.jianshu.com/p/358dd9b93937
承接上一篇文章已经创建了的Hadoop 2.6 的伪分布式环境,这里记录一下创建HBase伪分布式环境的过程,使用的HBase版本是1.1.1。
主要分为以下几步:
- 搭建Hadoop 2.6伪分布式环境(见上一篇文章)
- 下载安装Hbase 1.1.1
- 配置本地ssh免登陆
- 安装并配置Hadoop伪分布模式
- 测试运行wordcount实例
下载安装HBase
HBase的下载地址在这里,我们选择hbase-1.1.1-bin.tar.gz 版本下载:
su hadoop # 切换到上篇文章中创建的hadoop账户
cd ~
wget http://mirrors.cnnic.cn/apache/hbase/1.1.1/hbase-1.1.1-bin.tar.gz
然后解压到当前文件夹
tar xzvf hbase-1.1.1-bin.tar.gz
mv hbase1.1.1 hbase
修改HBase配置文件
2.1 进入HBase配置文件夹,为HBase 指定JAVA_HOME的值
cd hbase/conf
vim hbase-env.sh
按照上一篇文章的搭建过程,则这里JAVA_HOME的值应该是 /usr/lib/jvm/java-8-oracle,
# The java implementation to use. Java 1.7+ required. export JAVA_HOME=/usr/lib/jvm/java-8-oracle
然后编辑hbase-site.xml文件:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>hbase.rootdir</name>
<value>hdfs://localhost:9000/hbase</value>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<name>hbase.zookeeper.property.dataDir</name>
<value>/home/hadoop/zookeeper</value>
</property>
</configuration>
因为我们采用的是伪分布模式,这里需要将HBase的数据存储到之前的Hadoop的HDFS上,hbase.rootdir的值便是HDFS上HBase数据存储的位置,值中的主机名和端口号要和之前Hadoop的 core-site.xml中的fs.default.name的值相同,比如上一篇文章中的 hdfs://localhost:9000 。
vim ~/.bashrc
然后将以下值追加到文件末尾: export HBASE_HOME=/home/hadoop/hbase
export HBASE_CONF_DIR=$HBASE_HOME/conf
export HBASE_CLASS_PATH=$HBASE_CONF_DIR
export PATH=$PATH:$HBASE_HOME/bin
启动HBase
由于伪分布式下的 HBase 依赖 HDFS ,因此我们需要先启动 HDFS :
start-dfs.sh
然后启动 HBase :
start-hbase.sh
测试 HBase
上一步启动HBase之后,我们查看一下系统中的Java进程,应该可以看到以下几个进程:
hadoop@iZ259rt0i0iZ:~$ jps
2832 HMaster
2945 HRegionServer
2245 DataNode
2150 NameNode
3065 Jps
2745 HQuorumPeer
2431 SecondaryNameNode
然后我们启动HBase shell,利用HBase提供的命令进行简单交互:
hadoop@iZ259rt0i0iZ:~$ hbase shell
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/home/hadoop/hbase/lib/slf4j-log4j12-1.7.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/hadoop/hadoop/share/hadoop/common/lib/slf4j-log4j12-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
2015-08-06 15:09:30,272 WARN [main] util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable HBase Shell; enter 'help<RETURN>' for list of supported commands. Type "exit<RETURN>" to leave the HBase Shell Version 1.0.1.1, re1dbf4df30d214fca14908df71d038081577ea46, Sun May 17 12:34:26 PDT 2015 hbase(main):001:0> help HBase Shell, version 1.0.1.1, re1dbf4df30d214fca14908df71d038081577ea46, Sun May 17 12:34:26 PDT 2015 Type 'help "COMMAND"', (e.g. 'help "get"' -- the quotes are necessary) for help on a specific command. Commands are grouped. Type 'help "COMMAND_GROUP"', (e.g. 'help "general"') for help on a command group. COMMAND GROUPS: Group name: general Commands: status, table_help, version, whoami Group name: ddl Commands: alter, alter_async, alter_status, create, describe, disable, disable_all, drop, drop_all, enable, enable_all, exists, get_table, is_disabled, is_enabled, list, show_filters Group name: namespace Commands: alter_namespace, create_namespace, describe_namespace, drop_namespace, list_namespace, list_namespace_tables Group name: dml Commands: append, count, delete, deleteall, get, get_counter, incr, put, scan, truncate, truncate_preserve Group name: tools Commands: assign, balance_switch, balancer, catalogjanitor_enabled, catalogjanitor_run, catalogjanitor_switch, close_region, compact, compact_rs, flush, major_compact, merge_region, move, split, trace, unassign, wal_roll, zk_dump Group name: replication Commands: add_peer, append_peer_tableCFs, disable_peer, enable_peer, list_peers, list_replicated_tables, remove_peer, remove_peer_tableCFs, set_peer_tableCFs, show_peer_tableCFs Group name: snapshots Commands: clone_snapshot, delete_all_snapshot, delete_snapshot, list_snapshots, restore_snapshot, snapshot Group name: configuration Commands: update_all_config, update_config Group name: security Commands: grant, revoke, user_permission Group name: visibility labels Commands: add_labels, clear_auths, get_auths, list_labels, set_auths, set_visibility SHELL USAGE: Quote all names in HBase Shell such as table and column names. Commas delimit command parameters. Type <RETURN> after entering a command to run it. Dictionaries of configuration used in the creation and alteration of tables are Ruby Hashes. They look like this: {'key1' => 'value1', 'key2' => 'value2', ...} and are opened and closed with curley-braces. Key/values are delimited by the '=>' character combination. Usually keys are predefined constants such as NAME, VERSIONS, COMPRESSION, etc. Constants do not need to be quoted. Type 'Object.constants' to see a (messy) list of all constants in the environment. If you are using binary keys or values and need to enter them in the shell, use double-quote'd hexadecimal representation. For example: hbase> get 't1', "key\x03\x3f\xcd" hbase> get 't1', "key\003\023\011" hbase> put 't1', "test\xef\xff", 'f1:', "\x01\x33\x40" The HBase shell is the (J)Ruby IRB with the above HBase-specific commands added. For more on the HBase Shell, see http://hbase.apache.org/book.html hbase(main):002:0> list TABLE 0 row(s) in 0.4050 seconds => [] hbase(main):003:0>
退出HBase shell:
hbase(main):003:0> exit
这里我们尝试使用HBase 的 Thrift API,用Python和HBase进行简单交互。首先启动HBase的Thrift服务:
hadoop@iZ259rt0i0iZ:~$ hbase-daemon.sh start thrift starting thrift, logging to /home/hadoop/hbase/logs/hbase-hadoop-thrift-iZ259rt0i0iZ.out
然后安装Python的happybase模块,HBase是对 HBase的Thrift接口的一个简单包装:
pip install happybase
然后启动ipython,如果没有ipython,请通过pip安装:
hadoop@iZ259rt0i0iZ:~$ ipython
Python 2.7.6 (default, Mar 22 2014, 22:59:56)
Type "copyright", "credits" or "license" for more information.
IPython 3.2.1 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features. %quickref -> Quick reference. help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.
In [1]: import happybase
In [2]: connection = happybase.Connection('localhost')
In [3]: connection.tables()
Out[3]: []
In [4]: families = {'basic':dict(max_versions=3),'detail':dict(max_versions=1000),'comment':dict(max_versions=1000),'answer':dict(max_versions=1000),'follower':dict(max_versions=1000)}
In [5]: connection.create_table('question',families)
In [6]: connection.tables()
Out[6]: ['question']
In [7]:
至此,我们HBase的伪分布式环境搭建完毕。
Reference: