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 居然没有携带):
将下面的配置段加入到全部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高可用集群