Phoenix 技术分享

目录

1. Phoenix 安装

2.Phoenix 升级

3. phoenix 依赖打包方式

4. 二级索引使用

5. 优化

6. 事务处理

7. 数据更新



1. Phoenix 安装

1.1)Maven 编译

从如下地址获取相应版本源码 https://github.com/chiastic-security/phoenix-for-cloudera/tree/4.9-HBase-1.2-cdh5.9(这个是最高的版本)
根据需要修改pom.xml中<version>4.9.0-cdh5.9.1</version>改为需要的版本
此处改为了<version>4.9.0-cdh5.10.0</version>
编译
mvn clean package -DskipTests
复制jar包 cp phoenix-assembly\target\phoenix-4.9.0-cdh5.10.0.tar.gz 到合适目录后,解压

1.2)phoenix和spark整合:

在spark-conf/spark-env.sh中配置

SPARK_DIST_CLASSPATH="$SPARK_DIST_CLASSPATH:/opt/cloudera/phoenix-4.9.0-cdh5.10.0/phoenix-4.9.0-cdh5.10.0-client.jar"
export SPARK_YARN_USER_ENV="CLASSPATH=$HADOOP_CONF_DIR"

1.3)phoenix 二级索引需要的配置

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

1.4)phoenix 4.9 中使用 schema 和 Namespace 对应的配置

<property>
<name>phoenix.schema.isNamespaceMappingEnabled</name>
<value>true</value>
</property>
<property>
<name>phoenix.schema.mapSystemTablesToNamespace</name>
<value>true</value>
</property>

2. Phoenix 升级

2.1)解压文件夹
2.2)创建软连接

  ln -s /etc/hbase/conf/hbase-site.xml  phoenix-4.9.0-cdh5.10.0/bin/hbase-site.xml

2.3)修改spark-conf/spark-env.sh中phonix client配置 (参考安装模块)
2.4)将phoenix-4.9.0-cdh5.10.0 /目录下phoenix-*.jar包复制到hbase的lib目录下
2.5)备份system.catalog和system.mutx,然后删除即可
2.6)重启Hbase
2.7)测试链接 sqlline.py
2.8)表转换 bin/psql.py localhost -m TEST_MERGE_APP.WHALE_USER
这样将会产生一个namespace TEST_MERGE_APP,并把WHALE_USER
表放到这个namespace下面,实现namespace之间的隔离,便于管理和提高读写
注意:升级要一级一级的升级,否则会报错!!!

3. phoenix 依赖打包方式

3.1)点击 File-> Project-structure -> Modules -> common -> Dependencies -> 右面的+ 号 -> JARs or directories -> 添加 phoenix-4.9.0-HBase-1.2-client.jar ->去掉 此jar包中的 shade模块-> 选择 compile -> apply -> ok
3.2)点击 File-> Project-structure -> Artifacts -> + 号 -> JAR -> from modules with dependencies -> apply -> ok
3.3)Build -> make modules ‘common’ -> Build Artifacts -> common:jar -> build
3.4)在工程 根目录下的classes下找到 common.jar 上传到 /home/bigdataservice/service/statistic-1.4.0.1/batch/lib/
3.5)zip -d common.jar META-INF/.RSA META-INF/.DSA META-INF/*.SF
3.6)mv common.jar common-1.0.jar
说明:为了去除shade模块,因为这个里面的zookeeper和spark-streaming中的zookeeper会冲突

4. 二级索引使用

4.1)Covered Indexes

创建方式:

CREATE INDEX my_index ON my_table (v1,v2) INCLUDE(v3)

应用场景:提高读效率
原理:数据插入、更新时,以v1,v2为基础建立索引,同时copy v3到索引。
使用索引方式:

SELECT v3 FROM my_table WHERE v1 = ‘d’ and v2=‘h’

4.2)Functional Indexes

创建方式:

CREATE INDEX UPPER_NAME_IDX ON EMP (UPPER(FIRST_NAME||' '||LAST_NAME))

应用场景:提高读效率,创建以函数为基础的索引
原理:数据插入或更新时,以函数为基础建立索引
使用索引方式:

SELECT EMP_ID FROM EMP WHERE UPPER(FIRST_NAME||' '||LAST_NAME)='JOHN DOE'

4.3)Global Indexes

创建方式:默认创建方式即是Global方式
应用场景:最大限度提高读效率
原理:数据插入或更新时, Index是多个表,SALT_BUCKETS参数能改变,插入时会消耗大量性能。下面是官方解释:
build the index update and then sent any necessary updates to all interested index tables. At read time, Phoenix will select the index table to use that will produce the fastest query time
使用索引方式:
查询和过滤的列必须都在Index中

4.4)Local Indexes

创建方式:

CREATE INDEX UPPER_NAME_IDX ON EMP (UPPER(FIRST_NAME||' '||LAST_NAME))

应用场景:写入最快的索引,Index数据最少,读性能也有所提升(经测试千万级表提升了10倍左右)
原理:数据插入或更新时,以建立索引,索引数据和表数据在每个RegionServer上同时存在。比如表有20个Region,分布在5个RegionServer上,在RegionServer1上的Region和Index是一一对应的。并且Index是一个独立的表, SALT_BUCKETS参数不能改变
使用索引方式:
查询和过滤的列不必须都在Index中
工作机制详解:
https://github.com/Huawei-Hadoop/hindex/blob/master/README.md#how-it-works

4.5)异步创建

使用场景:表数据非常大时
步骤:
1)phoenix命令:

CREATE INDEX ASYNC_IDX ON my_schema.my_table (v) ASYNC

2)MapReduce任务触发

${HBASE_HOME}/bin/hbase org.apache.phoenix.mapreduce.index.IndexTool
  --schema MY_SCHEMA --data-table MY_TABLE --index-table ASYNC_IDX
  --output-path ASYNC_IDX_HFILES

说明: output-path是存储在HDFS上的路径;任务执行完成后,Index才能提供服务。

4.6)数据一致性

1)原表是事务表
原理介绍:
要求表和索引最高的一致性,表更新和索引更新是强制的ACID。
2)原表是不可变的
创建方式:

CREATE TABLE my_table (k VARCHAR PRIMARY KEY, v VARCHAR) IMMUTABLE_ROWS=true

原理介绍:表数据一旦写入,很少会更新,但也不是一定不能再更新。
不能保证一致性,除非声明是global,且保证客户端能重复发送失败的更新直至成功。
3)原表是非事务性的可变表
原理介绍:如果要实现强一致性,
要保证WAL启用,
在server端配置下面配置

phoenix.index.failure.block.write   true
phoenix.index.failure.handling.rebuild true

5. 优化

5.1)自带优化:把计算在服务端完成

1)coprocessors 计算放在服务端
2)custom filters 计算和数据尽量在同一个位置

5.2)多个Column Family

作用:当过滤条件和返回数据分别属于两个CF时,过滤时加载一个CF,返回数据时再加载另一个CF,可以提高查询效率
Eg: 创建表:create table t (k varchar not null primary key, a.c1 integer, b.c2 varchar, b.c3 varchar, b.c4 varchar).
查询数据:select count(c2) from t where c1 = ?
原理:因为Hbase中表是按照CF进行划分Region的,故把表中列按照需要划分到多个CF,可以提高一定的性能

5.3)预处理

1)原理:Salting in Phoenix leads to both improved read and write performance by adding an extra hash byte at start of key and pre-splitting data in number of regions. This eliminates hot-spotting of single or few regions servers.
2) 创建语句:

CREATE TABLE T (HOST CHAR(2) NOT NULL,DOMAIN VARCHAR NOT NULL, FEATURE VARCHAR NOT NULL,DATE DATE NOT NULL,USAGE.CORE BIGINT,USAGE.DB BIGINT,STATS.ACTIVE_VISITOR INTEGER CONSTRAINT PK PRIMARY KEY (HOST, DOMAIN, FEATURE, DATE)) SALT_BUCKETS = 4.

注意:最好的SALT_BUCKETS 个数是和RegionServer个数一样。Salting会影响查询效率,因为在查询时会启用和SALT_BUCKETS 一样多的Query

5.4)压缩和数据块编码

1)在compaction时触发;两者都是以CF为单位,可以同时作用在一个CF上
( compaction 可以设置成定时的,避免资源不够用)
2)CDH支持的压缩 none,gz,lz4, snappy.不需要安装lib
测试方法:
hbase org.apache.hadoop.hbase.util.CompressionTest hdfs://tagticHA/test/hbase-com snappy 测试时压缩格式小写
3)数据块编码类型介绍
Key:RowKey:Family:Qualifier
Prefix
原理:增加一列用来记录当前key和前一条key前面共同的字符
使用场景:key很接近,share a common prefix and only differ near the end

1.没有使用Prefix
这里写图片描述

2.使用Prefix
这里写图片描述

Diff
原理:是Prefix的扩展,把key分割成相应的field,另外增加了两个timestamp and type,对每一个field进行压缩。但是这种压缩格式是默认关闭的,因为它会影响读写和增大内存使用。
这里写图片描述

Fast Diff
原理:和Diff类似,但是比Diff快,hbase默认是这种编码
Prefix Tree
实验阶段,官方解释在和上面3种一样使用内存的情况下,能够提供更快速的随机访问
具体数据结构,参考 https://en.wikipedia.org/wiki/Trie
4)使用方法
压缩格式
修改
disable ‘test’
alter ‘test’, {NAME => ‘cf’, COMPRESSION => ‘snappy’}
enable ‘test’
新建
create ‘test2’, { NAME => ‘cf2’, COMPRESSION => ‘snappy’}使用时压缩格式大小写都行

数据块编码
disable ‘test’
alter ‘test’, { NAME => ‘cf’, DATA_BLOCK_ENCODING => ‘FAST_DIFF’ }
enable ‘test’
查看
!desc 'test ‘
5)压缩格式的选择:

1.在空间大小和压缩/解压耗时之间进行权衡
2.key比较长,或者列比较多,推荐使用 Prefix或Fast Diff
3. GZ 压缩用在冷数据处理,压缩比高,占用CPU高;snappy和lz4用 于热数据处理,压缩比没GZ高,占用CPU没GZ高。

5.5、Primary Keys 设计

1)创建时,按照查询的需要设计,按照过滤数据的级别从左到右排列组成一个Row Key组合
2)查询时,按照PK的顺序来排列条件

5.6、建议:

1)随机读取建议使用SSD硬盘
2)读数据压力大用Global Index
3)写数据多用Salting和Local Index
4)数据不变,用immutable(表和索引都可以设置)
5)速度比准确性要求高时,可以DISABLE_WAL
6) PK 尽量小,因为它会保存在一行数据的每个列中,总的来看hbase 表就是一个多维的 Map
7)把相同业务或者相同查询频率的列放到一个CF中,多个CF可以提高查询效率
8)结构化数据不要用json,因为它的压缩不好,用protobuf, Avro, msgpack, or BSON
9)不要用join,除非一端很小
10) Filtering the first leing column with IN or OR in the WHERE clause enables skip scan optimizations
11)使用upsert来大量写数据时,关掉autocommit ,使用批处理

6. 事务处理

6.1.事务定义:

事务是一条或多条数据库操作语句的组合,具备ACID( Atomicity, Consistency, Isolation, Durability),4个特点。
原子性:要不全部成功,要不全部撤销
一致性:数据库正确地改变状态后,数据库的一致性约束没有被破坏
隔离性:事务之间相互独立,互不干扰
持久性:事务的提交结果,将持久保存在数据库中

6.2.启动步骤

1)客户端 hbase-site.xml中配置

<property>
  <name>phoenix.transactions.enabled</name>
  <value>true</value>
</property>

2)服务端配置

<property>
  <name>data.tx.snapshot.dir</name>
  <value>/tmp/tephra/snapshots</value>
</property>
<property>
  <name>data.tx.timeout</name>
  <value>60</value>
</property>

3)启动transaction manager

/opt/cloudera/phoenix-4.9.0-cdh5.10.0/bin/tephra

4)创建事务表

CREATE TABLE my_table (k BIGINT PRIMARY KEY, v VARCHAR) TRANSACTIONAL=true;
ALTER TABLE my_other_table SET TRANSACTIONAL=true;

(记得disable和enable操作)

6.3.处理机制

原理:和Tephra 整合,Tephra使用multi-versioned 实现 snapshot 隔离
处理过程:

ALTER TABLE my_other_table SET TRANSACTIONAL=true;
SELECT * FROM my_table; -- This will start a transaction
UPSERT INTO my_table VALUES (1,'A');
SELECT count(*) FROM my_table WHERE k=1; -- Will see uncommitted row
DELETE FROM my_other_table WHERE k=2;
!commit -- Other transactions will now see your updates and you will see theirs

冲突:
如果事务尝试提交与已经提交还没有处理的其他事务冲突,则抛出异常

UPSERT INTO my_table VALUES (1,'B');
!commit
UPSERT INTO my_table VALUES (1,‘A’);  

此语句抛出异常
注意:表数据的版本限制会限制Tephra的版本数

###7. 数据更新
1. 使用ON DUPLICATE KEY,如果你想更新是原子性的
2.使用IGNORE,如果你只想插数据,不想更新数据
Eg:
更新

UPSERT INTO my_table(id, counter1, counter2) VALUES ('abc', 0, 0)
ON DUPLICATE KEY UPDATE counter1 = counter1 + 1, counter2 = counter2 + 1;

插入

UPSERT INTO my_table(id, my_col) VALUES ('abc', 100)
ON DUPLICATE KEY IGNORE;

注意:事务表或不可变表不会启用上述配置

北京小辉微信公众号

在这里插入图片描述

大数据资料分享请关注
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辉哥大数据

你的鼓舞将是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值