本文主要介绍在压测HBase的二级索引phoenix时踩的一个坑,使用时需要特别注意,而且背后的原因也很有意思,可以看出HBase和Phoenix对元数据设计上的差异。

1.问题介绍

在做phoenix压测时发现一个奇怪的现象。

压测请求分布非常均匀,但是有一台机器的流量、负载都明显高于其他机器。

如下图所示。

请求均匀

资源利用率不均匀,单个节点明显偏高。

2.排查思路

看到这个问题的第一反应,是去看下表分布是否均匀。

  • hbase表分布是否均匀
  • 索引表分布是否均匀

令人遗憾的是,确认后hbase表和索引表都是均匀分布的,各个机器上的region数量、存储用量都是一致,非常均匀。

然后在网上查相关资料,在官网上看到这样一段描述。(http://phoenix.apache.org/language/index.html)

UPDATE_CACHE_FREQUENCY option (available as of Phoenix 4.7) determines how often the server will be checked for meta data updates (for example, the addition or removal of a table column or the updates of table statistics). Possible values are ALWAYS (the default), NEVER, and a millisecond numeric value. An ALWAYS value will cause the client to check with the server each time a statement is executed that references a table (or once per commit for an UPSERT VALUES statement). A millisecond value indicates how long the client will hold on to its cached version of the metadata before checking back with the server for updates.

大致的意思是,phoenix的表设计时有一个表级别参数UPDATE_CACHE_FREQUENCY,这个参数默认是ALWAYS,表示每次sql查询都会先去请求meta数据。也可以设置为一定频率,表示多久去请求一次meta数据。

那我们大概能猜想到了,因为设计表的时候没有指定这个参数,所以为默认的always,而phoenix的meta数据正好落在了那个机器上。

我们查验了下系统表的位置,果然如此!

于是立刻做了变更

alter table xxx set UPDATE_CACHE_FREQUENCY = xxxxx。

  效果显著!

不仅流量、负载均匀了,而且整体负载下降了很多!!!

那为什么监控上请求量是均匀的呢?因为phoenix需要访问catalog表,然后这个表刚才在core-2上,访问这个表走的coprocessor,所以没统计出请求数。

3.进一步思考

到上面为止,问题的原因找到了,也解决了。

但是熟悉HBase的同学肯定会马上有个疑问,跟我一样。为什么会有这样一个参数设置,HBase本身也有meta表,而HBase的meta表在客户端缓存就可以。

下面,就让我们来思考下。

1)phoenix为什么要这么设计呢,而不是像hbase的meta表一样?

这个问题得从phoenix的架构设计说起。

phoenix一直以来,都是重客户端模式,即使是现在的轻客户端版本,本质也是如此。只不过把客户端放在了query server这个角色上,让query server跑在服务端了。

但对hbase来说,phoenix的核心逻辑都在client侧。元数据管理也是如此。phoenix和HBase不同的是,phoenix的元数据更复杂,如果元数据有变化,没有拿到最新meta的客户端不一定会抛错。

举个例子,比如一个查询命中索引后会更高效。但是,某个客户端它 不知道有这个索引表,于是就去查了主表,这个在phoenix上看也没有毛病。

所以,关键原因是phoenix无法感知元数据是否发生了变化!而HBase可以。

因此,最初为了解决元数据同步的问题,就采用了比较激进的每次刷新的方式。后来发现会影响性能,就加了一个周期性刷新的功能,来避免per request去刷meta数据。

2)那可以alter table时触发meta更新吗?

这个是不可以的。因为客户端可能比较多。而且,也不会有一个地方去记录全局有哪些client。即使有这样一个地方,那某个client挂了怎么办?没有通知成功怎么办?此时,alter操作是成功还是不成功呢?

3)结论

所以这个参数是phoenix的设计,而不是缺陷。phoenix默认情况下,每个请求都会去校验一次表的元数据信息,以避免因meta未刷新导致失败。为此,phoenix提供了一个表参数,来控制meta的刷新频率,比如1分钟刷一次,类似这种。

可以在建表的时候设定:

craete table if not exists ns.table_demo (
id varchar not null primary key,
f1.a varchar,
f1.b varchar,
f1.c varchar
)
TTL=86400,
UPDATE_CACHE_FREQUENCY=900000;

也可以变更表结构设定:

alter table xxx set UPDATE_CACHE_FREQUENCY = xxxxx; 

设一个你期望的刷新时间,就可以解决问题了。

当然,这样带来的副作用就是,如果未来你修改了这个表,比如add了一个新的列,或者新加了一个索引,最少要等待一个刷新周期才能生效。但是无关大局,一般表结构变更就属于低频操作,而且能够接受一定延迟。

看到这里了,原创不易,点个关注、点个赞吧,你最好看了~

知识碎片重新梳理,构建Java知识图谱:https://github.com/saigu/JavaKnowledgeGraph(历史文章查阅非常方便)

使用phoenix踩的坑与设计思考的更多相关文章

  1. 一次flume exec source采集日志到kafka因为单条日志数据非常大同步失败的踩坑带来的思考

    本次遇到的问题描述,日志采集同步时,当单条日志(日志文件中一行日志)超过2M大小,数据无法采集同步到kafka,分析后,共踩到如下几个坑.1.flume采集时,通过shell+EXEC(tail -F ...

  2. Phoenix踩坑填坑记录

    Phoenix踩坑填坑记录 Phoenix建表语句 如何添加二级索引 判断某表是否存在 判断索引是否存在 Date类型日期,条件判断 杂项 记录Phoenix开发过程中的填坑记录. 部分原文地址:ph ...

  3. 使用CCNode作为容器容易踩的坑

    Cocos2dx中CCNode经常作为一个父容器,里面装一些UI控件,最后组成一个复杂的自定义的UI控件,但是在使用别人的自定义控件和自己写自定义问题的时候会踩一些坑. 首先拿到一个自定义的UI控件一 ...

  4. Asp.Net Core中使用Swagger,你不得不踩的坑

    很久不来写blog了,换了新工作后很累,很忙.每天常态化加班到21点,偶尔还会到凌晨,加班很累,但这段时间,也确实学到了不少知识,今天这篇文章和大家分享一下:Asp.Net Core中使用Swagge ...

  5. java基础不牢固容易踩的坑

    java基础不牢固容易踩的坑 经过一年java后端代码以及对jdk源码阅读之后的总结,对java中一些基础中的容易忽略的东西写下来,给偏爱技术热爱开源的Coder们分享一下,避免在写代码中误入雷区. ...

  6. 从零开始学 Java - Spring 支持 CORS 请求踩的坑

    谁没掉进过几个大坑 记得好久之前,总能时不时在某个地方看到一些标语,往往都是上面一个伟人的头像,然后不管是不是他说的话,下面总是有看起来很政治正确且没卵用的屁话,我活到目前为止,最令我笑的肚子痛得是下 ...

  7. 用thinkphp进行微信开发的整体设计思考

    用thinkphp进行微信开发的整体设计思考 http://www.2cto.com/weixin/201504/388423.html 2015-04-09      0个评论       作者:明 ...

  8. webuploader插件,我踩得坑

    我在目前的公司做的项目要么是原生写法去做项目,要么就是vue+webpack做项目,但是vue这部分只是用了模板template,vue其他的都没用. 有一个项目需要做上传图片的功能,老大扔给我一个插 ...

  9. 谈谈调用腾讯云【OCR-通用印刷体识别】Api踩的坑

    一.写在前面 最近做项目需要用到识别图片中文字的功能,本来用的Tesseract这个写的,不过效果不是很理想. 随后上网搜了一下OCR接口,就准备使用腾讯云.百度的OCR接口试一下效果.不过这个腾讯云 ...

随机推荐

  1. udp包最大数据长度是多少

    因为udp包头有2个byte用于记录包体长度. 2个byte可表示最大值为: 2^16-1=64K-1=65535    udp包头占8字节, ip包头占20字节, 65535-28 = 65507 ...

  2. java学习(第五篇)包装类

    一.Integer package com.test01; public class IntegerTest01 { public static void main(String[] args) { ...

  3. QT QLabel内容太长时候使用省略号

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/xiezhongyuan07/articl ...

  4. Zabbix CPU utilization监控参数

    工作中查看Zabbix linux 监控项的时候对linux 监控的cpu使用的各个参数没怎么明白,特意查看了下资料 Zabbix linux模板下的CPU utilization是自带的监控Linu ...

  5. HTML中使用CSS样式(下)

    上节内容回顾加补充: 补充:默认img标签,有一个1px的边框 如果点击图片跳转到连接,a标签下套img标签,在IE有的版本中,会有蓝色边框. <a href="http://blog ...

  6. javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake

    2019独角兽企业重金招聘Python工程师标准>>> 问题 前两天一个学弟在群里面问一个问题: 请问一下用阿里云服务器发送https请求为什么会失败,是需要有些其他什么配置吗? 同 ...

  7. 11.25-11.27 配置防盗链,访问控制(Directory,FilesMatch)

    4月17日任务 11.25 配置防盗链 11.26 访问控制Directory 11.27 访问控制FilesMatch 扩展 几种限制ip的方法 http://ask.apelearn.com/qu ...

  8. Joomla CMS 3.2-3.4.4 SQL注入 漏洞分析

    RickGray · 2015/10/26 11:24 昨日,Joomla CMS发布新版本3.4.5,该版本修复了一个高危的SQL注入漏洞,3.2至3.4.4版本都受到影响.攻击者通过该漏洞可以直接 ...

  9. angularJS中$http.get( ).success( )报错原因及解决方案

    一.问题描述: 电脑安装的angular1.6.7版本,项目中使用了$http.get( ).success( ),控制台报错: $http.get(...).success is not a fun ...

  10. java基于socket的网络通信,实现一个服务端多个客户端的群聊,传输文件功能,界面使用Swing

    最近在复习java的io流及网络编程.但复习写那些样板程序总是乏味的.便准备写个项目来巩固.想来想去还是聊天项目比较好玩.如果日后完成的比较好自己也可以用(哈哈哈).并且自己后面也要继续巩固java多 ...