随着计算机网络基础设施的完善,社交网络和电商的发展以及物连网的推动,产生了愈来愈多的大数据,使得人工智能最近几年也有了长足的发展(可供机器学习的样本数据量足够大了),大数据的存储和处理也愈来愈重要,国家对此也比较重视(可上网搜索关键字“大数据白皮书”关键字,以了解详细状况),会长决定和年轻人也一起学习一下,因而报了网易云课堂的课程,不定时将学习到的东西整理为博客,此乃开篇。java
学习大数据必先学习Hadoop,由于它是目前世界上最流行的分布式数据处理框架。node
Tips:所谓大数据,是指数据量庞大、产生数度快、结构多样的价值密度低的数据。其中,数据量庞大是指数据规模超出了1,2台高性能主机所能处理范围;结构多样性是指除了关系型数据库可以处理的结构化数据还包含半结构化数据(如各种传感设备必如地镑、卫星、GPS设备等产生的纯文本格式的数据,还有良心网站NASA官网公布的txt格式的空间天气数据等成行成列的数据)和非结构化数据(视频、图像等)。这些数据的价值密度广泛较低(和具体的应用范围也有关系,好比NASA的数据,若是想知道某天的太阳射电状况,看当天发布的txt就行了,价值密度很高,可是这就不算大数据了,由于须要采集的数据量很小;若是想知道过去N年太阳射电的极值就须要处理不少数据,这些数据的价值密度就低了),大数据处理的目的就是从价值密度的数据里把有价值的数据过滤分析出来。linux
Hadoop是一个用于分布式大数据处理的编程框架。同时它也是个大数据处理完整的生态系统,围绕着Hadoop,这个生态系统还包括但不限于:数据库
但愿本系列的写做可以坚持下去,对上述内容都有所涉及吧。apache
假设老王在某不知名IT公司工做,因为最近太阳活动异常,引发了领导的外甥的读硕士的同窗的关注,领导让老王把山西铁岛太阳射电望远镜观测到的近30年的太阳射电数据下载下来,让老王从里面找到最高的记录。老王毕竟搞挨踢已有多年,虽然技术不行,终日碌碌无为,但多年的直觉告诉老王这个很简单。老王马上下载了其中一个文件并大体看了文件的机构:数据保存在txt文件里,每行N列,其中包含了时间和数据信息列,大约每0.1s记录一条数据,一个文件记录15分钟的数据,大约有9000条记录,1个小时4个文件,1天96个文件,30年大约1051200个文件,一共大约100亿条数据,这其中还有一些损坏的文件,还有一些用9999表示的未检测到值的占位数据须要特殊照顾。编程
老王以为单机处理这些数据耗时过久,因而老王找来一些公司淘汰下来的旧服务器(通常小公司最破的机器都是服务器),准备每一个机器负责一部分,最后把结果汇总,老王在开发的过程当中仍是遇到了不少问题,好比,如何分配任务,有的机器破,有的机器新,还有的文件大,有的文件小,老是不能保证全部的任务一块儿完成,先完成任务的机器闲置浪费掉了资源;还有最后把结果经过网络通讯汇总起来,如何保证数据不丢失,不覆盖;还有若是某台机器出了问题,如何从新分配任务,这些非核心业务的开发使得老王心力憔悴,还好,老王最后找到了Hadoop这个工具,这个工具给老王提供了一个简单的编程模型,老王在map方法中写了分配的任务的逻辑,在reduce方法中写了合并结果的逻辑,而后Hadoop帮老王完成了其余全部事情,Hadoop就是干这个的。以上故事纯属虚构,若有雷同,实属巧合。服务器
其实上述意淫的例子里的数据量不是很大,若是天天产生上TB级别的数据,就算是速度很快的固态硬盘也须要小时级时间才能读取一遍,速度仍是远远跟不上,终归有上限,并且高性能主机价格不菲,不如把数据分开放到一个相对廉价又可扩展的计算机集群中,每一个节点上运行一段程序并处理一小块数据,而后在汇总处理结果,使用Hadoop可让开发者没必要把精力放在集群的建设上,采用Hadoop提供的简单的编程模型就能够实现分布式处理。网络
Hadoop集群中运行的守护进程共有5类:框架
Hadoop集群中的机器(节点)分为2类:主节点和从节点,NameNode、JobTracker所在节点为主节点(负责管理),DataNode和TaskTracker所在节点为从节点(负责干活儿)。ssh
NameNode节点负责将一个文件分红若干文件块,并记录了HDFS文件系统中的文件块放了在哪些DataNode中(一个数据块被冗余地放到1个或多个DataNode节点中),一个集群中只有一个NameNode节点(Hadoop2.X中状况有所不一样了),且该节点一般再也不运行DataNode和TaskTracker守护进程。
DataNode实际管理不少NameNode分配给它的不少数据块,当有文件块变更时会通知NameNode,同时也从NameNode接受指令。一个集群中有多个DataNode节点,DataNode之间也会保持联系,复制冗余文件块,这样当一个DataNode出现故障后不会影响到文件的完整性。
SNN只与NameNode通讯,定时获取HDFS元数据的快照,一个集群只有一个SNN,且SNN所在节点只运行SNN守护进程,不干其它的事情。当NameNode出现故障后,能够人工启用SNN做为NameNode。
JobTracker负责分配MapReduce任务给TaskTracker,负责监控任务的执行,如任务失败后重启任务。JobTracker守护进程运行在主节点上,一般该节点不运行DataNode和TaskTracker守护进程。
TaskTracker负责完成JobTracker分配的任务并和JobTranker进行通讯,回报状况。TaskTracker守护进程运行在多个子节点上
上图中,NameNode和JobTracker是分开的,若是集群规模不大也能够运行在同一个节点上(若是这个节点出现故障该如何恢复?)
在安装Hadoop以前须要先安装以下软件:
我用的是Ubuntu16.04,已经预装了ssh和ssh-kengen了,只须要安装jdk和sshd,能够经过执行命令which
命令来检查是否安装了某软件,如which sshd
下载压缩包解压便可:
sudo mkdir /usr/local/lib/jvm
sudo tar -zxv -f ~/setupFiles/jdk-8u101-linux-x64.tar.gz -C /usr/local/lib/jvm
配置环境变量:
修改 /etc/profile文件,追加:
export JAVA_HOME=/usr/local/lib/jvm/jdk1.8.0_101 export PATH=$JAVA_HOME/bin:$PATH
配置完毕后执行命令source /etc/profile
,此刻经过echo $JAVA_HOME
应该能看到刚才设置的了。
sudo apt install openssh-server
安装完了sshd后应该能够经过ssh lcoalhost
命令远程访问了,可是须要输入密码,Hadoop集群节点间要进行通讯须要配置为无密码登陆方式。
执行以下命令:
ssh-keygen -t rsa
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
chmod 0600 ~/.ssh/authorized_keys
ssh-keygen
命令时一路回车不要输入密码,执行完毕后会在/home/userName/.ssh路径下生成公钥和私钥id_rsa和id_rsa.pub。若是一切顺利的话,如今能够经过ssh localhost
无密码登陆了我下载的是1.0.4版本(2.X版本和1.X版本有着很大的差异,仍是先学会1.X再看2.X吧,咱们的课程也是以1.X为例的,事实上我刚才下的2.X,发现不少东西不懂,又退回1.X了,:-)),先把下载下来的压缩包解压到~/wiley/hadoop(其实最好放按照Linux的习惯放到/usr/local下,而后把hadoop目录及里面的文件所属用户和所属组改为当前用户和当前用户所属组)
解压后配置文件conf/hadoop-env.sh文件中的JAVA_HOME,反注释以下行
# export JAVA_HOME=/usr/lib/j2sdk1.5-sun
,而且设置为相应的Java所在路径。
Hadoop能够在三种模式下工做:
工做环境下是分布式模式,开发环境下可使用单节点模式或伪分布式模式,方便调试。解压后不作配置就是单节点模式,而伪分布式模式意思是指集群中的各个节点实际配置为同一台机器。下面的步骤用来配置伪分布式模式:
反注释并修改JAVA_HOME:
export JAVA_HOME=/usr/local/lib/jvm/jdk1.8.0_101
<configuration> <property> <name>hadoop.tmp.dir</name> <value>/home/joey/wiley/hadoop/hadoop_temp/</value> <description>http://stackoverflow.com/questions/2354525/what-should-be-hadoop-tmp-dir</description> </property> <property> <name>fs.default.name</name> <value>hdfs://localhost:9000</value> <description>NameNode守护进程所在机器和端口</description> </property> </configuration>
<configuration> <property> <name>dfs.replication</name> <value>1</value> <description>HDFS的默认副本数,因为是伪分布式模式,因此设置为1</description> </property> </configuration>
<configuration> <property> <name>mapred.job.tracker</name> <value>localhost:9001</value> <description>JobTracker守护进程所在机器及端口</description> </property> </configuration>
在启动以前先格式和HDFS文件系统:
cd ~/wiley/hadoop/bin ./hadoop namenode -format
而后启动Hadoop:./start-all.sh
,若是一切顺利的话用jps
命令查看会有5个进程(不包括jps自己):
此时能够打开两个基于Web的界面
文章的最后运行一个简单的MapReduceJob:单词统计。Hadoop中已经附有一些实例Java代码,放在了hadoop/src/examples/org/apache/hadoop/examples,其中一个叫作WordCount.java,是用来统计文件中单词数量的,代码很简单的,你们能够去看看。此处先运行一下这个例子感觉一下,执行以下命令
mkdir test
mkdir test/classes
mkdir test/src
cp src/examples/org/apache/hadoop/examples/WordCount.java test/src
生成jar文件:
javac -classpath hadoop-core-1.0.4.jar:lib/commons-cli-1.2.jar -d test/classes test/src/WordCount.java
jar -cvf test/WordCount.jar -C test/classes/ .
运行该程序须要两个参数(可参考源码文件),一个是放置文本文件的input路径,一个是输出结果的output路径,先在HDFS中建立之:
bin/hadoop dfs -mkdir input
在本地文件系统中建立一个文本文件test/f1.txt,写入一句话:2b or not 2b is ff
,把文件put到HDFS里:
bin/hadoop fs -put test/f1.txt /user/joey/input
激动人心的时刻到了:
bin/hadoop jar test/WordCount.jar org.apache.hadoop.examples.WordCount input output
因为input和output位于/user/joey下面,而/user/joey是默认的工做目录,全部直接写input和output,不用在前面加/user/joey/。如今看看运行结果:
竟然用了整整两天时间才写完,啊,虽然有点蛇尾,但是我太累了。到此结束,欢迎批评。
*参考资料: