前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一次PHP Hive客户端协议问题分析

一次PHP Hive客户端协议问题分析

作者头像
桶哥
发布2019-06-04 18:21:09
9960
发布2019-06-04 18:21:09
举报
文章被收录于专栏:PHP饭米粒PHP饭米粒

原起

由于项目需要使用hive client,我们就找了hive的php版本的client,首先看一段网上找的demo

<?php
// set THRIFT_ROOT to php directory of the hive distribution
$GLOBALS['THRIFT_ROOT'] = '/lib/php/';
// load the required files for connecting to Hive
require_once $GLOBALS['THRIFT_ROOT'] . 'packages/hive_service/ThriftHive.php';
require_once $GLOBALS['THRIFT_ROOT'] . 'transport/TSocket.php';
require_once $GLOBALS['THRIFT_ROOT'] . 'protocol/TBinaryProtocol.php';
// Set up the transport/protocol/client
$transport = new TSocket('localhost', 10000);
$protocol = new TBinaryProtocol($transport);
$client = new ThriftHiveClient($protocol);
$transport->open();

// run queries, metadata calls etc
$client->execute('SELECT * from src');
var_dump($client->fetchAll());
$transport->close();

然后在测试的时候出现了一个问题,使用下面的代码不能选择数据库。原因呢,是因为我们的hive使用sasl权限认证,服务端会默认给选择一个跟账号名一样的数据库,而且不能自由切换,这样就不能一个账号连接多个库了

$client->execute('use database');

似乎问题卡住了

剖析

万变不离其宗,即出大杀器,抓包对比看下

使用tcpdump抓了下beeline的数据包,然后和我们的数据包对比了下,发现在OpenSession请求时候的数据不一样。 下面是我们程序的数据包

0x0000:  4500 004f 500d 4000 4006 4c15 0a10 8584  E..OP.@.@.L.....
0x0010:  0aca 0429 b978 2710 c5c7 a509 4bdc bdae  ...).x'.....K...
0x0020:  5018 006f 9ec8 0000 0000 0023 8001 0001  P..o.......#....
0x0030:  0000 000b 4f70 656e 5365 7373 696f 6e00  ....OpenSession.
0x0040:  0000 000c 0001 0800 0100 0000 0700 00    ...............

下面是使用beeline命令行连接时的数据包

0x0000:  4500 0073 9cff 4000 4006 879c 0aca fc2c  E..s..@.@......,
0x0010:  0aca 0429 952c 2710 f919 1dbc 7e2d 48e8  ...).,'.....~-H.
0x0020:  5018 00e5 164f 0000 0000 0047 8001 0001  P....O.....G....
0x0030:  0000 000b 4f70 656e 5365 7373 696f 6e00  ....OpenSession.
0x0040:  0000 010c 0001 0800 0100 0000 070d 0004  ................
0x0050:  0b0b 0000 0001 0000 000c 7573 653a 6461  ..........use:da
0x0060:  7461 6261 7365 0000 0007 6861 776b 6579  tabase....hawkey
0x0070:  6500 00                                  e..

好像发现了什么? 少了一串东西吧,怎么办呢?

先看源码,源码中没看出来什么信息。

然后找了官方文档(java的文档),也没找到解决办法。只能上终极大招了

解析协议

一番搜寻,找到了Thrift协议的格式编码

消息类型重点说下

  1. 表示方式一:四个字节的版本(含调用类型),四个字节的消息名称长度,消息名称,四个字节的流水号,消息负载数据的值,一个字节的结束标记。
  2. 表示方式二:四个字节的消息名称长度,消息名称,一个字节调用类型,四个字节的流水号,消息负载数据的值,一个字节的结束标记。 对严格的thrift消息,必须包含32位版本信息。(从数据包中可以看出来使用的是包含32位版本信息的表达式一)若有32为版本信息,函数调用(请求:1,响应:2,异常:3,无返回值的请求:4)被包含到32为版本中,不独立出现。

看完后尝试解析,我打印了数据包的拼接过程,然后果然有惊喜,这个包使用的是表示方式一:

TSaslClientTransport:write 80010001 版本+消息类型(请求)
TSaslClientTransport:write 0000000b 消息名称长度
TSaslClientTransport:write 4f70656e53657373696f6e 消息名称
TSaslClientTransport:write 00000001 请求流水号
TCLIService_OpenSession_args:write 30
函数的第一个参数
TSaslClientTransport:write 0c 表示结构体TType.STRUCT = 12
TSaslClientTransport:write 0001 参数编号1
TSaslClientTransport:write 08 i32
TSaslClientTransport:write 0001 结构体元素编号1
TSaslClientTransport:write 00000007 值
TSaslClientTransport:write 00 结构体结束
TCLIService_OpenSession_args:write 3131
TSaslClientTransport:write 00 参数结束

结合代码,发现其中有个seqid,目前还不知道什么作用,不过不用关心,因为后面的数据都可以解释通了,然后对照beeline命令行的数据包(这里我格式化了,看起来更清晰)。

8001 0001  P....O.....G....
0000 000b ....
4f70 656e 5365 7373 696f 6e OpenSession
0000 0001 seqid
0c
0001
08
0001
0000 0007
0d 表示map TType.MAP = 13
0004 元素编号4
0b0b 表示 key:TType.STRING = 11 and val :TType.STRING = 11
0000 0001 map元素个数1
0000 000c key长度12
7573 653a 6461 7461 6261 7365 use:database key
0000 0007 val长度7
6861 776b 6579 65 hawkeye val
00 结构体结束
00 参数结束

然后所有的数据都可以解释通了,这是一个map,是OpenSession的结构体参数里面的第四个元素,然后结合代码。问题得以解决!其实就加一行代码就ok了!

关于需要sasl认证的代码我就不粘了,网上可以找到

$vals['configuration'] = ['use:database' => 'hawkeye']; //加这么一行代码
$sorq = new TOpenSessionReq($vals);

透过现象看本质,解决方案就是如此简单

----------伟大的分割线-----------

PHP饭米粒(phpfamily) 由一群靠谱的人建立,愿为PHPer带来一些值得细细品味的精神食粮!

饭米粒只发原创或授权发表的文章,不转载网上的文章

所发的文章,均可找到原作者进行沟通。

也希望各位多多打赏(算作稿费给文章作者),更希望大家多多投搞。

投稿请联系:

shenzhe163@gmail.com

本文由 李云飞 授权 饭米粒 发布,转载请注明本来源信息和以下的二维码(长按可识别二维码关注)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-03-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 PHP饭米粒 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档