HBase 高可用集群整合 Phoenix 配置

Posted 车斗

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HBase 高可用集群整合 Phoenix 配置相关的知识,希望对你有一定的参考价值。

HBase 高可用集群整合 Phoenix 配置

接上文:HBase 高可用集群配置

命令行参考:https://blog.csdn.net/ubuntu64fan/article/details/80832903

整合 phoenix 虽然简单,但是有坑。按照官网(http://phoenix.apache.org/installation.html )进行操作在新版本上基本不会成功!

首先确保你的 hbase ha 搭建完全正常(查看各节点日志 “$HBASE_HOME/logs/*.log” 文件里没有任何 ERROR)。好了,接下来做整合。

我采用 apache hbase-2.4.2 + phoenix-hbase-2.4-5.1.1-bin.tar.gz,下载(http://phoenix.apache.org/download.html)链接:

        http://www.apache.org/dyn/closer.lua/phoenix/phoenix-5.1.1/phoenix-hbase-2.4-5.1.1-bin.tar.gz

将 phoenix-hbase-2.4-5.1.1-bin.tar.gz 解压到全部HBase的节点上,然后把下面2个 jar 复制到 $HBASE_HOME/lib 目录下(每个hbase节点都要这么做):

        phoenix-server-hbase-2.4-5.1.1.jar
        htrace-core-3.1.0-incubating.jar

其中 htrace-core-3.1.0-incubating.jar 我是从maven repo 下载的(这个巨坑,phoenix 居然没有携带):

       https://repo1.maven.org/maven2/org/apache/htrace/htrace-core/3.1.0-incubating/htrace-core-3.1.0-incubating.jar

将下面的配置段加入到全部HBase节点的hbase-site.xml 中:

  <property>
    <name>hbase.regionserver.wal.codec</name>
    <value>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec</value>
  </property>

接着,选中其中某台作为 phoenix 客户端(命令行和jdbc),仅作为 phoenix 客户端的机器需要配置如下环境变量(/etc/profile.d/phoenix-clienv.sh 名字任意):

export JAVA_HOME=/usr/local/java/jdk1.8.0_271
export JRE_HOME=$JAVA_HOME/jre
export ZK_HOME=/usr/local/apache/apache-zookeeper-3.5.9-bin

export PHOENIX_HOME=/opt/hacl/phoenix-hbase-2.4-5.1.1-bin
export PHOENIX_OPTS="-Djava.library.path=/opt/hacl/hadoop-3.3.0/lib/native"

export HBASE_CLIENT_HOME=/opt/hacl/hbase-2.4.2-client
export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$PHOENIX_HOME:$PHOENIX_HOME/phoenix-client-hbase-2.4-5.1.1.jar:$HBASE_CLIENT_HOME/lib
export PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PHOENIX_HOME/bin:$ZK_HOME/bin

就是要把 phoenix-client-hbase-2.4-5.1.1.jar 配置到 JAVA 的 CLASSPATH 里。然后把 $HBASE_HOME/conf/hbase-site.xml 复制到 $PHOENIX_HOME/bin/ 目录下,覆盖原有的文件。

接下来重启  HBase 集群。然后运行phoenix命令行客户端接入HBase:

cd $PHOENIX_HOME

bin/sqlline.py flink01,flink02,flink03

如下输出:

[root@flink01 phoenix-hbase-2.4-5.1.1-bin]# bin/sqlline.py flink01.pepstack.com
Setting property: [incremental, false]
Setting property: [isolation, TRANSACTION_READ_COMMITTED]
issuing: !connect -p driver org.apache.phoenix.jdbc.PhoenixDriver -p user "none" -p password "none" "jdbc:phoenix:flink01.pepstack.com"
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/opt/hacl/phoenix-hbase-2.4-5.1.1-bin/phoenix-client-hbase-2.4-5.1.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/opt/hacl/hadoop-3.3.0/share/hadoop/common/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
Connecting to jdbc:phoenix:flink01.pepstack.com
Connected to: Phoenix (version 5.1)
Driver: PhoenixEmbeddedDriver (version 5.1)
Autocommit status: true
Transaction isolation: TRANSACTION_READ_COMMITTED
sqlline version 1.9.0
0: jdbc:phoenix:flink01.pepstack.com> !table
+-----------+-------------+------------+--------------+---------+-----------+---------------------------+----------------+-------------+----------------+--------------+--------------+----------------+----------+
| TABLE_CAT | TABLE_SCHEM | TABLE_NAME |  TABLE_TYPE  | REMARKS | TYPE_NAME | SELF_REFERENCING_COL_NAME | REF_GENERATION | INDEX_STATE | IMMUTABLE_ROWS | SALT_BUCKETS | MULTI_TENANT | VIEW_STATEMENT | VIEW_TYP |
+-----------+-------------+------------+--------------+---------+-----------+---------------------------+----------------+-------------+----------------+--------------+--------------+----------------+----------+
|           | SYSTEM      | CATALOG    | SYSTEM TABLE |         |           |                           |                |             | false          | null         | false        |                |          |
|           | SYSTEM      | CHILD_LINK | SYSTEM TABLE |         |           |                           |                |             | false          | null         | false        |                |          |
|           | SYSTEM      | FUNCTION   | SYSTEM TABLE |         |           |                           |                |             | false          | null         | false        |                |          |
|           | SYSTEM      | LOG        | SYSTEM TABLE |         |           |                           |                |             | true           | 32           | false        |                |          |
|           | SYSTEM      | MUTEX      | SYSTEM TABLE |         |           |                           |                |             | true           | null         | false        |                |          |
|           | SYSTEM      | SEQUENCE   | SYSTEM TABLE |         |           |                           |                |             | false          | null         | false        |                |          |
|           | SYSTEM      | STATS      | SYSTEM TABLE |         |           |                           |                |             | false          | null         | false        |                |          |
|           | SYSTEM      | TASK       | SYSTEM TABLE |         |           |                           |                |             | false          | null         | false        |                |          |
+-----------+-------------+------------+--------------+---------+-----------+---------------------------+----------------+-------------+----------------+--------------+--------------+----------------+----------+
0: jdbc:phoenix:flink01.pepstack.com> !quit
Closing: org.apache.phoenix.jdbc.PhoenixConnection

 然而并没有结束,考虑到性能和调优,我的真实的 hbase-site.xml 如下:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
  <property>
    <name>hbase.rootdir</name>
    <value>hdfs://hacl/hbase</value>
  </property>
  <property>
    <name>hbase.tmp.dir</name>
    <value>/hacl/hbase/tmp</value>
  </property>
  <property>
    <name>hbase.cluster.distributed</name>
    <value>true</value>
  </property>
  <property>
    <name>hbase.zookeeper.quorum</name>
    <value>flink01.pepstack.com,flink02.pepstack.com,flink03.pepstack.com</value>
  </property>
  <property>
    <name>hbase.regionserver.handler.count</name>
    <value>30</value>
  </property>
  <property>
    <name>zookeeper.session.timeout</name>
    <value>30000</value>
  </property>
  <property>
    <name>dfs.namenode.avoid.read.stale.datanode</name>
    <value>true</value>
  </property>
  <property>
    <name>dfs.namenode.avoid.write.stale.datanode</name>
    <value>true</value>
  </property>
  <property>
    <name>hbase.wal.provider</name>
    <value>filesystem</value>
  </property>
  <property>
    <name>zookeeper.znode.parent</name>
    <value>/hbase</value>
  </property>
  <property>
    <name>hbase.regionserver.wal.codec</name>
    <value>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec</value>
  </property>
  <property>
    <name>hbase.client.scanner.caching</name>
    <value>1000</value>
  </property>
  <property>
    <name>hbase.client.scanner.timeout.period</name>
    <value>600000</value>
  </property>
  <property>
    <name>hbase.client.ipc.pool.type</name>
    <value>RoundRobinPool</value>
  </property>
  <property>
    <name>hbase.client.ipc.pool.size</name>
    <value>10</value>
  </property>
  <property>
    <name>hbase.regionserver.lease.period</name>
    <value>7200000</value>
  </property>
  <property>
    <name>phoenix.query.timeoutMs</name>
    <value>3600000</value>
  </property>
  <property>
    <name>phoenix.query.keepAliveMs</name>
    <value>60000</value>
  </property>
  <property>
    <name>hbase.client.pause</name>
    <value>50</value>
  </property>
  <property>
    <name>hbase.client.retries.number</name>
    <value>10</value>
  </property>
  <property>
    <name>hbase.rpc.timeout</name>
    <value>300000</value>
  </property>
  <property>
    <name>hbase.client.operation.timeout</name>
    <value>3600000</value>
  </property>
  <property>
    <name>hbase.hstore.blockingStoreFiles</name>
    <value>200</value>
  </property>
  <property>
    <name>hbase.hregion.max.filesize</name>
    <value>107374182400</value>
  </property>
  <property>
    <name>hbase.rpc.controllerfactory.class</name>
    <value>org.apache.hadoop.hbase.ipc.controller.ServerRpcControllerFactory</value>
  </property>
  <property>
    <name>hbase.region.server.rpc.scheduler.factory.class</name>
    <value>org.apache.hadoop.hbase.ipc.PhoenixRpcSchedulerFactory</value>
  </property>
  <property>
    <name>hbase.regionserver.executor.openregion.threads</name>
    <value>100</value>
  </property>
</configuration>

具体参数很多,我整理好放在下面的 yaml 文件里了,适合用于程序编写配置参考:

---
Description: Apache Phoenix 5.0 Config Schema
Refer: http://phoenix.apache.org/update_statistics.html

FirstCreate: 2021-05-06
LastUpdate: 2021-05-07

MetaKeys:
  - Section: Apache Phoenix Configurations
    Help: |
      Phoenix各个参数的含义及设置: $PHOENIX_HOME/bin/hbase-site.xml

    Refer: https://blog.csdn.net/qq_36732988/article/details/87915449
    Keys:
      - phoenix.query.timeoutMs:
          Help: |
            查询超时时间,默认为10分钟,单位:毫秒
          Type: Integer
          Unit: Milliseconds
          Default: 600000

      - phoenix.query.keepAliveMs:
          Help: |
            当客户端的线程超过线程池的核心线程数量时,空闲线程等待任务的默认时间,单位:毫秒。超过这个时间,空闲线程就会关闭,默认是60s
          Type: Integer
          Unit: Milliseconds
          Default: 60000

      - phoenix.query.threadPoolSize:
          Help: |
            客户端线程池的线程数量,当集群扩大时,这个数量最好也增大
          Type: Integer
          Default: 128

      - phoenix.query.queueSize:
          Help: |
            线程池的队列最大数,超过这个数的任务就会被拒绝。当值为0的时候,就会使用 SynchronousQueue
          Type: Integer
          Default: 5000

      - phoenix.stats.guidepost.width:
          Help: |
            服务器端参数,这个参数指定集群传输的字节指标,值较小时,会增加并行计算,但也增加客户端合并块的数量。(初步理解,当客户端数据数据到100MB时,就会发送到服务端。数值小的时候,可以多线程发送)
          Type: Integer
          Unit: Bytes
          Default: 104857600

      - phoenix.stats.guidepost.per.region:
          Help: |
            服务器端参数, 指定每个region的指标。如果这个值大于0,那么guidepost.width就会是 MAX_FILE_SIZE of table / phoenix.stats.guidepost.per.region. ,否则就会使用phoenix.stats.guidepost.width,没有默认值

      - phoenix.stats.updateFrequency:
          Help: |
            服务器端参数, 指定 statistics table的统计信息的刷新频率,刷新后会通知客户端。默认是15分钟
          Type: Integer
          Unit: Milliseconds
          Default: 900000

      - phoenix.stats.useCurrentTime:
          Help: |
            服务器高级参数,为真:当hbase表发生合并或者compactions时,统计表会用服务器的当前时间作为行的时间戳。为false:就会使用表的被统计的最大的时间戳。除非你自己自己插入数据时,自己控制时间戳,最好使用默认。
          Type: Boolean
          Default: true

      - phoenix.query.spoolThresholdBytes:
          Help: |
            并行查询结果的阈值,超过这个阈值,就会溢出到硬盘。默认为20MB,单位:字节
          Type: Integer
          Unit: Bytes
          Default: 20971520

      - phoenix.query.maxSpoolToDiskBytes:
          Help: |
            并行查询结果最大的字节数,超过这个阈值,查询就会失败。默认是1GB
          Type: Integer
          Unit: Bytes
          Default: 1024000000

      - phoenix.query.maxGlobalMemoryPercentage:
          Help: |
            所有线程使用的最大堆内存( Runtime.getRuntime().maxMemory()) 的百分比. 只会对小的内存跟踪。主要是统计group by aggregation过程中产生的map内存的使用。当到达这个值的时候,会尝试获取更多的内存。主要就是节省内存的使用。默认是15%
          Type: Integer
          Unit: Percentage
          Default: 15

      - phoenix.query.maxGlobalMemorySize:
          Help: |
            所有线程使用的最大内存的字节数。如果设置这个参数,就会使用phoenix.query.maxGlobalMemorySize和phoenix.query.maxGlobalMemoryPercentage的最小值

      - phoenix.query.maxGlobalMemoryWaitMs:
          Help: |
            当内存不够时,client就会被阻塞。这个参数是最大的等待时间。超过这个时间。就会抛出 InsufficientMemoryException 默认是10s
          Type: Integer
          Unit: Milliseconds
          Default: 10000

      - phoenix.query.maxTenantMemoryPercentage:
          Help: |
            所有消费者能够占用phoenix.query.maxGlobalMemoryPercentage的最大的占用比例,超过这个值,就会抛出 InsufficientMemoryException 默认是100%
          Type: Integer
          Unit: Percentage
          Default: 100

      - phoenix.query.dateFormat:
          Help: |
            默认时间格式。TO_CHAR(<date>), TO_DATE(<String>), resultSet.getString(<date-column>)
          Default: "yyyy-MM-dd HH:mm:ss"

      - phoenix.query.dateFormatTimeZone:
          Help: |
            时区的ID,指定默认的时区。对date, time,timestamp,to_date()有效.可以简写为“PST”,也可以写为“America/Los_Angeles”,或自定义偏移量如“GMT-9:00”,“LOCAL”会使用当前的时区
          Default: "GMT"

      - phoenix.query.numberFormat:
          Help: |
            数字和字符串互相转换的数字格式。 TO_CHAR(<decimal-number>), TO_NUMBER(<decimal-string>), resultSet.getString(<decimal-column>)
          Default: "#,##0.##"

      - phoenix.mutate.maxSize:
          Help: |
            commit或rollback前,一次批量处理的最大的行数
          Type: Integer
          Default: 500000

      - phoenix.mutate.batchSize:
          Help: |
            自动提交时。一次批处理的数量,这个参数会被 connect 参数 UpsertBatchSize 覆盖。注意,当这 UPSERT SELECT or DELETE 在服务器使用 coprocessor 执行时。connect参数对bathcsize无效
          Type: Integer
          Default: 1000

      - phoenix.coprocessor.maxServerCacheTimeToLiveMs:
          Help: |
            服务器缓存的最大存活时间(毫秒)。从最后一次访问到现在的过期时间。当服务器端发生 IOException(“Could not find hash cache for joinId”) 时,可以考虑调整这个参数。当服务器端 有像“Earlier hash cache(s) might have expired on servers”这样的警告时,就是一个调大这个参数的信号。
          Type: Integer           
          Unit: Milliseconds
          Default: 30000

      - phoenix.query.useIndexes:
          Help: |
            查询时是否作用索引
          Type: Boolean
          Default: true

      - phoenix.index.mutableBatchSizeThreshold:
          Help: |
            批处理中的突变数量,超过此数量,索引元数据将作为单独的RPC发送到每个区域服务器,而不是包含在每个突变的内联中。默认为 5。
          Type: Integer
          Default: 5

      - phoenix.schema.dropMetaData:
          Help: |
            删除一张phoenix表时,是否删除对应的Hbase表。默认是True
          Type: Boolean
          Default: true

      - phoenix.groupby.spillable:
          Help: |
            在 regionServer 上 是否一个大量不重复的数据是否允许溢出到磁盘上(Group By 也不例外)。为False时,抛出 InsufficientMemoryException
          Type: Boolean
          Default: true

      - phoenix.groupby.spillFiles:
          Help: |
            溢出文件的数量( Number of memory mapped spill files to be used when spilling GROUP BY distinct values to disk. Default is 2)
          Type: Integer
          Default: 2

      - phoenix.groupby.maxCacheSize:
          Help: |
            groupBy 溢出时最大的缓存字节数。默认是100MB
          Type: Integer
          Unit: Bytes
          Default: 102400000

      - phoenix.groupby.estimatedDistinctValues:
          Help: |
            当一个group by执行时预估的不同值的数量,( Used to perform initial sizing with growth of 1.5x each time reallocation is required)
          Type: Integer
          Default: 1000

      - phoenix.distinct.value.compress.threshold:
          Help: |
            使用聚合函数时。跟踪的不同值数量的阈值。超过这个数量后就会使用 Snappy 压缩,默认是1MB
          Type: Integer
          Unit: Bytes
          Default: 1024000

      - phoenix.index.maxDataFileSizePerc:
          Help: |
            共享索引表MAX_FILESIZE对于数据表MAX_FIELSIZE的百分比。这个值应该根据索引行和数据行的预计平均大小来估算,默认是50%
          Type: Integer
          Unit: Percentage
          Default: 50

      - phoenix.coprocessor.maxMetaDataCacheTimeToLiveMs:
          Help: |
            服务器端元数据缓存的过期时间。默认是30分钟。单位:毫秒
          Type: Integer           
          Unit: Milliseconds
          Default: 180000

      - phoenix.coprocessor.maxMetaDataCacheSize:
          Help: |
            服务器端最大的元数据字节数。如果超过这个值。就会根据最后访问时间来删除一些数据。默认是20MB
          Type: Integer
          Unit: Bytes
          Default: 20480000

      - phoenix.client.maxMetaDataCacheSize:
          Help: |
            客户端最大的元数据字节数。如果超过这个值。就会根据最后访问时间来删除一些数据。默认是10MB
          Type: Integer
          Unit: Bytes
          Default: 10240000

      - phoenix.sequence.cacheSize:
          Help: |
            在下一个序列值被分配时,从服务器和缓存中保留的序列值的数目。在序列自己定义时这个参数无效(猜测:这个是主键的生成策略)。默认为100
          Type: Integer
          Default: 100

      - phoenix.clock.skew.interval:
          Help: |
            打开系统时的延迟间隔(毫秒)。目录,以补偿可能的时间时钟偏差时,系统。目录在区域服务器之间移动。
            Delay interval(in milliseconds) when opening SYSTEM.CATALOG to compensate possible time clock skew when SYSTEM.CATALOG moves among region servers.
          Type: Integer           
          Unit: Milliseconds
          Default: 2000

      - phoenix.index.failure.handling.rebuild:
          Help: |
            当数据发生变化时,索引是否自动重建。默认是 True
          Type: Boolean
          Default: true

      - phoenix.index.failure.handling.rebuild.interval:
          Help: |
            索引重建后。检查下一次重建的时间间隔(毫秒)
          Type: Integer
          Unit: Milliseconds
          Default: 10000

      - phoenix.index.failure.handling.rebuild.overlap.time:
          Help: |
            索引失效后到索引重建的时间间隔(毫秒)。这个参数是为了防止。存在 time clock skew 的更新丢失。
          Type: Integer
          Unit: Milliseconds
          Default: 300000

      - phoenix.query.rowKeyOrderSaltedTable:
          Help: |
            对于salted表。非聚合函数总是返回以rowkey排序的数据。为true时,在表创建时,分割点可以先不指定,但就会在每个salt bucket使用默认的分割。默认是 True
          Type: Boolean
          Default: true

      - phoenix.connection.autoCommit:
          Help: |
            是否自动提交。对于所有连接有效。默认是 False
          Type: Boolean
          Default: false

      - phoenix.spool.directory:
          Help: |
            数据量到20MB(phoenix.query.spoolThresholdBytes )溢出到本地目录
          Type: Path
          Default: /tmp

      - phoenix.query.scanResultChunkSize:
          Help: |
            一次查询返回的批量数量	2999
          Type: Integer
          Default: 2999

就写到这里吧。运维很累的。换换脑子,该写点程序了!

如果开发程序,对 HBase+PhoenixDB 进行操作,有2种方式:

1)使用 query server,这是一个 http 服务,通过这个服务操作 phoenixdb。服务的源代码:

https://github.com/apache/phoenix-queryserver

jar包:

https://mvnrepository.com/artifact/org.apache.phoenix/phoenix-queryserver/5.0.0-HBase-2.0

用法参考下面的:

https://www.dazhuanlan.com/2019/11/28/5ddf5066c0578/

2)使用 JDBC 标准驱动。建自己的 java 项目,引入 jar 包:

https://mvnrepository.com/artifact/org.apache.phoenix/phoenix-core/5.1.1

然后可以使用 springboot + MyBatis 什么的做库表捆绑映射,或者直接写代码操作 JDBC API。参考:

https://www.itdaan.com/blog/2017/11/29/7a2c4458931a0743782490c10ea0b4c0.html

https://www.hangge.com/blog/cache/detail_2988.html

如果仅仅做个  http 接口,那就直接采用 1)吧,毕竟车轮子不是谁都可以造的出来的。

如果开发一个产品,库表结构和查询基本都是可以预知的,例如  Flink 之类的实时任务,那么采用2)比较合适,不需要那么通用,JDBC 也足够快。

 

 

以上是关于HBase 高可用集群整合 Phoenix 配置的主要内容,如果未能解决你的问题,请参考以下文章

大数据高可用集群环境安装与配置(07)——安装HBase高可用集群

HBase 高可用集群配置

HBase 高可用集群配置

Hbasehbase和phoenix的整合

最新Hadoop-2.7.2+hbase-1.2.0+zookeeper-3.4.8 HA高可用集群配置安装

hadoop集群高可用的配置以及hbase的环境配置