ubuntu server虚拟机
安装openssh server:用于ssh直接连接
hadoop配置
参考链接:hadoop配置
修改网络参数
最好虚拟机配置仅主机,主机与虚拟机就能互联
(桥接、NAT、仅主机)
修改Ubuntu的网络配置
- 设置IP、网关、掩码等。
vi /etc/network/interfaces,添加以下内容:
iface eth0 inet static
address 192.168.1.10
netmask 255.255.255.0
gateway 192.168.1.1
auto eth0 - 添加DNS,vi /etc/resolv.conf,添加以下内容(重启会覆盖),在/etc/resolvconf/resolv.conf.d/目录创建tail文件或修改目录内base文件不会受重启影响:
#以下内容为DNS服务器ip,需要与主机DNS服务器一模一样(ipconfig查看)
nameserver 101.226.4.6
nameserver 114.114.114.114 - 生效: /etc/init.d/networking restart
- 在主机的网络链接是OK的情况下,测试Ubuntu是否OK。比如ping www.baidu.com
网络问题排错
基本的排错步骤(从上往下)
ping 127.0.0.1ping的通说明tcp协议栈没有问题
ping 主机地址 ping的通说明网卡没有问题
ping 路由器默认网关 ping的通说明包可以到达路由器
最后 ping DNS服务器地址
卡在那一步,就补哪里
桥接ubuntu,使虚拟机能连上外网又能与主机通信
- 完成修改ubuntu的网络配置
- 编辑->虚拟网络编辑器,设置两个桥接网络,一个使用主机的无线网络适配器,另一个设为wifi direct 虚拟适配器
- ubuntu设置网络适配器为自定义,指向使用主机的无线网络适配器的桥接网络
公钥认证
私钥放客户端,公钥放服务端,通过ssh协议可实现无需账号密码输入登陆
windows宿主机的vmnet1的ip设为与虚拟机集群在同一网段,故windows与linux服务器可以互相访问
hadoop安装
- 解压:在~目录
tar zxvf ./hadoop-1.2.1.tar.gz
mv hadoop-1.2.1/ hadoop - 配置hadoop环境变量,在~目录
sudo vi /etc/profile
在结尾加入:
export HADOOP_HOME=/home/hadoop/hadoop
export PATH= PATH: HADOOP_HOME/bin
然后更新修改的配置:
source /etc/profile - 启动hadoop
./start-all.sh
注意:出现JAVA_HOME is not set时,到hadoop/conf找到hadoop-env.sh,把#export JAVA_HOME=/usr/lib/j2sdk1.6去掉#并改为安装JAVA的路径,如:export JAVA_HOME=/usr/lib/jdk - hadoop/bin$下运行jps查看java进程
单机模式下无java进程 - 查看hdfs文件系统
hadoop/bin$hadoop fs -ls
查错
- datanode是否alive
通过/bin/hadoop dfsadmin -report ,在web的界面下也可以看到datanode是否alive
查看namenode和datanode是否alive - 查看系统HDFS状况:HDFS
查看系统MapReduce状况:MapReduce - 查错方法:
最好查看日志:logs文件夹
错误集锦
- java.lang.IllegalArgumentException: Does not contain a valid host :port authority
解决:节点主机名无法识别、core-site.xml 中的 fs.default.name 的value 值有问题、也可能是mapred-site.xml中的mapred.job.tracker的 value 值有问题。 - org.apache.hadoop.ipc.Client: Retrying connect to server: master/192.168.1.10:9000. Already tried 0 time(s)
解决:去掉/etc/hosts中环回地址127.0.1.1 - The type java.util.Map$Entry cannot be resolved. It is indirectly ref
解决:项目的jre版本从1.8换到1.7
参考:项目jre版本切换 - java.io.IOException: Failed to set permissions of path: \home\jerry123\hadoop\tmp\mapred\staging\jerry123649601815.staging to 0700
解决:windows文件权限问题,linux下不会报此错
参考链接:
简单方法:每个项目均操作一遍
彻底方法,修改jar包内容1
彻底方法,修改jar包内容2
Secondary NameNode可以及时地作为备用NameNode使用。在namenode宕机时充当备用。
安全模式
master下:
- 返回安全模式是否开启
hadoop dfsadmin -safemode get
- 进入安全模式
hadoop dfsadmin -safemode enter
- 离开安全模式
hadoop dfsadmin -safemode leave
- 检查HDFS状态,包括DN信息
hadoop dfsadmin -report
概念
JobTracker后台程序用来连接应用程序与Hadoop。
TaskTracker与负责存储数据的DataNode相结合,其处理结构上也遵循主/从架构。
Datanode是文件系统的工作节点,他们根据客户端或者是namenode的调度存储和检索数据,并且定期向namenode发送他们所存储的块(block)的列表。
Namenode 管理者文件系统的Namespace。
HDFS文件系统
数据读取
- DistributedFileSystem.open()
- DistributedFileSystem实例通过RPC向NameNode发送请求,获取文件数据块,并将最近距离 DataNode地址返回给DistributedFileSystem
- DistributedFileSystem生成FSDataInputStream实例,实例内封装了DFSInputStream对象,包含文件信息
- FSDataInputStream.read()
- 读取数据
- FSDataInputStream.close()
数据写入
- DistributedFileSystem.create()
- 通过RPC向NameNode发出创建文件请求,NameNode检查权限,成功后创建文件,否则抛出异常
- DistributedFileSystem生成FSDataOutputStream实例,该实例包装了DFSOutputStream对象,负责后续文件写入操作
- FSDataInputStream.write()
- FSDataInputStream.close()
HDFS Shell命令
- 输出能够支持的命令列表
hadoop fs - 路径指定文件内容输出到/user/input.txt
hadoop fs -cat /user/input.txt - 改变文件/hadoop/hadoopfile的组到group1(加-R,文件夹内文件递归进行)
hadoop fs -chgrp group1 /hadoop/hadoopfile - 改变文件/hadoop/hadoopfile的权限为764
hadoop fs -chmod [-R] 764 /hadoop/hadoopfile - 改变文件/hadoop/hadoopfile的拥有者为user1 (加-R,文件夹内文件递归进行)
hadoop fs -chown [-R] /hadoop/hadoopfile - 本地文件/home/hadoop/stdrj49.flv复制到HDFS下的/user
hadoop fs -copyFromLocal /home/hadoop/stdrj49.flv /user - copyToLocal
- cp
- du:显示目录中所有文件大小
- dus:显示文件大小,对目录显示目录内所有文件大小之和
- expunge:清空回收站
- get:复制文件到本地
- ls:显示目录下文件的详细信息
- lsr:ls的递归版本
- mkdir:创建目录
- movefromLocal:文件或目录从本地到HDFS
- mv:文件从源路径到目标路径
- put
- rm
- rmr
- test:检查文件是否存在
- text:源文件输出位文本格式
- touchz:创建空文件
eclipse 创建MapReduce项目及项目文件编写
eclipse创建MapReduce项目
eclipse创建MapReduce项目详细
eclipse中DFS location可查看hadoop分布式文件系统HDFS
HDFS是针对大文件进行设计的,处理大文件能体现它的性能优势,小文件时会导致文件系统效率低下、集群内部节点内存占用率过高、浪费大量的存储空间。解决小文件问题有一些方法,这些方法均有各自优缺点。
MapReduce 原理及开发
初识MapReduce
试用WordCount:自带程序
统计一批文本文件中各单词出现的频次
步骤:WordCount先把输入的文本文件按单词进行切分,然后统计每个单词出现的次数,并把结果输出
1. master服务器上创建一个input目录
2. input目录下创建两个文本文件:text1.txt,text2.txt
3. 将input目录复制到HDFS文件系统中,并命名为in目录:
1) cd ..
2) hadoop fs -put input in
4. 执行WordCount程序
1)cd ~/hadoop
2)hadoop jar hadoop-examples-1.2.1.jar wordcount in out
5. 查看执行的结果
hadoop fs -cat out/*
自己编WordCount
三个class:
- WordMapper
- WordReducer
- WordCount
in目录需要有,并且目录内文本文件即为待处理的文件,out文件夹是运行后生成的,运行前不能存在此文件夹
处理过程
- 数据拆分为split,文件拆分成
MapReduce工作原理
数据处理过程
MapReduce框架分为两个阶段,Map阶段和Reduce阶段,分别自定义map()函数和reduce()函数,这两个函数把数据从一个数据集转换为另一个数据集。
- Map阶段:待处理数据集分割成许多小数据集(splits),每个小数据集进一步分解为一批键值对
框架组成:Job位于master,Task位于slave
- JobTracker:接收Job,调度Job每一个子任务Task运行于TaskTracker,监控它们,发现失败的Task就重新运行它们。
- TaskTracker:运行于多个节点上的slaver服务。通过心跳(Heartbeat)与JobTracker通信,接收作业,并执行任务。
- JobClient:每个Job都会在用户端通过JobClient类将应用程序及配置打包成jar文件,存在HDFS,路劲提交到JobTracker的master服务,master创建Task并将它们分发到各个TaskTracker中执行。
- JobInProgress:JobClient提交Job后,JobTracker会创建一个JobInProgress来跟踪和调度这个Job,并把它添加到队列。
- TaskInProgress:JobTracker启动任务通过每个TaskInProgress来运行Task,这时会把Task对象序列化写入相应TaskTracker,TaskTracker收到后创建对应的TaskInProgress用于监控和调度Task。
- MapTask和ReduceTask:完整的Job会依次执行Mapper、Combine和Reducer。
Shuffle和Sort过程:MapReduce的核心过程
- Shuffle:从Map输出数据开始,包括执行一些列数据排序以及把数据从Map输出传送到Reduce输入的过程。
- Sort:Map端输出数据按key进行排序的过程。
shuffle过程优化主要在于减少拉取数据的量及尽量使用内存而非磁盘
MapReduce编程接口
- InputFormat:输入格式类,为MapRduce作业描述输入的细节规范,包括形式和格式
- FileInputFormat:文件输入格式类
- InputSplit:数据分块类,每个均对应一个Mapper的输入
- RecordReader:记录读取类
- Mapper:执行map过程
- Reducer:执行reduce过程
- OutputFormat:输出格式类
- FileOutputFormat:文件输出格式类
- RecordWriter:记录输出类
相关应用
- 计数类应用:一个班级有许多学生,各有三门课要学,每门课为一文本文件,求每个同学平均成绩
- 去重计数类应用:有两文件,文件中表示某天某ip访问系统的日志,将时间和ip相同的数据只留一份
- 简单排序类应用:输入文件中数据进行排序
- 倒排索引类应用:根据单词查找文档的索引为倒排索引
- 二次排序类应用:排序时根据多个属性来排序
HBase数据库
HBase介绍
- google搜索运用了BigTable数据库,HBase是BigTable的开源实现
- HBase是一种NoSql数据库
- 特点:
- 大:普通硬件也能处理大量数据,
- 面向列:存储、检索和权限控制面向列,
- 稀疏:空列不占空间
HBase架构和原理
架构
- HBase Client:HBase使用者
- Zookeeper:在HBase中协调管理节点,提供分布式协调、管理操作
- HMaster:整个架构的控制节点
- 管理用户对表的增删查改
- 管理RegionServer的负载均衡、协调Region分布
- 在Region Split后,负责新的Region的分配
- HRegionServer:HBase最核心组件,负责响应用户的I/O请求,向HDFS读写数据
- HRegion:HRegionServer管理的一类数据对象
- Store:存储的核心对象,由StoreFile和MemStore组成
- MemStore:StoreFile的内存缓存
- StoreFile:以HDFS文件形式存储数据
- Hlog:解决分布式环境下系统可靠性而设计的
HBase逻辑视图
映射函数:CellValue=Map(TableName,RowKey,ColumnKey,TimeStamp)
HBase的物理模型
HBase是按列存储的稀疏矩阵
元数据表
HBase核心组件:MasterServer、HRegionServer、HRegion、HMemcache、HLog、HStore
Hadoop主从结构:master和slave
HBase主从结构:MasterServer和HRegionServer
Client增删查改操作找到对应的HRegionServer是通过两个元数据表:-ROOT-和.META.,这两个表存储系统信息:Region的分布和每个Region的详细信息。
安装
安装出错集锦
- 若出现HBase无法停止
解决方法:必须先关HBase,再关Hadoop,顺序出错会导致HBase无法用sh脚本停止
解决参考链接:HBase安装部署 - 如果Hbase的时间没有同步,启动主节点会起来,子节点的regionServer就不会起来。
解决方法:同步集群中各服务器的时间戳
参考链接:Hbase时间同步
网页查看相关信息
HBase
Region Server
Zookeeper tree
HBase Shell操作
5类命令:表管理、数据管理、工具、复制和其他
基本shell命令
- hbase shell:启动shell
- status:查看HBase的运行状态
- version:查看版本
- help:获得帮助
- exit:退出shell
DDL操作:表操作
- create ‘tab1’,’colfam1’:创建表tab1,列族名为colfam1
- list:以列表形式显示所有数据表
- describe ‘tab1’:查看表的结构
- disable ‘tab1’:将表设为不可用状态
- alter ‘tab1’,NAME=>’F2’,VERSIONS=>5:添加一个列族’F2’
- alter ‘tab1’,NAME=>’F1’,METHOD=>’delete’:删除列族’F1’
enable ‘tab1’:将表设为启动状态
exists ‘tab1:查询表是否存在
- is_enabled ‘tab1’:判断表是否可用
is_disabled ‘tab1’:判断表是否不可用
disable ‘tab1’:设置表不可用
- drop ‘tab1’:删除表
DML操作:记录操作
#创建student表 create 'student','address','info' #向表中插入记录 put 'student','zhangsan','info:height','180' put 'student','zhangsan','info:weight','80' put 'student','zhangsan','address:province','Hubei' put 'student','zhangsan','address:city',Huangshi' #获取一条数据 get 'student','zhangsan' #获取一个id、一个列族的所有数据 get 'student','zhangsan','info' #获得一个id、一个列族中一个列的所有数据 get 'student','zhangsan','info:height' #更新一个记录 put 'student','zhangsan','info:height','70' #全表扫描 scan 'student' #删除id为zhangsan的值的info:weight字段 delete 'student','zhangsan','info:weight' get 'student','zhangsan' #查询表中有多少行 count 'student' #将整张表清空 truncate 'student'
HBase Shell脚本
- 新建Shell脚本:test.sh,内容如下:
put 'student','zhangsan','info:height','180' put 'student','zhangsan','info:weight','80' put 'student','zhangsan','address:province','Hubei' put 'student','zhangsan','address:city',Huangshi'
- 执行脚本文件:hbase shell test.sh
- 脚本执行结果:scan ‘student’
基于API使用HBase
API简介
- HBaseConfiguration类:从hbase-default.xml和hbase-site.xml读取配置信息
- HBaseAdmin类:对数据表结构进行操作:创建、删除、列出、表有无效、增删表列族等
//创建数据表 createTable(HTableDescriptor desc) //删除表 deleteTable(byte[] tableName) //使表有效 enableTable(byte[] tableName) //使表无效 disableTable(byte[] tableName) //检查表是否存在 tableExists(String tableName) //修改表的模式,异步操作,可能花一定时间 modifyTable(byte[] tableName,HTableDescriptor htd)
- HTableDescriptor类:表相关属性和操作的接口:
//添加一个列族 addFamily(HColumnDescriptor) //移除一个列族 removeFamily(byte[] column) //获取表的名字 getName() //获取属性的值 getValue(byte[] key) //设置属性的值 setValue(String key,String value)
- HColumnDescriptor类:
//获取列族的名字 getName() //获取对应属性的值 getValue(byte[] str) //设置对应属性值 setValue(String key,String value)
- HTable类:与HBase直接通信,但更新操作是非线程安全的
//释放所有资源或挂起内部缓冲区中的更新 close() //检查Get实例所指定的值是否存在于HTable的列中 exists(Get get) //获取当前给定列族的scanner实例 getScanner(byte[] family) //获取当前表的HTableDescriptor实例 getTableDescriptor() //获取表名 getTableName() //检查表是否有效 isTableEnabled(HBaseConfiguration conf,String tableName) //向表中添加值 put(Put put)
- Put类
//指定列和对应值添加到Put实例中 add(byte[] family,byte[] qualifier,byte[] value) //将指定的列和对应值以及时间戳加到Put实例中 add(byte[] family,byte[] qualifier,long ts,byte[] value) //获取Put实例的行 getRow() //获取Put实例的行锁 getRowLock() //获取Put实例的时间戳 getTimeStamp() //检查familyMap是否为空 isEmpty() //设置Put实例的时间戳 setTimeStamp(long timeStamp)
- Set类
//获取指定列族和列修饰符对应的列 addColumn(byte[] family,byte[] qualifier) //通过指定的列族获取其对应列的所有列 addFamily(byte[] family) //获取指定列族的列的版本号 setTimeRange(long minStamp,long maxStamp) //当执行Get操作时设置服务器端的过滤器 setFilter(Filter filter)
- Scan类
scan.addFamily() addColumn() //指定最大的版本个数,若不设置则默认取最新的版本 setMaxVersions(int maxVersions) //指定最大的时间戳和最小的时间戳 setTimeRange(long minStamp,long maxStamp) //指定时间戳 setTimeStamp() //指定Filter来过滤不需要的信息 setFilter() //指定开始的行 setStartRow(byte[] startRow) //指定结束的行 setStopRow(byte[] stopRow)
- Result类
//检查对应指定的列是否存在 containsColumn(byte[] family,byte[] qualifier) //获取对应列族所包含的修饰符与值的键值对 getFamilyMap(byte[] family) //获取对应列的最新值 getValue(byte[] family,byte[] qualifier)
- ResultScanner类:客户端获取值的接口
//关闭scanner并释放分配给它的资源 close() //获取下一行的值 next()
运行程序出错
- eclpse下运行程序出现警告:WARN zookeeper.ClientCnxn: Session 0x0 for server null, unexpected error
解决方法:
参考链接:
linux下编译java代码
src里面存放了我们的java类,lib里是我们要用到的包,我们的目地是首先把java类编译成class文件放在当前class目录下并包含包路径,然后把class文件打成jar放在lib下
第一步编译java代码
首先们要建一个class文件,javac编译的时候不会生成目录除了类中含有的包名目录外,然后用如下的命令就可以生成class文件,并放在我们指定的目录下
Java代码
javac -encoding utf-8 -Djava.ext.dirs=./lib -d class src/com/yan/compress/*.java
对上面的命令进行说明
-encoding utf-8 指定编码,如果不指定就以平台的编码为准
-Djava.ext.dirs=./lib 指定编译的时候调用的类
-d class 指定要生成到的目录
src/com/yan/compress/*.java 这就是具体要编译的类了,星号表示这个目录下的所有的java文件,如果在这个目录下有多个java文件,那么装分别生成class文件到指定目录
命令执行后就可以看到class目录中就有了我们编译过的类
第二步生成jar文件
Java代码
jar -cf lib/abc.jar class/com/yan/compress/ZipCompressorByAnt.class
对命令进行一个说明
-c 就是要生成jar包
-f后面跟指定的包名lib/abc.jar
class/com/yan/compress/ZipCompressorByAnt.class 类文件
命令执行后就可以看到在lib目录下多了一个abc.jar包
第三步就是执行这个类
Java代码
java -Djava.ext.dirs=./lib com.yan.compress.ZipCompressorByAnt 2013-08-04
-Djava.ext.dirs=./lib 指定要用到的包
com.yan.compress.ZipCompressorByAnt 带包名的类
2013-08-04 参数,如果需要参数的话就可以带参数
到这里一个手工编译类的例子就完成了,下面就对命令的一些细节进行一些扩展
编译多个类
如果在编译的时候想一下子编译多个类,并且这些类不在一个文件夹里怎么办
假设除了下面的要编译的类个还有在a/.java b/.java c/*.java 一些文件
其实也简单就看命令
Java代码
javac -encoding utf-8 -Djava.ext.dirs=./lib -d class src/com/yan/compress/*.java a/*.java b/*.java c/*.java
参考链接:
linux下编译执行java代码
eclipse自动导入包快捷键:shift+ctrl+o
HBase的EXception
Exception | Description |
---|---|
ClockOutOfSyncException | 当一个RegionServer始终偏移太大时,master节点结将会抛出此异常. |
DoNotRetryIOException | 用于提示不要再重试的异常子类: 如UnknownScannerException. |
DroppedSnapshotException | 如果在flush过程中快照内容并没有正确的存储到文件中时,该异常将被抛出. |
HBaseIOException | 所有hbase特定的IOExceptions都是HBaseIOException类的子类. |
InvalidFamilyOperationException | Hbase接收修改表schema的请求,但请求中对应的列族名无效. |
MasterNotRunningException | master节点没有运行的异常 |
NamespaceExistException | 已存在某namespace的异常 |
NamespaceNotFoundException | 找不到该namsespace的异常 |
NotAllMetaRegionsOnlineException | 某操作需要所有root及meta节点同时在线,但实际情况不满足该操作要求 |
NotServingRegionException | 向某RegionServer发送访问请求,但是它并没有反应或该region不可用. |
PleaseHoldException | 当某个ResionServer宕掉并由于重启过快而导致master来不及处理宕掉之前的server实例, 或者用户调用admin级操作时master正处于初始化状态时, 或者在正在启动的RegionServer上进行操作时都会抛出此类异常. |
RegionException | 访问region时出现的异常. |
RegionTooBusyException | RegionServer处于繁忙状态并由于阻塞而等待提供服务的异常. |
TableExistsException | 已存在某表的异常 |
TableInfoMissingException | 在table目录下无法找到.tableinfo文件的异常 |
TableNotDisabledException | 某个表没有正常处于禁用状态的异常 |
TableNotEnabledException | 某个表没有正常处于启用状态的异常 |
TableNotFoundException | 无法找到某个表的异常 |
UnknownRegionException | 访问无法识别的region引起的异常. |
UnknownScannerException | 向RegionServer传递了无法识别的scanner id的异常. |
YouAreDeadException | 当一个RegionServer报告它已被处理为dead状态,由master抛出此异常. |
ZooKeeperConnectionException | 客户端无法连接到zookeeper的异常. |