HBase计数器Increment
在互联网企业中,经常会有这样的一些需求,比如说:统计下某网站某日pv/uv量或是统计下某签约作者某篇文章的所获点赞数等等。
传统的做法可能需要我们先读出该列的原有值,然后+1后再覆盖原有值,同时还要加锁处理等等。
为了保证原子性的完成一个客户端请求,HBase 引入了计数器的概念,可以用于实时统计。HBase 有一种机制可以将列当作计数器,支持原子操作。
通过HBase Shell命令使用计数器
HBase计数器就是一个与其他列类似的简单列,列值要求必须以长整型转码插入。计数器不需要初始化,创建一个新列时初始值为0,第一次 incr 操作返回1。
计数器使用 incr 命令,增量可以是正数也可以是负数,但是必须是Long型。其语法如下:
incr '<table>','<row>','<column>',['<increment-value>']
例如,创建计数器并插入值:(注意:步长值可为正、可为负、可为0)
hbase> create 'test','f' hbase> incr 'test','r1','f:count',1 hbase> incr 'test','r1','f:count',2 hbase> incr 'test','r1','f:count',-1
下面获取计数器值:
hbase> get_counter 'test','r1','f:count'
需要注意的是,增加的参数必须是长整型 Long,如果按照错误的格式更新了计数器(如字符串格式),下次调用 incr 会得到错误的结果。
通过Java API使用计数器
HBase Client API 提供了专门的方法实现对计数器的读取和修改操作,在单独的一次客户端调用中保证原子性。
单计数器 Java API
操作一个计数器,类似 shell 命令 incr。示例代码如下:
HTable table = new HTable(conf, "counters"); long cnt1 = table.incrementColumnValue(Bytes.toBytes("r1"),Bytes.toBytes("f"),Bytes.toBytes("count"),1L);
多计数器 Java API
使用 Table 的 increment() 方法可以操作一行的多个计数器。需要构建 Increment 实例,并且指定行键:
HTable table = new HTable(conf, "counters"); Increment incr1 = new Increment(Bytes.toBytes("r1")); incr1.addColumn(Bytes.toBytes("f"), Bytes.toBytes("count"),1); incr1.addColumn(Bytes.toBytes("f"), Bytes.toBytes("hits"), 1); Result result = table.increment(incr1); for(Cell cell : result.rawCells()) { // ... }