Doris 数仓使用规范(经验版)

第一部分:字符集规范

【强制】数据库字符集指定utf-8,并且只支持utf-8。

命令规范

  1. 【建议】库名统一使用小写方式,中间用下划线(_)分割,长度62字节内
  2. 【建议】表名称大小写敏感,统一使用小写方式,中间用下划线(_)分割,长度64字节内

第二部分:建表规范

  1. 【强制】确保每个tablet大小为1-3G之间。举例:假设表内单分区数据量在100G,按天分区,bucket数量100个。
  2. 【强烈建议】不要使用Auto Bucket ,按照自己的数据量来进行分区分桶,这样你的导入及查询性能都会得到很好的效果,Auto Bucket 会造成 tablet 数量过多,造成大量小文件的问题。
  3. 【强制】 5 亿以上的数据必须设置分区分桶策略
    1. 维度表:缓慢增长的,可以使用单分区,在分桶策略上使用常用查询条件(这个字段数据分步相对均衡)分桶,
      1. 100M以内:1 buckets
      2. 100M-1G :3-5 个 Buckets
      3. 大于1G-3G : 5-7个 buckets
      4. 3-5G : 7-10 个 buckets
    2. 事实表
      1. 没有办法分区的,数据又缓慢增长的:单个tablet数据量保持在1-3G;比如5亿数据大小在20G,bucket数量给20个
      2. 没有办法分区的,数据又较快增长的,没办法按照时间动态分区,可以适当放大一下你的bucket数量,按照你的数据保存周期(180天)数据总量,来估算你的bucket数量应该是多少,建议还是单个bucket大小在1-3G。
        1. 避免数据倾斜的问题
          1. 一个是对分桶字段进行加盐处理,业务上查询的时候也是要同样的加盐策略,这样能利用到分桶数据剪裁能力
          2. 另外一个是数据随机分桶,这种缺点是没办法利用数据分桶剪裁能力,数据分布会很均匀
  4. 【建议】 1000w-2 亿以内数据为了方便可以不设置分区,直接用分桶策略。(不设置其实Doris内部会有个默认分区)
    1. 参考上面第二点
  5. 【强制】 2000kw 以内数据禁止使用动态分区(动态分区会自动创建分区,而小表用户客户关注不到,会创建出大量不使用分区分桶)
    1. 参考上面第二点
  6. 【强制】对于有大量历史分区数据,但是历史数据比较少,或者不均衡,或者查询概率的情况,使用如下方式将数据放在特殊分区。
    1. 对于历史数据,如果数据量比较小我们可以创建历史分区(比如年分区,月分区),将所有历史数据放到对应分区里
    2. 创建历史分区方式FROM ("2000-01-01") TO ("2022-01-01") INTERVAL 1 YEAR
(
 PARTITION p00010101_1899 VALUES [('0001-01-01'), ('1900-01-01')),
 PARTITION p19000101 VALUES [('1900-01-01'), ('1900-01-02')),
...
 PARTITION p19000104_1999 VALUES [('1900-01-04'), ('2000-01-01')),
 FROM ("2000-01-01") TO ("2022-01-01") INTERVAL 1 YEAR,
 PARTITION p30001231 VALUES [('3000-12-31'), ('3001-01-01')),
 PARTITION p99991231 VALUES [('9999-12-31'), (MAXVALUE))
)
  1. 【强制】如果分桶字段存在30%以上的数据倾斜,则禁止使用Hash分桶策略,改使用random分桶策略

    1. 参考上面第二点事实表部分
  2. 【建议】前缀索引的第一个字段一定是最长查询的字段,并且需要是高基字段。这里面选取分区分桶外最长查询且高基数的列

    1. 前缀索引(36位):第一个字段查询性能最好,前缀索引碰见varchar类型的字段,会自动截断前20个字符
      1. Int(4)+ Int(4) + varchar(50),前缀索引长度只有28
      2. Int(4) + varchar(50) + Int(4),前缀索引长度只有24
      3. varchar(10) + varchar(50) ,前缀索引长度只有30
    2. 最常用的查询字段如果能放到前缀索引里尽可能放到前前缀索引里,如果不能,可以放到分桶字段里
      1. 分桶字段注意事项:这个一般是数据分布比较均衡的,也是经常使用的字段,最好是高基数字段
  3. good case :UNIQUE KEY(user_id, age) user_id最长被查询,且数据分布比较散

  4. bad case :UNIQUE KEY(age,user_id ) age是低基数列,且可能存在数据倾斜

  5. 【强制】表的副本数必须为3

  6. 【建议】前缀索引中的字段长度尽可能明确,因为Doris只有前36个字节能走前缀索引

  7. 【强制】除了UNIQUE KEY和aggregate key要构建key的情况,否则不要基数(例如user_type)小于50的字段建立任何索引。因为Doris内置了字典类型优化。

    1. 已经有了低基数优化了
    2. Unique Key 是aggregate key 的一个特例,当aggregate key 的key 保持唯一其实就是Unqiue key 模型
  8. 【强制】BloomFilter索引必须在查询条件是in或者=,并且是高基(5000以上)列上构建。

    1. 数据基数在一半左右
    2. 类似身份证号这种基数特别高并且查询是等值(=)查询,使用Bitmap索引能极大加速
    3. Bloomfilter 使用场景:
      1. 首先BloomFilter适用于非前缀过滤。
      2. 查询会根据该列高频过滤,而且查询条件大多是 in 和 = 过滤。
      3. 不同于Bitmap, BloomFilter适用于高基数列。比如UserID。因为如果创建在低基数的列上,比如 “性别” 列,则每个Block几乎都会包含所有取值,导致BloomFilter索引失去意义。
  9. 【强制】bitmap索引必须在一定基数范围内构建,太高或者太低的基数都不合适

    1. 这种索引更多的适合正交查询
    2. 适用场景:
      1. 适用于低基数的列上,建议在100到100,000之间,如:职业、地市等。 重复度过高则对比其他类型索引没有明显优势;重复度过低,则空间效率和性能会大大降低。 特定类型的查询例如count、or、and 等逻辑操作因为只需要进行位运算
    3. Bitmap 索引支持类型:
      1. bitmap 索引支持的数据类型如下:
        • TINYINT
        • SMALLINT
        • INT
        • BIGINT
        • CHAR
        • VARCHAR
        • DATE
        • DATETIME
        • LARGEINT
        • DECIMAL
        • BOOL
  10. 【强制】亿级别以上数据,如果有模糊匹配,使用倒排索引或者是 NGram Bloomfilter

  11. 【建议】如果某个范围数据在分区分桶和前缀索引中都不好设计,可以考虑引入倒排索引加速。

  12. 【强制】单表物化视图不能超过6个

    1. 单笔物化视图是实时构建
    2. 在unique 模型上物化视图只能起到 Key 重新排序的作用,不能做数据的聚合,因为Unqiue模型的聚合模型是replace
  13. 【建议】建议使用JSON数据类型代替字符串类型存放JSON数据的使用方式

第三部分:数据变更规范

  1. 【强制】应用程序不可以直接使用delete后者update语句变更数据,使用CDC的upsert方式来实现。

    1. 低频操作上使用,比如 Update 几分钟更新一次
    2. 如果使用 Delete 一定带上分区条件
  2. 【强制】DBA执行delete后者update语句时必须带分区条件

  3. 【强制】禁止使用INSERT INTO tbl1 VALUES ("1"), ("a");这种方式写入数据。

  4. 【建议】特殊大的ETL操作,简单单独在Session中设置超时时间

    1. SELECT/*+ SET_VAR(query_timeout = 1*/ sleep(3); 类似这样通过Hint方式去设置Session 会话变量,不要设置全局的系统变量

第四部分:数据查询规范

  1. 【强制】in 中条件超过 2000 后,必须修改为子查询

  2. 【强制】禁止使用REST API(Statement Execution Action)执行大量SQL查询,改接口仅仅用于集群维护。

  3. 【建议】一次insert into select 数据超过1亿条后,建议拆分为多个insert into select语句执行,分成多个批次来执行。

    1. 如果真的是要这样执行,在集群资源相对空闲的时候可以通过调整并发度来加快的数据导入速度

      2.0 以后版开启了Pipeline 就不需要设置并发度了

      set parallel_fragment_exec_instance_num = 8 或者 16 建议是你CPU内核的一半
      insert into new_tbl select * from old_tbl
    
  4. 【强制】query查询条件返回结果在5w条以上,使用JDBC Catalog或者OUTFILE方式导出。不然大量FE上数据传输将占用FE资源,影响集群稳定性

    1. 如果你是交互式查询,建议使用分页方式(offset limit),分页要加Order by
    2. 如果是数据导出提供给第三方使用,建议使用 outfile 或者 export 方式
  5. 【建议】query查询如果有大量的数据传输需求,建议部署observer节点并在该该节点执行查询(私有化部署)

    1. 建议的方式是 1 FE(Follower) + 多个 OBserver(FE)方式,读写分析,所有的写连接 Follower,所有的读连接Observer
  6. 【建议】尽量不要使用OR 作为 JOIN条件

  7. 【建议】大量数据排序(5亿以上)后返回部分数据,建议先减少数据范围在执行排序,否则大量排序会影响性能。

select * from kunpeng_risk_record krr where krr.event_occur_time_date between '2023-10-01 00:00:00' and '2023-10-25 23:59:59' and krr.partner_code = 'liveme' order by krr.sequence_id desc limit 20;
  1. 例如将 from table order by datatime desc limit 10 优化为from table where datatime='2023-10-20' order by datatime desc limit 10

  2. 【强制】2个以上大于3亿的表 JOIN 使用 Colocate JOIN

    1. Colocate Join 的使用参照:Colocation Join - Apache Doris
  3. 【强制】亿级别大表禁止使用select * 查询,查询时需要明确要查询的字段

    1. SQL Block方式禁止这种操作

    2. 如果是高并发点查,建议开启行存

    3. 表属性级别

    "enable_unique_key_merge_on_write" = "true",
    "store_row_column" = "true"
          
    be.conf
    disable_storage_row_cache 是否开启行缓存, 默认不开启
    
    1. 使用PrepareStatement模板
  4. 【强制】亿级以上表数据查询必须带分区分桶条件

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342