美文网首页
006 Kudu | Schema设计

006 Kudu | Schema设计

作者: __destory__ | 来源:发表于2019-02-19 10:27 被阅读0次

    Kudu有着和RDBMS类似你的结构数据存储机制,Schema的设计非常重要

    1. 读写能够spread到整个tablet servers,而不会出现热点,partition作用
    2. Tablets能够按照均匀,可预测的速度增长,负载平稳
    3. 一次查询,最小的数据访问需求

    Column设计

    属于Primary Key的列不能为空,支持的数据类型如下

    • boolean
    • 8-bit signed integer
    • 16-bit signed integer
    • 32-bit signed integer
    • 64-bit signed integer
    • unixtime_micros (64-bit microseconds since the Unix epoch)
    • single-precision (32-bit) IEEE-754 floating-point number
    • double-precision (64-bit) IEEE-754 floating-point number
    • decimal
    • UTF-8 encoded string (up to 64KB uncompressed)
    • binary (up to 64KB uncompressed)

    Kudu会对列进行高效的编码和序列化,这也是它做列式存储的初衷,因此应该正确使用列的类型,而不是简单一味的全部使用string或者binary。

    Decimal Type

    该类型是一个数值类型,通过fixed scale和precision,来满足财务或者数学相关数据的表示。都有float和double了,为什么还需要decimal type?
    float和double是浮点数,而decimal是定点数,浮点数会出现精确度不高的问题,所以,decimal定点数更多用于财务数字方面。
    尽可能使用合适的精度和标度,以减少存储的消耗和计算的消耗。

    列编码

    编码列表如下,


    列编码.png
    1. Plain Encoding,数据按照自有的格式存储,比如,int32的值就按照fixed-size 32-bit little-endian整形进行存储
    2. Bitshuffle Encoding,数据块bit被重新编排,所有值的最重要bit第一位,其次放次重要的bit,以此类推...,最终结果是lz4压缩,该编码适合有很多重复的数值情况,或者当根据primary key进行排序,对应某个数值集合改动很小。
    3. Run Length Encoding,通过存储值value和数量count来对一列进行压缩,适合当对primary key进行排序后,连续重复的数值进行压缩
    4. 构造包含unique values的字典,在字典中存储每列编码后的值和其对应的字典index完成编码工作,对于具有low cardinality的列高效。在对数据进行flush的时候,如果列的unique values的数量过多的话,kudu自动将该编码降解为plain Encoding
    5. Prefix Encoding,前缀编码,对于列值大多数有共同前缀的情况下,使用该编码,对于第一列为主键的列,使用该编码。

    列压缩

    支持Lz4,Snappy,Zlib。目前lz4最好,bitshuffle-Encoding默认是lz4编码,不需要重复设置。

    主键的设计

    每个Kudu表必须声明primary key,并且primary key具有唯一性的约束,试图插入一个primary key已经存在的数据,会导致duplicate error。

    primary key涉及的列,必须是非空的,不能是boolean,float,double类型(decimal可以),一旦设置完primary key后的表,不能修改primary key。

    和RDBMS不同,Kudu不支持自动增加的primary key,因此insert时候,必须提供全部的primary key;同理,修改删除的时候,也需要指明修改删除row对应的全部的primary key,目前,Kudu不支持natively的范围delete和update;虽然Kudu的主键不支持修改,但是可以先删除后插入。

    主键索引

    Tablet中的所有rows是按照primary key排序的。基于主键的,相等,范围查找,效率高。

    Backfill 插入//todo

    考虑一个问题,primary key是timestamp或者primary key的第一个列是timestamp,当插入数据时,Kudu会去查找key是否存在,如果存在则duplicate error。

    分区

    选择一个合适的分区策略需要理解数据模型和table表的负载期望,对于写多的应用场景,能够让写操作spread所有tablet至关重要,这样可以避免某个tablet过大。同样的,对于很多short scans的情况,如果对于scan的数据都在一个tablet上的话,会有更高的效率。上面两点是我们进行分区策略设置需要铭记于心的。

    Range分区

    Range分区使用全局有序的range分区key来分布数据,每一个分区都被赋予一部分连续的keys,这部分一定会是整体primary key 列的keys的子集。如果没有hash分区参与,对于range分区,一个分成的range分区都是一个tablet。

    Range分区必须不能彼此重叠,每个row都只能落在唯一一个分区中。

    Range分区可以动态的增加和删除,如果删除一个range分区,则对应的tablet也会删除,数据也会删除,

    Hash分区

    Hash分区通过hash值将数据分布到多个buckets中,buckets的数量在create表的时候设置好。当不需要顺序访问表的时候,使用hash分区是非常有效的,能有效的将数据spread所有tablets

    多级别分区

    Hash和Range两种分区,各种好坏,通过结合,能够充分利用二者的优势,当然要结合业务情况。

    分区Prune

    Kudu能够自动skip扫描所有分区,当他能够对scan语句进行确定是否能够过滤掉某些不需要的分区。对于hash分区,scan扫描能够在每一个hashed列上相等才行,对于range扫描,能够在range partitioned列上进行相等或者范围上判断。

    分区的例子

    接下来,我们通过例子来说明两种分区的某些特点。考虑如下建表语句,metric表

    CREATE TABLE metrics (
        host STRING NOT NULL,
        metric STRING NOT NULL,
        time INT64 NOT NULL,
        value DOUBLE NOT NULL,
        PRIMARY KEY (host, metric, time),
    );
    

    Range分区例子

    假定,time有2014,2015,2016年的,通常time字段设置range分区,两种方式

    1. unbounded range分区
    2. bounded range分区


      range-partitioning-example.png

    在第一个例子中,使用了默认的range分区,将会在2015-01-01和2016-01-01两个点进行分区,这样导致了三个tablets,1)2015-01-01之前,2)2015-01-01到2016-01-01,3)2016-01-01之后,

    第二个例子,使用分区范围bounded方式,[(2014-01-01), (2017-01-01)],分割点是2015-01-01,和2016-01-01。最终,分区为,[(2014-01-01), (2015-01-01)], [(2015-01-01), (2016-01-01)], 和[(2016-01-01), (2017-01-01)]

    第一个例子是unbounded,第二个是bounded分区。

    上述两种方式都支持time-bounded扫描的分区prune(前提是被pruned分区的time bound都落在scan time的bound之外)。对于写操作,上述两种方式都面临着写热点的问题,因此,指标metric写入都是基于当前时间的,大多数写操作都会落入到一个单独range分区中。

    Hash分区

    假设,我们在host和metric上同时hash


    hash-partitioning-example.png

    该例子,在host和metric上分成4个buckets,这点不同于range分区,hash分区可以使得write操作spread所有tablets,提高写的吞吐量,同时,scan操作也可以利用分区的prune。

    严重的一点是,hash策略会导致每个分区越来越大,因为buckets个数固定了。这点range分区不会,因为range分区可以通过增加新的分区来扩容

    Hash和Range结合的例子

    先看下二者之间的优缺点。


    优缺点.png

    Hash分区能够提高写的吞吐量,Range分区能够避免无限的tablet增长问题。所以,通常可以结合两种策略,来利用各自的优点。如下图,


    结合的分区方案.png

    在time上进行range分区,在host和metric上进行hash分区,结合了hash和range两种策略。写操作会并发到hash buckets的数据,这里是4个buckets,读操作还可利用time bound和明确host以及metric实现分区prune。新的分区也可以添加进来,同时会生成4个新的tablets。

    Hash和Range结合的例子

    两个hash策略结合,可以不同的buckets


    hash-hash-partitioning-example.png

    host 4 buckets,metric 3 buckets,总共12个tablet,写操作可以spread所有tablets,读操作可以重复利用host和metric进行分区prune。

    缺陷

    • Number of Columns
      By default, Kudu will not permit the creation of tables with more than 300 columns. We recommend schema designs that use fewer columns for best performance.

    • Size of Cells
      No individual cell may be larger than 64KB before encoding or compression. The cells making up a composite key are limited to a total of 16KB after the internal composite-key encoding done by Kudu. Inserting rows not conforming to these limitations will result in errors being returned to the client.

    • Size of Rows
      Although individual cells may be up to 64KB, and Kudu supports up to 300 columns, it is recommended that no single row be larger than a few hundred KB.

    • Valid Identifiers
      Identifiers such as table and column names must be valid UTF-8 sequences and no longer than 256 bytes.

    • Immutable Primary Keys
      Kudu does not allow you to update the primary key columns of a row.

    • Non-alterable Primary Key
      Kudu does not allow you to alter the primary key columns after table creation.

    • Non-alterable Partitioning
      Kudu does not allow you to change how a table is partitioned after creation, with the exception of adding or dropping range partitions.

    • Non-alterable Column Types
      Kudu does not allow the type of a column to be altered.

    • Partition Splitting
      Partitions cannot be split or merged after table creation.

    相关文章

      网友评论

          本文标题:006 Kudu | Schema设计

          本文链接:https://www.haomeiwen.com/subject/bgcxyqtx.html