开发者社区> 问答> 正文

hbase如何设计实现大流量实时读写pv,uv等统计指标?

假设通过storm接入了每小时百万级的埋点数据(有userId和url字段),要求可以实现能够实时获取某个用户每天,每周或每月访问了某个url的累加值。读和写的量都较大且实时性要求比较高。hbase的话如何设计才能实现读写在时间上最优?

展开
收起
hbase小能手 2018-11-06 10:01:05 4374 0
1 条回答
写回答
取消 提交回答
  • HBase是一个分布式的、面向列的开源数据库,一个结构化数据的分布式存储系统。HBase不同于一般的关系数据库,它是一个适合于非结构化数据存储的数据库。阿里云HBase技术团队共同探讨HBase及其生态的问题。

    针对题目的pv,uv来说,假设需要求出单个url某天,某周,某月的pv和uv
    一般来说这种需求如果查询时再计算就太慢了,需要提前进行预聚合,比如我们设计这么一个表
    | url | timeRange | pv | uidSet |
    把url和timeRange组合为rowkey
    timeRange为统计的时间范围(跨度为所需的最小时间粒度,本问题中为一天,比如2018-10-11,2018-10-12)
    pv为数值,uidSet为访问该url的userId集合
    当一条记录来临时,storm处理之后,对对应的url和对应timeRange里面的pv值+1,uidSet执行uidSet.add(userId)操作
    这样如果统计url1的2018-10-01到2018-10-07号的pv值与uv值,可以取出对应7行数据,执行如下计算
    pv=pv1 + pv2 + ... + pv7
    总uidSet = uidSet1.merge(uidSet2).merge(uidSet3)...... .merge(uidSet7)
    uv = 总uidSet.cardinality()

    上面方法中pv计算很简单,直接是值的相加,单条记录pv字段存储量为一个long的大小
    uv的计算就会有些问题:uidSet的大小按照普通方法会随着userId的规模扩大而失控,merge操作耗时也会增加
    解决方法有几种
    如果不要求结果完全精确,能接受微小的误差的话,可以使用hyperloglog结构存储,这样的话uidSet的大小可控,merge操作的速度也很快
    如果要求结果完全精确,可以参照druid的datasketches实现,来存储uidSet

    2019-07-17 23:12:22
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
大数据时代的存储 ——HBase的实践与探索 立即下载
Hbase在滴滴出行的应用场景和最佳实践 立即下载
阿里云HBase主备双活 立即下载