SelectDB

什么是SelectDB

SelectDB是基于Apache Doris 研发的,基于 MPP 架构的高性能、实时的分析型数据库。

应用场景

  • 在线高并发报表与分析
    使用云数据库 SelectDB 版处理在线高并发报表,获得实时、快速、稳定、高可用的服务,支持数据实时写入、亚秒级查询响应、高并发点查询,满足集群高可用部署需求。

  • 用户画像与行为分析
    基于建设用户CDP数仓平台(数据管理平台),支持毫秒级加列以及动态表灵活应对业务变动,支持丰富的行为分析函数带来开发简化和效率提升,支持高表正交位图实现画像场景的秒级圈人。

  • 湖仓一体的现代化数据平台
    统一数据仓库和数据湖到单一平台,提供高性能的商业智能报表、Adhoc分析,以及增量ETL/ELT数据处理的能力。

  • 日志存储与分析
    将日志系统接入到云数据库 SelectDB 版,实现日志的实时查询、低成本存储、高效处理,降低企业日志系统综合成本,提升日志系统的性能和可靠性。

基本结构

image.png

使用接口

Apache Doris 采用 MySQL 协议,高度兼容 MySQL 语法,支持标准 SQL。兼容 MySQL 生态的命令行工具、JDBC/ODBC 和各种可视化工具。

数据模型

数据以表(Table)的形式进行逻辑上的描述。一张表包括行(Row)和列(Column)。Row 即用户的一行数据,Column 用于描述一行数据中不同的字段。

Column 可以分为两大类:Key 和 Value。从业务角度看,Key 和 Value 可以分别对应维度列和指标列。Doris 的 Key 列是建表语句中指定的列,建表语句中的关键字 unique key 或 aggregate key 或 duplicate key 后面的列就是 Key 列,除了 Key 列剩下的就是 Value 列。

Doris 的数据模型分为 3 类:

明细模型(Duplicate Key Model)

在明细数据模型中,存储层会保留写入的所有数据。即使两行数据完全相同,也都会保留。建表语句中指定的 Duplicate Key,只是用来指明数据存储按照哪些列进行排序,可以用于优化常用查询


image.png

主键模型(Unique Key Model)

主键模型能够保证 Key(主键)的唯一性,当用户更新一条数据时,新写入的数据会覆盖具有相同 key(主键)的旧数据。

image.png

聚合模型(Aggregate Key Model)

根据 Key 列聚合数据,Doris 存储层保留聚合后的数据,从而可以减少存储空间和提升查询性能;通常用于需要汇总或聚合信息(如总数或平均值)的情况。

image.png

目前有以下聚合方式:


image.png

分区与分桶

数据以关系表(Table)的形式进行呈现,会依次按照先分区(Partition)、再分桶(Bucket)的方式划分,最终在同一个分桶中的数据会形成数据分片(Tablet)。Tablet 是 Apache Doris 中多副本高可用、集群间数据调度与均衡的最小物理存储单位。

image.png

分区是物理上的隔离,分桶是逻辑上的隔离

分区

List Partition

List Partition 相当于对分区的列值进行枚举,因此选择的分区列最好是有区分度的可枚举值,例如本例中的 city。根据 city 列的枚举值创建多个 List Partition,则 PARTITION_DESC可以写为:

-- 以city作为分区列,创建华北、东北、华中、西南等分区
PARTITION BY LIST(city)
(
    PARTITION `p_huabei` VALUES IN ("beijing", "tianjin", "shijiazhuang"),
    PARTITION `p_dongbei` VALUES IN ("shenyang", "dalian"),
    PARTITION `p_huazhong` VALUES IN ("wuhan", "changsha")
    PARTITION `p_xinan` VALUES IN ("chengdu", "chongqing")
)

Range Partition

创建 Range partition 一般使用时间列,Range Partition 又可以分为静态和动态两种方式:

  • 静态 Range Partition

此类 Partition 的创建会生成一个左闭右开的区间,定义一个分区只需要指定右边界,该分区的左边界由上一个分区的右边界确定,PARTITION_DESC可以写为:


-- 以sdate这个时间列作为分区列,
-- 日期处于[min, 2023-01-01)的数据,都放到名为p2022的分区下;
-- 日期处于[2023-01-01, 2023-01-02)的数据,都放到名为p20230101的分区下;
-- 日期处于[2023-01-02, 9999-12-31)的数据,都放到名为pmax的分区下;
PARTITION BY RANGE(sdate)
(
    PARTITION `p2022` VALUES LESS THAN ("2023-01-01"),
    PARTITION `p20230101` VALUES LESS THAN ("2023-01-02"),
    PARTITION `pmax` VALUES LESS THAN ("9999-12-31")
)

可以看出,p20230101 这个分区的左边界由 p2022 分区的右边界确定,而 pmax 的左边界由 p20230101 的右边界确定。需注意的是,此处为了举例说明动态分区,使用了一个很大的边"9999-12-31",实际业务中很少会直接创建从 2023-01-02 到 9999-12-31 的分区。

动态 Range Partition

上述静态的分区需要手动指定边界,分区个数太多使用起来也不方便。动态 Range Partition 帮助我们解决了这个问题,只需指定一些分区的参数即可动态创建,PARTITION_DESC 相对更简单,只需指定哪个列作为分区列即可:

PARTITION BY RANGE(sdate)()
剩余参数需要在PARTITION进行配置:

PROPERTIES (
  "dynamic_partition.enable" = "true", -- 动态开启
  "dynamic_partition.time_unit" = "DAY", -- 分区单位,yer,month,week等
  "dynamic_partition.start" = "-30", --以当前时间为准,保留多少个单位时间内的分区数,超出的自动删除
  "dynamic_partition.end" = "3", --未来得空分区数
  "dynamic_partition.prefix" = "p", -- 分区名前缀
  "replication_num" = "1" -- 副本数
);

分桶

分桶在物理层面即数据分片(Tablet)。在数据表完成分区后,指定部分列作为分桶列,将这些列数据中相同哈希值的数据合到一起,形成了 Tablet。一个表中 Tablet 总数量 = 分区数(Partition num)x 分桶数(Bucket num)x 数据副本数(Replication_num) 。

[BUCKET_DESC] 语句非常简单,只需要一句:

DISTRIBUTED BY HASH(site) BUCKETS 20

关于 Partition 和 Bucket 的数量和数据量的建议

1.一个表的 Tablet 总数量等于 (Partition num * Bucket num)。

2.一个表的 Tablet 数量,在不考虑扩容的情况下,推荐略多于整个集群的磁盘数量。

3.单个 Tablet 的数据量理论上没有上下界,但建议在 1G - 10G 的范围内。如果单个 Tablet 数据量过小,

则数据的聚合效果不佳,且元数据管理压力大。如果数据量过大,则不利于副本的迁移、补齐,

且会增加 Schema Change 或者 Rollup 操作失败重试的代价(这些操作失败重试的粒度是 Tablet)。

4.当 Tablet 的数据量原则和数量原则冲突时,建议优先考虑数据量原则。

5.一个 Partition 的 Bucket 数量一旦指定,不可更改。所以在确定 Bucket 数量时,需要预先考虑集群扩容的情况。

比如当前只有 3 台 host,每台 host 有 1 块盘。如果 Bucket 的数量只设置为 3 或更小,那么后期即使再增加机器,

也不能提高并发度。

前缀索引

在 Aggregate、Unique 和 Duplicate 三种数据模型中。底层的数据存储,是按照各自建表语句中,AGGREGATE KEY、UNIQUE KEY 和 DUPLICATE KEY 中指定的列进行排序存储的。

而前缀索引,即在排序的基础上,实现的一种根据给定前缀列,快速查询数据的索引方式。
即只能在在Key的Column上有索引,Value的不能;且需要按照Key的顺序查询,将一行数据的前 36 个字节 作为这行数据的前缀索引。当遇到 VARCHAR 类型时,前缀索引会直接截断

BloomFilter索引

布隆过滤器索引,Bloom Filter本质上是一种位图结构,用于快速的判断一个给定的值是否在一个集合中。这种判断会产生小概率的误判。即如果返回false,则一定不在这个集合内。而如果返回true,则有可能在这个集合内。

image.png

  • 首先BloomFilter适用于非前缀过滤。
  • 存储这个额外的索引层次会占用额外的空间
  • 不支持对Tinyint、Float、Double 类型的列建Bloom Filter索引。
  • BloomFilter适用于高基数列。比如UserID。因为如果创建在低基数的列上,比如 “性别” 列,则每个Block几乎都会包含所有取值,导致BloomFilter索引失去意义。
  • Bloom Filter索引只对 in 和 = 过滤查询有加速效果。

Bitmap 索引

与数据库Bitmap索引创建、使用类似。

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

推荐阅读更多精彩内容