分享

phoenix集成hbase后,插入hbase数据,如何通过phoenix查询

问题导读

1.hbase插入数据后,为何phoenix不能识别?
2.phoenix索引是如何组成的?
3.如何通过API实现?


问题描述:

用户访问的数据接口直接走Phoenix,Phoenix的表是映射hbase产生,Phoenix的表会建很多索引,这时候问题就出现了,正常通过接口直接写数据进Phoenix表,相应的索引表也是会更新的,但是直接写数据到底层hbase表,这时候对应的索引表是不会更新,从而影响正常的用户访问

直接通过API把数据写入Phoeinx是正常的,如下图:
1.png


直接写数据到Hbase,索引是不会更新的,如下图:

2.png


解决:
如果数据是直接写进Hbase的,数据写进主数据表的时候,往索引表也写一份,这样,外部接口访问Phoenix的数据就正常了,如图:

3.png


这里说一下索引表的数据该怎么写:

这是我在phoenix里建的索引表,表字段如下
4.png



对应Hbase的表如下:
5.png

这时候会发现:

phoenix的索引表会把所有索引字段+ID拼接起来写进Hbase ,做为RowKey

格式:name\x00ID

所以我们写数据进索引表就很简单了,我们插入主表数据的同时,把相应索引字段拼接起来插进索引表

举例:

1、先插一条数据到住表nt_member这里测试,我只插两个字段,一个ID,一个name

6.png

2、 这时候去Phoenix查主表数据如下:

7.png

索引表数据如下:

8.png

结果:索引表没更新,主表也查不到这条数据

3、往Hbase对应索引表插一条数据

9.png

(备注:注意,这里rowkey是双引号,如果是单引号会把‘\’转译掉,插入的数据就不对了)

4、 再次查询Phoenix表

先看索引表:                           

10.png

数据进来了

再看主表:
11.png

数据也能查到了

备注:其实数据在我们第一步做完之后,就已经进主表了,只是因为我们没有更新索引表,导致我们在Phoenix中的查询只要命中了那条没有更新的索引,查出来的数据就是有误的

API操作hbase
最后:操作起来很简单,就是插rowkey中的\x00的时候要注意方式,下面是java调API往Hbase表里插\x00的一个例子:

由于场景需要,需要向hbase中插入包含‘\x00’的rowkey,例:
1.png
起初以为直接以拼接字符串的形式往里插就可以,但是读源码发现hbase会对\做二进制转译,如下:

2.png
‘\’会被转译为\x5c

解决办法:我们在插入数据的时候直接以byte[] 的形式往hbase表插,代码如下:


public class Test_DESC {


    public static void main(String[] args) throws IOException {

        System.setProperty("spark.serializer", "org.apache.spark.serializer.KryoSerializer");
        System.setProperty("hadoop.home.dir", "C:\\hadoop-2.6.0-cdh5.11.0");
        Configuration hbaseConf = HBaseConfiguration.create();
        hbaseConf.set("hbase.zookeeper.quorum","zt01:2181,zt02:2181,zt03:2181");
        HTable htabe = new HTable(hbaseConf,"INDEX_SDC_TEST");
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        byte[] a = Bytes.toBytes("hello");


        byte b = (byte) 0;

        byte[] c = new byte[] {b};
        byte[] d = Bytes.toBytes("999");
        byte[] e = ArrayUtils.addAll(a,c);
        byte[] indexColumnKey1 = ArrayUtils.addAll(e,d);

        Put put = new Put(indexColumnKey1);
        put.add(Bytes.toBytes("0"), Bytes.toBytes("_0"), Bytes.toBytes("x"));
        htabe.put(put);
    }

}

最新经典文章,欢迎关注公众号



作者:TracyGao01
来源:CSDN
原文:https://blog.csdn.net/u012551524/article/details/79575632
版权声明:本文为博主原创文章,转载请附上博文链接!





已有(4)人评论

跳转到指定楼层
Jackson_hrdG2 发表于 2019-6-28 22:14:32
请问一下,byte存储到Phoenix后,在shell端怎么直接查询呢?
回复

使用道具 举报

s060403072 发表于 2019-6-29 06:49:02
Jackson_hrdG2 发表于 2019-6-28 22:14
请问一下,byte存储到Phoenix后,在shell端怎么直接查询呢?

直接查询二进制会遇到什么问题?
回复

使用道具 举报

琅琊榜尾 发表于 2019-8-8 23:52:09
你好,请问,有遇到Phoenix查询或者spark sql加载数据会有部分字段读取不出来的情况么?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条