HappyBaseFaceBook 员工开发的操作 HBasePython 库,其基于 Python Thrift,但使用方式比 Thrift 简单、简洁许多,已被广泛应用。本文就 HappyBase 的常用调用示例做下简单的介绍。

  • 非自动连接:

    connection = happybase.Connection('somehost', autoconnect=False)
    connection.open()

    自动连接:

    connection = happybase.Connection('somehost') #自动连接

    指定以后所涉及的表实际都是以指定前缀开头的(当然前缀后还有个'_'):

    connection = happybase.Connection('somehost', table_prefix='myproject') 

    连接(Connection)提供的方法:

    1. connection.tables() # 获取表格列表
    2. connection.create_table(
      'mytable',
      {'cf1': dict(max_versions=10),
      'cf2': dict(max_versions=1, block_cache_enabled=False),
      'cf3': dict(), # use defaults
      }) # 第二个参数是个 map<string, map> 的结构,内层的 map 用于设置创建的列的参数配置
    3. table = connection.table('mytable') # 获取表对象
  • table = connection.table('mytable')

    这个方法不会检查表格是否存在,也就是在用 table 的某些方法的时候才会出现异常,创建表,可以带上一些参数如:max_versionblock_cache_enables

    注意!因为 hbase 是多个产品功能的,所以表的命名最好跟应用相关,不然容易冲突,推荐用 classfoo_page 这种

    表格(Table)提供的方法:

    通过 key 获取一行的信息:

    row = table.row('row-key')

    获取指定 family:colum 的值:

    print row['cf1:col1']

    获取多行数据:

    rows = table.rows(['row-key-1', 'row-key-2'])
    for key, data in rows:
    print key, data
    rows_as_dict = dict(table.rows(['row-key-1', 'row-key-2']))

    获取多行有序 map

    from collections import OrderedDict
    rows_as_ordered_dict = OrderedDict(table.rows(['row-key-1', 'row-key-2']) # 将 rows 方法返回的 key、value 存入 map 或者放入有序 map

    获取指定列的数据(默认情况下。row 或者 rows 方*获取行的所有列(而大多数的列,在这些相应的业务处理的时候都是用不到的,所以可以指定获取那些 column,减少传输数据的大小):

    row = table.row('row-key', columns=['cf1:col1', 'cf1:col2'])
    print row['cf1:col1']
    print row['cf1:col2']
    row = table.row('row-key', columns=['cf1']) # 也可以只是指定列族
    row = table.row('row-key', timestamp=123456789) # 同时可以指定时间片信息,但是请注意一定得是数字(>=0),不可以是字串
    row = table.row('row-key', columns=['cf1:col1'], include_timestamp=True)
    value, timestamp = row['cf1:col1']
    rows = table.rows(['h1', 'h5', 'h3'], include_timestamp=True) #对于include_timestamp也可以用于rows方法
    for key, value in rows:
    print key, value # 而其返回的结果类似一个map,key为相应的row_key,value也为map,不过其值不光是value还有value对应的时间片,组成了一个数组,注意rows方法

    获取多版本的信息:

    values = table.cells('row-key', 'cf1:col1', versions=2)
    for value in values:
    print "Cell data: %s" % value
    cells = table.cells('row-key', 'cf1:col1', versions=3, include_timestamp=True)
    for value, timestamp in cells: # 一般都这格式,value带时间片的,都是先value,在时间片的数组
    print "Cell data at %d: %s" % (timestamp, value)

    表格遍历:

    for key, data in table.scan():
    print key, data

    这里 key 就收 row_keyvalue 为一整行的数据,都是 mapkeyfamliy:colname 形式,和 row 方法或者 row 方法返回的 value 值是一样的,可以在 scan 参数中指定 row_start='class' 或者 row_end='foo',用于限定范围,同事支持row_key 的前端匹配,通过 row_prefix

    数据存储(传入给 hbase 的数据都是原始的字节字符串):

    table.put('row-key', {'cf:col1': 'value1','cf:col2': 'value2'}) # 跟shell的差不多,key 然后是个colum与value的map
    table.put('row-key', {'cf:col1': 'value1'}, timestamp=123456789) # 可以手动加入时间片,注意一定是integer的

    批量存储:

    b = table.batch(timestamp=123456789)
    b.put( ...) # 这里的timestamp可以不指定,也可以在put的时候指定
    b.send()

    或者是与 with 集合,能起到即使有异常抛出,仍会进行 b.send() 的操作,不过从某种角度,这就不是一个完整的transation 了:

    with table.batch() as b:
    b.put('row-key-1', {'cf:col1': 'value1', 'cf:col2': 'value2'})
    b.put('row-key-2', {'cf:col2': 'value2', 'cf:col3': 'value3'})
    b.put('row-key-2', {'cf:col2': 'value2', 'cf:col3': 'value3'})
    b.put('row-key-3', {'cf:col3': 'value3', 'cf:col4': 'value4'}) # 注意 put 和 delet 操作可以放在一个 batch 里头,但是对同一行执行 put 和 delete 操作,放到一个 batch 里头其表现是不可预测

    当然因为需要插入多条数据或者数据本身很大,倒数数据量会很到,这时候就需要设置 batch 的大小,以做优化:

    with table.batch(batch_size=1000) as b:
    for i in range(1200):
    b.put('row-%04d' % i, {'cf1:col1': 'v1','cf1:col2': 'v2',}) # 这里也是可以 put 多个列的,用 map。特别需要注意的是在 batch 里头 transaction=True, batch_size=1000,这两个属性是不能同时使用的

    删除数据:

    table.delete('row-key')
    table.delete('row-key', columns=['cf1:col1', 'cf1:col2'])