hadoop1.X學習筆記
hadoop學習筆記
hadoop算是經典的分散式系統框架(distributed system framework)了, 整個系統跑在jvm上,所以原生支援java,對於我這個討厭java的人來說簡直是災難, 不過好在有python藉口,通過第三方庫(如:mrjob)可以實現python程式碼寫mapreduce的工作。
題外話,其實呢,個人覺得大部分情況下分散式系統完全用不到。。。 python+sqlite已經可以完成絕大多數個人專案了。一些牢騷以後有空會寫出來。
基礎
單機安裝
我的是mac,一般都可以通過brew安裝
brew install hadoop121
安裝的是1.21版本,為啥不用2.X版本呢,因為後續主要使用spark, 要的也就是hadoop的檔案系統HDFS而已,反正我討厭java不願意用hadoop,而且2.X還在更新中,老折騰累了。。。
安裝注意幾點
JAVA_HOME 的配置
用which java
確定你用的是啥版本的java,用whereis java
確定你的jdk位置
配置你的hosts檔案
具體位置我不知道。。。我用的mac,在/etc
資料夾下內容大致如下
127.0.0.1 localhost
255.255.255.255 broadcasthost
::1 localhost
fe80::1%lo0 localhost
127.0.0.1 XXX
配置你的hadoop
位置在hadoop根目錄中有個conf
資料夾,裡面有幾個檔案要添些東西
hadoop-env.sh
修改第9行JAVAHOME到你的jdk即可
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home
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>localhost:9000</value>
</property>
<!--fs.default.name:用來配置namenode,指定HDFS檔案系統的URL,通過該URL我們可以訪問檔案系統的內容,也可以把localhost換成本機IP地址;如果是完全分佈模式,則必須把localhost改為實際namenode機器的IP地址;如果不寫埠,則使用預設埠8020。 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/usr/local/Cellar/hadoop121/tmp/hadoop_tmp</value>
</property>
<!-- hadoop.tmp.dir:Hadoop的預設臨時路徑,這個最好配置,如果在新增節點或者其
他情況下莫名其妙的DataNode啟動不了,就刪除此檔案中的tmp目錄即可。不過如果刪除了NameNode機器的此目錄,那麼就需要重新執行NameNode格式化的命令。該目錄必須預先手工建立。-->
</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.data.dir</name>
<value>/usr/local/Cellar/hadoop121/hdfs/data</value>
</property>
<!--配置HDFS儲存目錄,資料存放目錄,用於datanode存放資料-->
<property>
<name>dfs.name.dir</name>
<value>/usr/local/Cellar/hadoop121/hdfs/name</value>
</property>
<!--用來儲存namenode的檔案系統後設資料,包括編輯日誌和檔案系統映像,如果更換地址的話,則需要重新使用hadoop namenode –format命令格式化namenode-->
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<!--用來設定檔案系統冗餘備份數量,因為只有一個節點,所有設定為1,系統預設數量為3-->
</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>
</property>
<!--該項配置用來配置jobtracker節點,localhost也可以換成本機的IP地址;真實分佈模式下注意更改成實際jobtracker機器的IP地址-->
</configuration>
其實單機預設也能跑。。。
ssh設定
先要去mac的偏好設定裡把共享中的遠端登入給勾選起來
$ ssh localhost
如果要口令就
$ ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa
$ cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
補充:環境變數設定
linux下我也不太懂,我就拿mac下的來說吧,應該是差不多的
$ cd ~
$ vim .bash_profile
內容增加如下:
#-----------for java-------------------------------------------------------------------------------
export java_home=/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home # Add java_home
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home # Add java_home
export JAVAPATH=/Users/huangsizhe/workspace/javafamily/java
#-----------for hadoop-------------------------------------------------------------------------------
export HADOOP_HOME=/usr/local/Cellar/hadoop121/1.2.1/libexec #你的hadoop根目錄
export HADOOP_CORE=$HADOOP_HOME/hadoop-core-1.2.1.jar #編譯方便
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/bin #把bin資料夾加入環境變數,我圖方便弄的,為了防止衝突建議不加,後面的操作可以用$HADOOP_HOME/bin/XXX代替
export HADOOP_HOME_WARN_SUPPRESS=1 #防止一個警告
export HADOOPPATH=/Users/huangsizhe/workspace/DistributedSystems/hadoop #方便快速定位自己的project,可有可無
單機測試
單機測試主要這幾個:
- hadoop系統執行測試
- mapreduce測試
- python介面測試
hadoop系統執行測試
先格式化namenode
$ hadoop namenode -format
ssh 到localhost $ ssh localhost
然後是啟動hadoop守護程式
$ start-all.sh
測試是否全部守護程式開啟了
$ jps
如果看到類似
1729 DataNode
1973 Jps
1943 TaskTracker
1807 SecondaryNameNode
1651 NameNode
1862 JobTracker
則說明成功了,注意這裡面有一個沒有就說明沒裝好
mapreduce測試
先自己試下官方的例子
cd到自己的專案資料夾,執行如下命令
$ hadoop fs -put $HADOOP_HOME/conf input
$ hadoop jar $HADOOP_HOME/hadoop-examples-1.2.1.jar grep input output 'dfs[a-z.]+'
$ hadoop fs -get output output
看到多出一個叫output的目錄,那個就是結果了
wordcount
這個是最簡單的mapreduce了,簡單說就是把一篇文章中出現的單詞做個詞頻統計
先把之前的input和output刪了,省的亂
$ hadoop fs -rmr input
$ hadoop fs -rmr output
專案檔案結構如下:
project |
|-src
|-input
|-lib
|-bin
WordCount.java
放在src裡,內容如下:
package org.myorg;
import java.io.IOException;
import java.util.*;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.conf.*;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapred.*;
import org.apache.hadoop.util.*;
public class WordCount {
public static class Map extends MapReduceBase implements Mapper<LongWritable, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
public void map(LongWritable key, Text value, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException {
String line = value.toString();
StringTokenizer tokenizer = new StringTokenizer(line);
while (tokenizer.hasMoreTokens()) {
word.set(tokenizer.nextToken());
output.collect(word, one);
}
}
}
public static class Reduce extends MapReduceBase implements Reducer<Text, IntWritable, Text, IntWritable> {
public void reduce(Text key, Iterator<IntWritable> values, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException {
int sum = 0;
while (values.hasNext()) {
sum += values.next().get();
}
output.collect(key, new IntWritable(sum));
}
}
public static void main(String[] args) throws Exception {
JobConf conf = new JobConf(WordCount.class);
conf.setJobName("wordcount");
conf.setOutputKeyClass(Text.class);
conf.setOutputValueClass(IntWritable.class);
conf.setMapperClass(Map.class);
conf.setCombinerClass(Reduce.class);
conf.setReducerClass(Reduce.class);
conf.setInputFormat(TextInputFormat.class);
conf.setOutputFormat(TextOutputFormat.class);
FileInputFormat.setInputPaths(conf, new Path(args[0]));
FileOutputFormat.setOutputPath(conf, new Path(args[1]));
JobClient.runJob(conf);
}
}
然後編譯
$ javac -classpath $HADOOP_CORE -d lib scr/WordCount.java
生成jarke執行程式
$ jar -cvf $HADOOPPATH/wordcount/bin/wordcount.jar -C lib/ .
然後在hdfs上存入input的檔案,我把spark的readme.md丟在input中,然後
$ hadoop fs -put input input
檢視下內容~~
$ hadoop fs -ls
$ hadoop fs -cat input/README.md
然後執行程式啦~
$ hadoop jar bin/wordcount.jar input output
輸出到本地~~
$ hadoop fs -get output output
結果可以看到了~~
python 介面測試
java這種煩死人的語言我不喜歡用,好在有python~~。
只是遺憾的是隻能使用Hadoop Streaming
來實現mapreduce。
既然都用python了當然最好是用封裝好的第三方庫來寫了,我選的mrjob
,pip 安裝即可
同樣的寫個WordCount.py
from mrjob.job import MRJob
import string
class MRWordFrequencyCount(MRJob):
def mapper(self, _, line):
line = line.strip()
delset = string.punctuation
line = line.translate(None,delset)
words = line.split()
for word in words:
yield word, 1
def reducer(self, key, values):
yield key, sum(values)
if __name__ == '__main__':
MRWordFrequencyCount.run()
不用HDFS執行
python script/WordCount.py input/README.md -r hadoop >output/out.md
用HDFS
python script/WordCount.py hdfs:///user/huangsizhe/input -r hadoop > pyout.txt
似乎不能輸出到HDFS上不過也蠻好了
完全分散式安裝
由於沒有那麼多硬體,所以就用虛擬機器模擬完全分散式安裝了
結構設計
叢集需要多臺計算機同時運算,其中一臺master2臺slave。 節點間用區域網互聯,可以相互ping通,所以用靜態ip地址,基本環境如下表
虛擬機器系統 | 機器名稱 | ip地址 --- | --- | -- debain8 | Master | 192.168.1.140 debain8 | slave1 | 192.168.1.141 debain8 | slave2 | 192.168.1.142
java配置
單機版本已經配置過一回,這次不詳細寫,只寫基本步驟,這次為了模擬伺服器配置將只在terminal中進行
下載jdk
從官網下載,然後將其放入資料夾中jvm ~$ wget http://download.oracle.com/otn-pub/java/jdk/7u75-b13/jdk-7u75-linux-x64.tar.gz?AuthParam=1425543713_d268d467b9cdd038acdf7a1748834ea6 ~$ su /home/hsz# tar zxvf jdk-7u75-linux-x64.tar.gz -C /usr/lib/jvm
配置環境變數
修改/etc/profile檔案,新增JAVA_HOME,HADOOP_INSTALL,以及將對應的bin資料夾假如PATH。不重啟的話別忘記source下
網路設定
域名解析設定
從這邊開始就是與單機版不同的地方了~~
首先修改/etc/hostname,將debian修改掉。master主機修改為master,slave1為slave1,slave2為slave2.
然後修改/etc/hosts,其中將127.0.0.1 debian
改為127.0.0.1 master
或改為
127.0.0.1 slave1`這種
再在其中新增
192.168.1.140 master
192.168.1.141 slave1
192.168.1.142 slave2
terminal中設定本機ip地址
用ifconfig檢視本機ip
一般與希望的不同,這邊我們臨時修改ip
sudo ifconfig eth1 192.168.1.141
每臺機器都將ip地址改好。相互之間ping一下看看能不能連通
也可以在路由器端直接修改ip地址,可以檢視我的這篇文章
設定專用賬戶
為了好記好用,我們為三臺機器都設一個名為hduser的賬戶,該賬戶屬於一個叫hadoop的group
sudo addgroup hadoop //設定hadoop使用者組
sudo adduser --ingroup hadoop hduser
sudo adduser hduser sudo
su - hduser //進入hduser賬戶
ssh連通
三臺機器通訊需要使用ssh無密碼通訊
生成本機ssh密匙
首先為各自機器生成一對公鑰,私鑰
~$ ssh-keygen -t dsa -P "" //用dsa因為它比rsa速度快
~$ cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
~$ ssh localhost
第一次ssh localhost會要你設定下,以後就可以無密碼登陸了。每臺機器都這麼設定下,要求都能
ssh localhost
無密碼登陸。
master與slave建立聯絡
將三臺機器上.ssh/資料夾下下載主機的公鑰
~$ ssh-copy-id hduser@slave1
~$ ssh-copy-id hduser@slave2
這就算配置好了
相關文章
- numpy的學習筆記\pandas學習筆記筆記
- IT學習筆記筆記
- 學習筆記筆記
- 【學習筆記】數學筆記
- 《JAVA學習指南》學習筆記Java筆記
- Elasticsearch學習筆記Elasticsearch筆記
- Scala學習筆記筆記
- MySql學習筆記MySql筆記
- jQuery 學習筆記jQuery筆記
- react學習筆記React筆記
- 學習筆記(4.3)筆記
- 學習筆記(4.4)筆記
- 學習筆記(3.29)筆記
- 學習筆記(4.1)筆記
- AOP學習筆記筆記
- AspectJ學習筆記筆記
- 學習筆記(3.27)筆記
- 學習筆記(4.2)筆記
- golang 學習筆記Golang筆記
- Zookeeper學習筆記筆記
- 學習筆記(3.24)筆記
- 學習筆記(3.25)筆記
- 學習筆記(3.21)筆記
- GitHub學習筆記Github筆記
- jest 學習筆記筆記
- typescript 學習筆記TypeScript筆記
- Echarts學習筆記Echarts筆記
- js學習筆記JS筆記
- shell學習筆記筆記
- Dubbo 學習筆記筆記
- SVN 學習筆記筆記
- 笨笨學習筆記筆記
- vue學習筆記Vue筆記
- wepack學習筆記筆記
- redis學習筆記Redis筆記
- PureMVC學習筆記REMMVC筆記
- gitee 學習筆記Gitee筆記
- 機器學習學習筆記機器學習筆記