• hbase实践之rowkey设计


    rowkey设计的重要性

    image

    rowkeys是HBase表设计中唯一重要的一点。

    rowkey设计要求

    • 唯一性

    存储特性

    • 按照字典顺序排序存储

    查询特性

    由于其存储特性导致查询特性:

    • 查询单个记录;
    • 查定一定范围的记录。

    可能存在的问题

    • 热点问题
    什么是热点和数据倾斜
    热点发生在大量的client直接访问集群的一个或极少数个节点(访问可能是读,写或者其他操作)。大量访问会使热点region所在的单个机器超出自身承受能力,引起性能下降甚至region不可用,这也会影响同一个RegionServer上的其他region,由于主机无法服务其他region的请求,造成资源浪费。设计良好的数据访问模式以使集群被充分,均衡的利用。
    数据倾斜:Hbase可以被划分为多个Region,但是默认创建时只有一个Region分布在集群的一个节点上,数据一开始时都集中在这个Region,也就是集中在这一个节点上,就算region存储达到临界值时被划分,数据也是存储在少数节点上。这就是数据倾斜。
    
    
    

    热点问题如何解决

    通过多个分区来分散读写压力。

    另外一次读写大量数据,也会导致机器性能问题,个人认为也可以通过分区来分散读写压力。

    分区的本质

    hbase相当对于一个表做水平拆分,比如范围[1,N]的数据在region1, 范围[N+1,2N]的数据在region2,依次类推,将数据分散到N个分区。

    rowkey设计的几个设计技巧

    1. 加盐
    2. 前缀hash
    3. 反转(ID,如手机号)
    4. 反转时间撮Reverse Timestamps(时间撮): (Long.MAX_VALUE - timestamp) to the end of any key, e.g. [key][reverse_timestamp].

    这几个设计技巧,本质就是让数据分散,避免热点问题。

    分区算法

    分区算法就是制定数据分散的规则,划分每个分区的边界,Determining Split Points。

    HBase 1* 自带的分区算法:

    1. HexStringSplit(默认分区算法)。 左填充。RegionSplitter.HexStringSplit to partition their table and set it as default。row key是十六进制的字符串(hexadecimal ASCII)作为前缀的时候

    2. UniformSplit(hash):随机均匀分布,节省空间。如果是整形转bytes,肯定节省空间;如果是string转bytes,其实是不节省空间。右填充

      某个hbase的表查询只是以随机查询为主,可以用UniformSplit的方式进行,按照原始byte值(从0x00~0xFF)右边以00填充。以这种方式分区的表在插入的时候需要对rowkey进行一个技巧性的改造, 比如原来的rowkey为rawStr,则需要对其取hashCode,然后进行按照比特位反转后放在最初rowkey串的前面

    此外还可以自定义分区算法:预分区:随机生成key,指定region的startkey、endkey。
    Relationship Between RowKeys and Region Splits

    Lesson #1: Pre-splitting tables is generally a best practice, but you need to pre-split them in such a way that all the regions are accessible in the keyspace. While this example demonstrated the problem with a hex-key keyspace, the same problem can happen with any keyspace. Know your data.
    预分区是最佳实践,但是需要对于所有region的访问都在key空间中。
    
    Lesson #2: While generally not advisable, using hex-keys (and more generally, displayable data) can still work with pre-split tables as long as all the created regions are accessible in the keyspace.
    当通常的方案(预分区)做不到,可以采用十六进制key。
    

    最好先将int 转成 byte[]。 byte[] b = String.format("%016x", key).getBytes();

    如何根据实际场景来设计rowkey

    此处可参考《滴滴HBASE使用经验》

    其他

    如果将时序数据存入HBase,可以研究OpenTSDB方案。

    参考文献

  • 相关阅读:
    17。3.12---re模块--正则表达式操作指南
    17.3.12---还有未整理的模块
    17.3.12---xmlrpclib模块
    17.3.12----math模块
    17.3.12--smtplib模块发送邮件__抄送,安装与下载
    17.3.12---logging日志模块level配置操作
    17.3.12---urlparse模块的URL下载
    17.3.12---socket
    17.3.12--urllib2模块
    SQLSERVER 中的共用表达式(CTE)
  • 原文地址:https://www.cnblogs.com/small-k/p/9610809.html
Copyright © 2020-2023  润新知