zoukankan      html  css  js  c++  java
  • Python 操作 HBase —— Trift Trift2 Happybase 安装使用

    Python无法直接访问HBase,必须通过Thrift。

    HBase与Thrift之间又支持两种接口标准,两种标准互不兼容,功能也互不覆盖。

    Thrift连接HBase还有超时自动断开的大坑。

    • 安装Thrift依赖(Server端)

    Centos: yum install automake libtool flex bison pkgconfig gcc-c++ boost-devel libevent-devel zlib-devel python-devel ruby-devel openssl-devel

    Ubuntu: apt-get install libboost-dev libboost-test-dev libboost-program-options-dev libboost-system-dev libboost-filesystem-dev libevent-dev automake libtool flex bison pkg-config g++ libssl-dev

    • 安装Boost(Server端)

    可以尝试yum/apt-get安装libboost1.53(或其他版本),安装完尝试Thrift是否正常启动,如果无法安装或安装完版本不兼容则手动下载安装

    wget http://sourceforge.net/projects/boost/files/boost/1.53.0/boost_1_53_0.tar.gz

    tar xvf boost_1_53_0.tar.gz

    cd boost_1_53_0

    ./bootstrap.sh

    ./b2 install

    cp /usr/local/lib/libboost_unit_test_framework.a /usr/lib/

    • 修改文件(安装Thrift报错:error: ‘uintptr_t’ was not declared)

    vim /usr/local/include/boost/cstdint.hpp

    第43行左右,将上面语句屏蔽,更新为下面语句
    //#if defined(BOOST_HAS_STDINT_H) && (!defined(__GLIBC__) || defined(__GLIBC_HAVE_LONG_LONG))
    #if defined(BOOST_HAS_STDINT_H) 
        && (!defined(__GLIBC__) 
        || defined(__GLIBC_HAVE_LONG_LONG) 
        || (defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) 
        && (__GLIBC_MINOR__ >= 17)))))
    • 安装Thrift(Server端)

    从http://thrift.apache.org/下载最新版本的Thrift

    tar -xvf thrift-0.12.0.tar.gz

    cd thrift-0.12.0

    ./configure --libdir=/usr/lib

    make

    make install

    • 启动HBase-Thrift(Server端)

    找到hbase-daemon.sh(如果是ambari安装则在/usr/hdp/版本号/hbase目录下面)

    启动Thrift:hbase-daemon.sh start thrift

    启动Thrift2:hbase-daemon.sh start thrift2

    默认启动HBase与Thrift交互端口为9095,Thrift外部端口为9090

    多个Thrift同时启动会端口冲突,可以通过--infoport 9096 -p 9091命令来指定内部和外部端口,同时还需要找到hbase-daemon.sh上层目录conf下面的hbase-site.xml,修改/新增hbase.thrift.info.port和hbase.regionserver.thrift.port配置,这个没有尝试过,不知道有没有其他坑

    • 配置HBase-Thrift(调用Thrift报错:TTransportException)

    TTransportException错误分两种情况

    一种是一条结果都获取不了,这种情况一般是使用问题,比如用Thrift2的接口调用Thrift,或者混淆了bytes和str

    另一种情况是可以正常使用,但过几分钟莫名其妙就断了,这种是由于HBase配置有bug

    需要在hbase-site.xml加入以下两项(如果设定超时时间为一天),然后重启HBase和Thrift

    <property>
             <name>hbase.thrift.server.socket.read.timeout</name>
             <value>86400000</value>
    </property>
    
    <property>
             <name>hbase.thrift.connection.max-idletime</name>
             <value>86400000</value>
    </property>
    • 安装Thrift/Thrift2环境(Client端)

    pip install thrift

    • 使用Thrift方式一:pip安装(Client端)

    pip install hbase-thrift

    安装包安装到python安装目录lib/hbase或lib/site-packages/hbase下面

    from thrift import Thrift
    from thrift.transport import TSocket, TTransport
    from thrift.protocol import TBinaryProtocol
    
    # 连接
    tsocket = TSocket.TSocket("10.0.0.1", 9090)
    tsocket.setTimeout(5000)
    ttransport = TTransport.TBufferedTransport(tsocket)
    protocol = TBinaryProtocol.TBinaryProtocol(ttransport)
    
    from hbase import Hbase
    
    # 客户端
    client = Hbase.Client(protocol)
    tsocket.open()
    
    #关键字
    tableName = bytes("namespace:table", encoding='utf8')
    rowkey = bytes("rowkey", encoding='utf8')
    
    # 获取所有表名
    tableNames = client.getTableNames()
    print('tableNames:',tableNames)
    
    # 获取列族
    columnDescriptors = client.getColumnDescriptors(tableName)
    print("columnName:",columnDescriptors)
    
    # 获取行
    row = client.getRow(tableName,rowkey)
    print("row:",row)

    使用hbase-thrift包的优点是包含的接口比较全面,比如获取所有tables、修改table属性等,缺点是读取方法很少,很多读取方法无法实现

    • 使用Thrift方式二:源码编译安装(Client端)

    如果hbase使用的是源码安装包安装的,可以找到Server端源码其中的hbase/thrift/Hbase.thrift

    或者上http://svn.apache.org/viewvc/hbase/trunk/hbase-thrift/src/main/resources/org/apache/hadoop/hbase/thrift/Hbase.thrift下载最新版本的Hbase.thrift

    执行thrift -r --gen py Hbase.thrift

    当前目录下生成gen-py

    将gen-py/hbase中的内容覆盖到Client端python安装目录的lib/hbase或lib/site-packages/hbase下面

    from thrift import Thrift
    from thrift.transport import TSocket, TTransport
    from thrift.protocol import TBinaryProtocol
    
    # 连接
    tsocket = TSocket.TSocket("10.0.0.1", 9090)
    tsocket.setTimeout(5000)
    ttransport = TTransport.TBufferedTransport(tsocket)
    protocol = TBinaryProtocol.TBinaryProtocol(ttransport)
    
    from hbase import Hbase
    
    # 客户端
    client = Hbase.Client(protocol)
    tsocket.open()
    
    #关键字
    tableName = bytes("namespace:table", encoding='utf8')
    rowkey = bytes("rowkey", encoding='utf8')
    
    # 获取所有表名
    tableNames = client.getTableNames()
    print('tableNames:',tableNames)
    
    # 获取列族
    columnDescriptors = client.getColumnDescriptors(tableName)
    print("columnName:",columnDescriptors)
    
    # 获取行
    row = client.getRow(tableName,rowkey,attributes={})
    print("row:",row)

    最新官方的Hbase.thrift生成的包中包含了一些新接口新功能,如getRow()函数的attributes参数,但是实测并没有什么作用

    • 使用Thrift方式三:Happybase(Client端)

    pip install happybase

    import happybase
    
    connect = happybase.Connection(host="10.0.0.1", port=9090)
    connect.open()
    table = connect.table("namespace:table")
    print(table.row('rowkey', timestamp=1554277000000, include_timestamp=True))
    connect.close()

    happybase的优势是封装较好,使用方便

    • 使用Thrift2(Client端)

    如果需要对表中的内容进行更细致的操作,比如提取某个时间段之间的columns,使用Thrift无法实现,只能使用Thrift2

    找到源码包中的hbase/thrift2/hbase.thrift或者下载http://svn.apache.org/viewvc/hbase/trunk/hbase-thrift/src/main/resources/org/apache/hadoop/hbase/thrift2/hbase.thrift

    执行thrift -r --gen py Hbase.thrift

    将gen-py/hbase中的内容拷贝到Client端python安装目录的lib/hbase或lib/site-packages/hbase2(为了区分thrift与thrift2,如果不用共存也可命名为hbase或其他名称)

    from thrift import Thrift
    from thrift.transport import TSocket, TTransport
    from thrift.protocol import TBinaryProtocol
    
    # 连接
    tsocket = TSocket.TSocket("10.0.0.2", 9090)
    tsocket.setTimeout(5000)
    transport = TTransport.TBufferedTransport(tsocket)
    protocol = TBinaryProtocol.TBinaryProtocol(transport)
    
    import hbase2
    
    # 客户端
    client = hbase2.THBaseService.Client(protocol)
    tsocket.open()
    
    # 获取行
    get = TGet()
    get.row = bytes("rowkey", encoding='utf8')
    #get.timestamp = 1554278944040
    get.timeRange = TTimeRange()
    get.timeRange.minStamp = 1554277751530
    get.timeRange.maxStamp = 1554277751550
    result = client.get(bytes('namespace:table', encoding='utf8'), get)

     Thrift2的数据接口完善很多,可以实现一些Thrift无法实现的查询功能,但是不包含获取table列表之类的接口

    参考文献:

    https://www.cnblogs.com/zhang-ke/p/9008228.html

    https://blog.csdn.net/caojinlei_91/article/details/82761157

    https://blog.csdn.net/kelonsen/article/details/78477152

    https://blog.51cto.com/13103353/2107257

    https://blog.csdn.net/wwlhz/article/details/56012053

    https://blog.csdn.net/qq_36330643/article/details/83106759

    http://www.aiuxian.com/article/p-3104971.html

  • 相关阅读:
    Ubuntu Docker 安装
    apt安装 E: 无法获取 dpkg 前端锁 (/var/lib/dpkg/lock-frontend),是否有其他进程正占用它?
    Ubuntu18.04 网路图标消失连接不上网
    Liunx 安装配置NFS服务,挂载目录
    python shutil包 文件/目录的复制,移动
    python urllib包 实现通过http下载文件
    MAC上的Terminal光标快捷键
    Safari下载zip文件后不再自动打开
    Wordpress: contact form 7 表单内容同行
    Zoi选项 — Insure抑制功能
  • 原文地址:https://www.cnblogs.com/jhc888007/p/10655785.html
Copyright © 2011-2022 走看看