调优
Phoenix和hbase适用点查询和小范围scan,能够通过primary key实现。如果是很多全表扫描,不能很好的处理。可能用列式存储格式,如Parquet
Primary Keys:是Phoenix加工的一个重要因素,除非重写Data和Index外,不能被修改。与Hbase的row
key相关。primary key constraint的columns 的选择和顺序应该与通用的查询模式一致 -- 选择最高
频查询的columns作为primary key.可以把timestamp加到primary key中,去提高scan效率--能跳过查询时间之外的row primary key实际就把全部的row key 追加到每片在memory and disk数据中.如用数字代
替timestamp如果 sum,把累加对象设置为row key,只需scan少量的数据。
monotonically increasing Primary Keys : 提高分布式写和并行化,但是会降低读的效率
CREATE TABLE () SALT_BUCKETS = N
N 与 regionServer数量相同
通常考虑点:
1、数据是随机读取?
SSD能够加快随机读取
2、数据是否多写多读?
多读:
创建大量index。将影响写的columns的速度,每个index单独写自己表。
创建复合index。
增加cores
多写:
Pre-splite table + salt : avoid 热点数据。使用 real data types 而不是 raw byte data type.
创建本地索引。
3.哪些列通常被访问
创建额外的index
4.数据是否只追加(不可改变)
如果数据是不可变或者只可追加。定义表和它的索引不可变 IMMUTABLE_ROW 项
alter trans.event set IMMUTABLE_ROWS = true 在创建表后。
如果写的速度比较数据的完整性重要,可以使用 DISABLE_WAL
UPDATE_CACHE_REQUENCY = 15minutes如果 metadata 不常改变。
如果超过50% 的cell 有值。 SINGLE_CELL_ARRAY_WITH_OFFSET ,这个配置能减少数据的size,来加快执行效率
5、表是否很大
使用 创建异步索引,需要手动设置 https://phoenix.apache.org/secondary_indexing.html#Index_Population for details.
创建索引,
6、是否需要事务
If you need transactionality, use the TRANSACTIONAL option. (See also http://phoenix.apache.org/transactions.html.)
7. Block Encoding
必须使用压缩或者编码,SNAPPY和FAST_DIFF
FAST_DIFF encoding Phoenix创建的表默认是自动开启,
CREATE TABLE ... (...) DATA_BLOCK_ENCODING = 'FAST_DIFF'
Schema设置
Indexes
是一个物理表,存储主要表的部分或者全部关键数据,为了服务几类查询。primary key 默认会创建index
Secondary indexs
covered/functional index
如果是大表,可采用异步索引,会启动下mapreduce任务,客户端的连接或者下线不影响index的创建,任务是自动重试。
CREATE index of not exists event_object_id_idx_b on trans.event(object_id)
ASYNC UPDATE_CACHE_FREQUENCY=6000;
如果不能创建异步索引,增加查询超时时间,phoexix.query.timeoutMs ,
通过SYSTEM.STATS查看索引。 count(*)将加载更多的数据到系统。
创建本地索引 -- 多写
创建全局索引 -- 多读 为了节省读取时间,使用covered index
热点数据处理 使用 monotonically increasing,create salt bucket
创建异步索引 -- 避免阻塞
创建必要的索引
限制频繁更新表上的索引
使用covered index -- 把表的扫描变成 covered索引的 point lookup 或者 range
queries 而不是主表。 CREATE INDEX index on table (...) INCLUDE(...)
Queries
Reading
1.在频繁的查找中,避免 joins,除非一个join表是很小的。
2.where 字句中,过滤头字段采用主键
3.where 字句中,过渡头字段采用 in or可能使where字句开启不优化
4. = < > 在where字句中,会开启扫描优化
5. 使用统计能优化 Phoenix的并行查询,在4.2 or 以后自动提供
Range query
Large Range Queries
Scan.setCacheBlocks(false)
Point lookups
使用cache去处理
Hints
在查询时,强制使用全局index,当查询的column不包含索引时, /*+ USER_SORT_MERGE_JOIN */
如果右边的表超过内存限制大小,使用 /*+ NO_STAR_JOIN */
Expalin Plans
打印执行计划
Parallelization
使用 UPDATE STATISTICS 提高并行。这个命令会根据key再细分每个region,然后使用这个
guidepost去拆分查询至多个并行扫描。默认打开 statistics.
Statitics受 cluster大小,cluster usage,节点cores ,table size ,disk IO 影响
配置项 phoenix.use.stats.parallelization
Writing
Updating data witch UPSERT VALUES -- 注意设置commitSize()
使用UPSERT VALUES 写大量记录,关闭自动提交和合理的小批量记录。
driver.executeBatch()不是很有优势的,多次 UPDATE VALUES ,再commit()。executeBatch能够最小化 RPC调用在client和服务之间。
try(Connection conn = DriverManager.getConnection(url)){
conn.setAutoCommit(false);
int batchSize = 0;
int commitSize = 100
try(Statement stms = conn.prepareStatement(upsert)){
stmt.set .... while( there are records to upsert){
stmt.executeUpdate();
batchSize ++ ;
if(batchSize % commitSize == 0){
conn.commit();
}
}
conn.commit();
}
}
Updating data with UPSERT SELECT
autocommit
phoenxi.mutate.batchSize
Deleting data
当删除数据前,开启autocommit,因为client不需要记住需要删除的row的key.
Reducing RPC traffic
为了减少RPC调用 set UPDATE_CACHE_FREQUENCY 在表和索引上,
Using local indexs
4.8 release ,