HBase环境搭建随记
Posted 大墨垂杨
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HBase环境搭建随记相关的知识,希望对你有一定的参考价值。
====软件版本====
jdk:jdk-8u77-linux-x64.tar.gz
zookeeper:zookeeper-3.4.6.tar.gz
hadoop:hadoop-2.7.4.tar.gz
hbase:hbase-1.3.1-bin.tar.gz
====前提准备====
3台vmware虚拟机(已配置无秘钥访问)
其中,/etc/hosts文件内容如下:
====安装jdk====
上传安装包,解压缩,然后配置环境变量即可。
正常配置之后,在服务器任意路径执行java -version可以显示java版本。如下所示。
====安装zookeeper====
这里也不在过多描述,简单罗列一下配置文件。
配置文件:zoo.cfg
需要分别在3个节点的,dataDir路径下生成节点的myid。
启动并验证zookeeper是否正常
启动命令:/home/hadmin/zookeeper-3.4.6/bin/zkServer.sh start
查看状态:/home/hadmin/zookeeper-3.4.6/bin/zkServer.sh status
启动之后,3个节点的状态分别如下:
====安装hadoop====
因为HBase的底层是基于Hadoop的hdfs的,所以在安装HBase之前,必须要安装Hadoop,并确保hdfs正常。
Hadoop的配置重点是各个配置文件,这里只罗列各个配置文件的基础信息(经验证,这些基本上是必须要配置的),
需要配置环境变量的同时,共需要修改如下文件:
- hadoop-env.sh(各节点相同)
- core-site.xml(各节点相同)
- hdfs-site.xml(各节点相同)
- mapred-site.xml(各节点相同)
- yarn-site.xml(各节点相同)
- masters(各节点相同)
- slaves(各节点相同)
配置文件路径:/home/hadmin/hadoop-2.7.4/etc/hadoop
1、环境变量
2、hadoop-env.sh
修改JAVA_HOME即可。
3、core-site.xml
<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://ns</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/home/hadmin/data/hadoop/tmp</value> </property> <property> <name>dfs.journalnode.edits.dir</name> <value>/home/hadmin/data/hadoop/journal</value> </property> <property> <name>ha.zookeeper.quorum</name> <value>dscn1:2181,dscn2:2181,dscn3:2181</value> </property> </configuration>
4、hdfs-site.xml
<configuration> <property> <name>dfs.replication</name> <value>2</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>/home/hadmin/data/hadoop/hdfs/name</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>/home/hadmin/data/hadoop/hdfs/data</value> </property> <property> <name>dfs.permissions</name> <value>false</value> </property> <property> <name>dfs.nameservices</name> <value>ns</value> </property> <property> <name>dfs.ha.namenodes.ns</name> <value>nn1,nn2</value> </property> <property> <name>dfs.namenode.rpc-address.ns.nn1</name> <value>dscn1:9000</value> </property> <property> <name>dfs.namenode.rpc-address.ns.nn2</name> <value>dscn2:9000</value> </property> <property> <name>dfs.namenode.http-address.ns.nn1</name> <value>dscn1:50070</value> </property> <property> <name>dfs.namenode.http-address.ns.nn2</name> <value>dscn2:50070</value> </property> <property> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://dscn1:8485;dscn2:8485;dscn3:8485/ns</value> </property> <property> <name>dfs.ha.automatic-failover.enabled.ns</name> <value>true</value> </property> <property> <name>dfs.client.failover.proxy.provider.ns</name> <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value> </property> <property> <name>dfs.ha.fencing.methods</name> <value>sshfence</value> </property> <property> <name>dfs.ha.fencing.ssh.private-key-files</name> <value>~/.ssh/id_dsa</value> </property> </configuration>
5、mapred-site.xml
<configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> <property> <name>mapreduce.reduce.memory.mb</name> <value>128</value> </property> <property> <name>mapreduce.map.memory.mb</name> <value>256</value> </property> </configuration>
6、yarn-site.xml
<?xml version="1.0" encoding="utf-8"?> <configuration> <!-- Site specific YARN configuration properties --> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.resourcemanager.ha.enabled</name> <value>true</value> </property> <property> <name>yarn.nodemanager.vmem-check-enabled</name> <value>false</value> </property> <property> <name>yarn.resourcemanager.cluster-id</name> <value>ns</value> </property> <property> <name>yarn.resourcemanager.ha.rm-ids</name> <value>rm1,rm2</value> </property> <property> <name>yarn.resourcemanager.hostname.rm1</name> <value>dscn1</value> </property> <property> <name>yarn.resourcemanager.hostname.rm2</name> <value>dscn2</value> </property> <property> <name>yarn.resourcemanager.webapp.address.rm1</name> <value>dscn1:8088</value> </property> <property> <name>yarn.resourcemanager.webapp.address.rm2</name> <value>dscn2:8088</value> </property> <property> <name>yarn.resourcemanager.zk-address</name> <value>dscn1:2181,dscn2:2181,dscn3:2181</value> </property> <property> <name>yarn.resourcemanager.recovery.enabled</name> <value>true</value> </property> <property> <name>yarn.resourcemanager.store.class</name> <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value> </property> <property> <name>yarn.nodemanager.resource.memory-mb</name> <value>1024</value> </property> <property> <name>yarn.scheduler.minimum-allocation-mb</name> <value>256</value> </property> <property> <name>yarn.scheduler.maximum-allocation-mb</name> <value>1024</value> </property> </configuration>
7、masters
dscn1
dscn2
8、slaves
dscn1
dscn2
dscn3
上述几个文件配置完毕之后,按照如下顺序启动
■首次启动:
1、在dscn1上
hdfs zkfc -formatZK
2、在3节点分别启动:
hadoop-daemon.sh start journalnode
3、在dscn1上:
hdfs namenode -format
hadoop-daemon.sh start namenode
4、在dscn2上:
hdfs namenode -bootstrapStandby
hadoop-daemon.sh start namenode
5、在dscn1和dscn2上:
hadoop-daemon.sh start zkfc
6、在3个节点分别启动:
hadoop-daemon.sh start datanode
7、在dscn1和dscn2上:
yarn-daemon.sh start resourcemanager
8、在3个节点分别启动:
yarn-daemon.sh start nodemanager
9、在dscn1上启动:
mr-jobhistory-daemon.sh start historyserver
■以后每次启动:
1、在3节点分别启动:
hadoop-daemon.sh start journalnode
2、在dscn1、dscn2上:
hadoop-daemon.sh start namenode
3、在dscn1和dscn2上:
hadoop-daemon.sh start zkfc
4、在3个节点分别启动:
hadoop-daemon.sh start datanode
5、在dscn1和dscn2上:
yarn-daemon.sh start resourcemanager
6、在3个节点分别启动:
yarn-daemon.sh start nodemanager
7、在dscn1上启动:
mr-jobhistory-daemon.sh start historyserver
■停止集群:
按照上面相反的顺序,把start换成stop即可。
安装是否正常,可以通过如下方式验证:
1、通过hadoop命令来操作hdfs
浏览hdfs根目录:hadoop fs -ls /
创建文件夹:hadoop fs -mkdir /test
2、通过浏览器可以查看Hadoop集群状态
其中,两个namenode,需要有一个保持active状态
3、通过浏览器可以查看hadoop applications状态
4、3个节点的jps进程如下:
dscn1:
dscn2:
dscn3:
====安装HBase====
hbase的安装相对简单,主要完成以下文件的配置:
1、hbase-env.sh
export JAVA_HOME=/home/hadmin/jdk1.8.0_77
export HBASE_MANAGES_ZK=false export HBASE_CLASSPATH=/home/hadmin/hadoop-2.7.4/etc/hadoop
其中,JAVA_HOME如果不配置,可能会出现如下错误:
HBASE_CLASSPATH这个配置需要特别注意,这个配置的目的是让HBase能够找到hadoop的配置文件,从而与hdfs建立联系,如果不配置这个,会出现如下错误:
另外,官方文档上也提到了这点,并提供了2种解决方法,我这里采用的是"方法a"。
2、hbase-site.xml
<configuration>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<name>hbase.tmp.dir</name>
<value>/home/hadmin/data/hbase/tmp</value>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<value>dscn1,dscn2,dscn3</value>
</property>
<property>
<name>hbase.rootdir</name>
<value>hdfs://ns/hbase</value>
</property>
<property>
<name>hbase.master.port</name>
<value>60000</value>
</property>
<property>
<name>hbase.master.info.port</name>
<value>60010</value>
</property>
<property>
<name>hbase.regionserver.port</name>
<value>60020</value>
</property>
<property>
<name>hbase.regionserver.info.port</name>
<value>60030</value>
</property>
<property>
<name>hbase.zookeeper.property.dataDir</name>
<value>/home/hadmin/data/zk/data</value>
</property>
</configuration>
3. regionservers
dscn1
dscn2
dscn3
按照上述的配置文件完成配置之后,就可以启动HBase了
启动命令:/home/hadmin/hbase-1.3.1/bin/start-hbase.sh
停止命令:/home/hadmin/hbase-1.3.1/bin/stop-hbase.sh
启动之后,可以通过如下几个方面来验证HBase集群是否正常。
1、查看jps进程
dscn1:
dscn2:
dscn3:
2、通过HBase shell控制台,创建表:
如下图所示:
建表命令:create \'t1\', {NAME => \'f1\', VERSION => 2}
3、通过程序连接HBase,创建表:
如下程序中,建立了一张MY_TABLE_TEST1的表,并且进行了预分区。
建表程序如下:
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.HColumnDescriptor; import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.client.HBaseAdmin; import org.apache.hadoop.hbase.io.compress.Compression; import org.apache.hadoop.hbase.regionserver.BloomType; import org.apache.hadoop.hbase.util.Bytes; public class SplitRegion { private static final String TABLE_NAME = "MY_TABLE_TEST1"; private static final String COLUMN_FAMILY = "df"; public static void main(String[] args) throws Exception { System.out.print("[------]SplitRegion Start.\\n"); Configuration configuration= HBaseConfiguration.create(); System.out.print("[------]step 1 succeed.\\n"); configuration.set("hbase.zookeeper.quorum", "192.168.6.3,192.168.6.4,192.168.6.5"); HBaseAdmin admin = new HBaseAdmin(configuration); System.out.print("[------]step 2 succeed.\\n"); String table_name = TABLE_NAME; if (admin.tableExists(table_name)) { admin.disableTable(table_name); System.out.println("[----]disableTable table[" + table_name + "]\\n"); admin.deleteTable(table_name); System.out.println("[----]deleteTable table[" + table_name + "]\\n"); } HTableDescriptor desc = new HTableDescriptor(table_name); HColumnDescriptor family = new HColumnDescriptor(COLUMN_FAMILY.getBytes()); //过期时间 family.setTimeToLive(3 * 60 * 60 * 24); //按行过滤 family.setBloomFilterType(BloomType.ROW); desc.addFamily(family); System.out.print("[------]step 3 succeed.\\n"); byte[][] splitKeys = { Bytes.toBytes("0"), Bytes.toBytes("2"), Bytes.toBytes("4"), Bytes.toBytes("6"), Bytes.toBytes("8"), }; admin.createTable(desc, splitKeys); System.out.println("[----]createTable table[" + table_name + "]\\n"); System.out.print("[------]SplitRegion end.\\n"); } }
工程pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <artifactId>hbase_sample</artifactId> <groupId>hbase_sample</groupId> <version>1.0</version> <modelVersion>4.0.0</modelVersion> <dependencies> <dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase-client</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase-server</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase-common</artifactId> <version>1.3.1</version> </dependency> </dependencies> <build> <sourceDirectory>src/main/java</sourceDirectory> <outputDirectory>target/classes</outputDirectory> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>2.4</version> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
通过maven,将程序编译完成,上传jar包只服务器,运行程序结果如下:
如果不上传jar包,直接在本地模式运行,可能会出现如下错误:
错误关键字:Exception in thread "main" java.io.IOException: Failed to get result within timeout, timeout=60000ms
解决办法:在客户端里(即你的程序所在的计算机)里,要修改etc/hosts文件,
把你的HBase集群的服务器Master的主机名加进去,因为客户端访问HBase的过程中,
很多环节都是通过HBase Master节点的主机名访问的,加上之后,访问就一切正常了!
host文件位置:C:\\Windows\\System32\\drivers\\etc
修改之后如下图所示:
再次运行程序就可以正常访问Hbase集群了,结果贴图:
4、通过浏览器访问HBase管理界面:
地址:http://192.168.6.3:60010/
从图中可以看到,有3个Region Server,并有通过命令创建的【t1】表,以及通过程序创建的【MY_TABLE_TEST1】表。
====HBase调优参数====
<configuration> <!-- RegionServer的共享目录,用来持久化HBase。 默认情况下HBase是写到/tmp的。不改这个配置,数据会在重启的时候丢失。 --> <property> <name>hbase.rootdir</name> <value>hdfs://ns/hbase</value> </property> <!-- HBase的运行模式。false是单机模式,true是分布式模式。 若为false, HBase和Zookeeper会运行在同一个JVM里面。 默认: false --> <property> <name>hbase.cluster.distributed</name> <value>true</value> </property> <!-- Zookeeper集群的地址列表,用逗号分割。 如果在hbase-env.sh设置了HBASE_MANAGES_ZK,这些ZooKeeper节点就会和HBase一起启动。 默认: localhost。 部署的zookeeper越多,可靠性就越高,但是部署只能部署奇数个,主要为了便于选出leader。最好给每个zookeeper 1G的内存和独立的磁盘,可以确保高性能。hbase.zookeeper.property.dataDir可以修改zookeeper保存数据的路径。 --> <property> <name>hbase.zookeeper.quorum</name> <value>dscn11,dscn12,dscn13</value> </property> <!-- 本地文件系统的临时文件夹。 可以修改到一个更为持久的目录上。(/tmp会在重启时清除) 默认:${Java.io.tmpdir}/hbase-${user.name} --> <property> <name>hbase.tmp.dir</name> <value>/home/hadmin/data/hadoop</value> </property> <!-- 最大HStoreFile大小。 若某个列族的HStoreFile增长达到这个值,这个Hegion会被切割成两个。 默认:10737418240(10G) 小region对split和compaction友好,因为拆分region或compact小region里的storefile速度很快,内存占用低。 缺点是split和compaction会很频繁。 特别是数量较多的小region不停地split, compaction,会导致集群响应时间波动很大,region数量太多不仅给管理上带来麻烦,甚至会引发一些Hbase的bug。 一般512以下的都算小region。 大region,则不太适合经常split和compaction,因为做一次compact和split会产生较长时间的停顿,对应用的读写性能冲击非常大。 此外,大region意味着较大的storefile,compaction时对内存也是一个挑战。 当然,大region也有其用武之地。如果你的应用场景中,某个时间点的访问量较低, 那么在此时做compact和split,既能顺利完成split和compaction,又能保证绝大多数时间平稳的读写性能。 既然split和compaction如此影响性能,有没有办法去掉? compaction是无法避免的,split倒是可以从自动调整为手动。 只要通过将这个参数值调大到某个很难达到的值,比如100G,就可以间接禁用自动split(RegionServer不会对未到达100G的region做split)。 再配合RegionSplitter这个工具,在需要split时,手动split。 手动split在灵活性和稳定性上比起自动split要高很多,相反,管理成本增加不多,比较推荐online实时系统使用。 内存方面,小region在设置memstore的大小值上比较灵活,大region则过大过小都不行,过大会导致flush时app的IO wait增高,过小则因store file过多影响读性能。 --> <property> <name>hbase.hregion.max.filesize</name> <value>1073741824</value> </property> <!-- RegionServers受理的RPC Server实例数量。 对于Master来说,这个属性是Master受理的handler数量 默认: 10 RegionServer的请求处理IO线程数。 这个参数的调优与内存息息相关。 较少的IO线程,适用于处理单次请求内存消耗较高的Big PUT场景(大容量单次PUT或设置了较大cache的scan,均属于Big PUT)或ReigonServer的内存比较紧张的场景。 较多的IO线程,适用于单次请求内存消耗低,TPS要求非常高的场景。设置该值的时候,以监控内存为主要参考。 这里需要注意的是如果server的region数量很少,大量的请求都落在一个region上,因快速充满memstore触发flush导致的读写锁会影响全局TPS,不是IO线程数越高越好。 --> <property> <name>hbase.regionserver.handler.count</name> <value>600</value> </property> <!-- 如果memstore有hbase.hregion.memstore.block.multiplier倍数的hbase.hregion.flush.size的大小,就会阻塞update操作。 这是为了预防在update高峰期会导致的失控。如果不设上界,flush的时候会花很长的时间来合并或者分割,最坏的情况就是引发out of memory异常。 默认: 2 当一个region里的memstore占用内存大小超过hbase.hregion.memstore.flush.size两倍的大小时,block该region的所有请求,进行flush,释放内存。 虽然我们设置了region所占用的memstores总内存大小,比如64M,但想象一下,在最后63.9M的时候,我Put了一个200M的数据, 此时memstore的大小会瞬间暴涨到超过预期的hbase.hregion.memstore.flush.size的几倍。 这个参数的作用是当memstore的大小增至超过hbase.hregion.memstore.flush.size 2倍时,block所有请求,遏制风险进一步扩大。 调优: 这个参数的默认值还是比较靠谱的。如果你预估你的正常应用场景(不包括异常)不会出现突发写或写的量可控,那么保持默认值即可。 如果正常情况下,你的写请求量就会经常暴长到正常的几倍,那么你应该调大这个倍数并调整其他参数值, 比如hfile.block.cache.size和hbase.regionserver.global.memstore.upperLimit/lowerLimit,以预留更多内存,防止HBase server OOM。 --> <property> <name>hbase.hregion.memstore.block.multiplier</name> <value>8</value> </property> <!-- 当memstore的大小超过这个值的时候,会flush到磁盘。 这个值被一个线程每隔hbase.server.thread.wakefrequency检查一下。 默认:134217728(128M),单位:bytes --> <property> <name>hbase.hregion.memstore.flush.size</name> <value>33554432</value> </property> <!-- 默认值:0.4 这个参数的作用是防止内存占用过大,当ReigonServer内所有region的memstores所占用内存总和达到heap的40%时, HBase会强制block所有的更新并flush这些region以释放所有memstore占用的内存。 调优:这是一个Heap内存保护参数,默认值已经能适用大多数场景。 参数调整会影响读写,如果写的压力大导致经常超过这个阀值,则调小读缓存hfile.block.cache.size增大该阀值,或者Heap余量较多时,不修改读缓存大小。 如果在高压情况下,也没超过这个阀值,那么建以上是关于HBase环境搭建随记的主要内容,如果未能解决你的问题,请参考以下文章
zookeeper3.5.5 centos7 完全分布式 搭建随记
HBase二次开发之搭建HBase调试环境,如何远程debug HBase源代码