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 完全分布式 搭建随记

springboot gradle项目搭建随记

HBase二次开发之搭建HBase调试环境,如何远程debug HBase源代码

搭建maven私服随记

甘道夫Eclipse+Maven搭建HBase开发环境及HBaseDAO代码演示样例

HBase的Java代码开发(从Linux集群环境搭建开始)