
分钟级 / 秒级报表(直播间观看人数 / 商品下单量) → Doris
毫秒级数据驱动(互动弹幕实时推荐) → Redis / Kafka
文章目录
Doris
Doris由百度大数据部研发,原名百度Palo,于2017年开源,2018年贡献到 Apache 社区后,更名为Doris。
Apache Doris是一个现代化的基于MPP(大规模并行处理)技术的分析型数据库 产品。MPP是将任务并行的分散到多个服务器和节点上,在每个节点上计算完成后,将各自部分的结果汇总在一起得到最终的结果(与Hadoop相似)。仅需亚秒级响应时间即可获得查询结果,有效地支持实时数据分析。
Apache Doris可以满足多种数据分析需求
- 1.固定历史报表
- 2.实时数据分析(直播间)
- 3.交互式数据分析
- 4.探索式数据分析等)
易上手:支持标准SQL语言,兼容MySQL协议
MPP
MPP, Massively Parallel Processing 大规模并行处理
在数据库非共享集群中,每个节点都有独立的磁盘存储系统和内存系统,业务数据根据数据库模型和应用特点划分到各个节点上,每台数据节点通过专用网络或者商业通用网络互相连接,彼此协同计算,作为整体提供数据库服务。
非共享数据库集群有完全的可伸缩性、高可用、高性能、优秀的性价比、资源共享等优势。
具体是:分区 ⟶ 分桶(tablet)⟶ 分布式节点层面并行进行
对数据库分区后,在每个分区内部还会再分桶。(因为一次肯定是在一个大分区中搜数据)
每个桶会被分配到不同的 BE(backend 节点),多个 BE 节点并行写入,天然并行写入能力很强。
示例
sql
SHOW CREATE TABLE db_user.dor_participate_alive_user_info_rt;
CREATE TABLE `dor_participate_alive_user_info_rt` (
`partition_id` tinyint(4) NOT NULL COMMENT '分区字段,取app_id的最后两位', --(看数据是最后一位)
`app_id` varchar(64) NOT NULL COMMENT '店铺id',
`alive_id` varchar(128) NOT NULL COMMENT '直播id',
`user_id` varchar(64) NOT NULL COMMENT '用户id',
`share_user_id` varchar(128) REPLACE_IF_NOT_NULL NULL DEFAULT "" COMMENT '所属邀请人id',
`his_online_time` int(11) REPLACE_IF_NOT_NULL NULL DEFAULT "0" COMMENT '直播间停留时长',
`his_learn_time` int(11) REPLACE_IF_NOT_NULL NULL DEFAULT "0" COMMENT '累计观看时长',
`his_learning_time` int(11) REPLACE_IF_NOT_NULL NULL DEFAULT "0" COMMENT '直播观看时长',
`his_learned_time` int(11) REPLACE_IF_NOT_NULL NULL DEFAULT "0" COMMENT '回放观看时长',
`first_in_time` datetime REPLACE_IF_NOT_NULL NULL COMMENT '首次进入时间',
`last_in_time` datetime REPLACE_IF_NOT_NULL NULL COMMENT '最近进入时间',
`his_learn_times` int(11) REPLACE_IF_NOT_NULL NULL DEFAULT "0" COMMENT '学习次数',
`his_learning_times` int(11) REPLACE_IF_NOT_NULL NULL DEFAULT "0" COMMENT '直播中学习次数',
`his_learned_times` int(11) REPLACE_IF_NOT_NULL NULL DEFAULT "0" COMMENT '回放学习次数',
`his_online_times` int(11) REPLACE_IF_NOT_NULL NULL DEFAULT "0" COMMENT '在线次数',
`finished_at` datetime REPLACE_IF_NOT_NULL NULL COMMENT '完课时间',
`learn_progress` int(11) REPLACE_IF_NOT_NULL NULL DEFAULT "0" COMMENT '学习进度',
`alive_join_type` tinyint(4) REPLACE_IF_NOT_NULL NULL DEFAULT "0" COMMENT '加入方式',
`alive_join_time` datetime REPLACE_IF_NOT_NULL NULL COMMENT '加入时间',
`resource_collection_phone` varchar(128) REPLACE_IF_NOT_NULL NULL DEFAULT "" COMMENT '课程采集手机号',
`is_policies` int(11) REPLACE_IF_NOT_NULL NULL DEFAULT "2" COMMENT '是否有直接权益:1-有效 2-无效',
`is_subscribe` tinyint(4) REPLACE_IF_NOT_NULL NULL DEFAULT "0" COMMENT '是否预约,0-否 1-是',
`subscribe_phone` varchar(128) REPLACE_IF_NOT_NULL NULL DEFAULT "" COMMENT '预约登记手机号',
`is_arrive` tinyint(4) REPLACE_IF_NOT_NULL NULL DEFAULT "0" COMMENT '是否到课,0-否 1-是',
`participate_prize_num` int(11) REPLACE_IF_NOT_NULL NULL DEFAULT "0" COMMENT '参与抽奖次数',
`prize_winner_num` int(11) REPLACE_IF_NOT_NULL NULL DEFAULT "0" COMMENT '中奖次数',
`user_receive_coupon_num` int(11) REPLACE_IF_NOT_NULL NULL DEFAULT "0" COMMENT '直播间领券次数',
`comment_num` int(11) REPLACE_IF_NOT_NULL NULL DEFAULT "0" COMMENT '评论次数',
`sign_num` int(11) REPLACE_IF_NOT_NULL NULL DEFAULT "0" COMMENT '签到次数',
`exceptional_price` int(11) REPLACE_IF_NOT_NULL NULL DEFAULT "0" COMMENT '打赏金额',
`user_total_price` int(11) REPLACE_IF_NOT_NULL NULL DEFAULT "0" COMMENT '直播间成交金额(分)',
`is_learned` int(11) REPLACE_IF_NOT_NULL NULL DEFAULT "0" COMMENT '是否学习 0-否 1-是',
`is_visited` int(11) REPLACE_IF_NOT_NULL NULL DEFAULT "0" COMMENT '是否访问 0-否 1-是',
`policies_end_at` datetime REPLACE_IF_NOT_NULL NULL COMMENT '策略授权结束时间',
`is_online` int(11) REPLACE_IF_NOT_NULL NULL DEFAULT "0" COMMENT '是否在线 0-否 1-是',
`online_change_time` datetime REPLACE_IF_NOT_NULL NULL COMMENT '在线状态变更时间',
`province` varchar(128) REPLACE_IF_NOT_NULL NULL COMMENT '省份',
`city` varchar(128) REPLACE_IF_NOT_NULL NULL COMMENT '城市',
`total_integral` int(11) REPLACE_IF_NOT_NULL NULL COMMENT '累计获得积分',
`is_new_paid` int(11) REPLACE_IF_NOT_NULL NULL COMMENT '是否新成交用户 1-是',
`md5_ip` varchar(128) REPLACE_IF_NOT_NULL NULL COMMENT 'md5加密ip',
`updated_at` datetime REPLACE_IF_NOT_NULL NULL COMMENT '更新时间'
) ENGINE=OLAP
AGGREGATE KEY(`partition_id`, `app_id`, `alive_id`, `user_id`) -- doris根据对应字段聚合、排序和存储数据
COMMENT '直播参与行为'
PARTITION BY LIST(`partition_id`) -- 分区裁剪(Partition Pruning)
(PARTITION p_00 VALUES IN ("0"),
PARTITION p_01 VALUES IN ("1"),
PARTITION p_02 VALUES IN ("2"),
PARTITION p_03 VALUES IN ("3"),
PARTITION p_04 VALUES IN ("4"),
PARTITION p_05 VALUES IN ("5"),
PARTITION p_06 VALUES IN ("6"),
PARTITION p_07 VALUES IN ("7"),
PARTITION p_08 VALUES IN ("8"),
PARTITION p_09 VALUES IN ("9"))
DISTRIBUTED BY HASH(`user_id`) BUCKETS 10
PROPERTIES (
"replication_allocation" = "tag.location.default: 3",
"bloom_filter_columns" = "alive_id, user_id", -- 布隆过滤器:Doris 可以快速判断某个 alive_id 是否不在某个数据块,从而跳过不必要的数据读取。
"colocate_with" = "user_10_group",
"in_memory" = "false",
"storage_format" = "V2",
"disable_auto_compaction" = "false"
);
查询
sql
select alive_id,
count(case when (is_learned = 1 or is_visited = 1) then 1 else null end) as 'uv',
sum(case when (is_learned = 1 or is_visited = 1) then his_online_time else 0 end)/
count(case when (is_learned = 1 or is_visited = 1) then 1 end) as avg_watch_time,
sum(if(is_arrive = 1, 1, 0)) / sum(if(is_subscribe = 1, 1, 0)) as '到课率',
sum(comment_num)
from db_user.dor_participate_alive_user_info_rt
where partition_id = 4
and app_id = 'apphqx3zfwa7174'
group by alive_id
limit 30000;
sql
CREATE TABLE `dor_t_orders_rt` (
`partition_id` tinyint(4) NOT NULL COMMENT 'C端-分区字段,取app_id的最后一位',
`app_id` varchar(64) NOT NULL COMMENT '应用Id',
`order_id` varchar(64) NOT NULL COMMENT '订单Id',
`user_id` varchar(64) NOT NULL COMMENT '用户id',
`alive_id` varchar(64) NULL COMMENT '直播带货-渠道来源',
`content_app_id` varchar(64) NULL COMMENT '内容方应用Id',
`pay_way` int(11) NOT NULL DEFAULT "0" COMMENT '支付渠道 默认0 -1-未指定支付方式 0-线上微信 1-线上支付宝 2-IOS支付 3-安卓支付 4-线下支付',
`payment_type` int(11) NOT NULL COMMENT '付费类型:2-单笔、3-付费产品包、4-团购、5-单笔的购买赠送、6-产品包的购买赠送、7-问答提问、8-问答偷听、9-购买会员、10-会员的购买赠送、11-付费活动报名、12-打赏类型',
`resource_type` int(11) NOT NULL COMMENT '资源类型:0-无(不通过资源的购买入口,如团购)、1-图文、2-音频、3-视频、4-直播、5-活动报名(若payment_type=14时,5-会员)、6-专栏、7-社群、8-大专栏、20-电子书、21-实物商品',
`resource_id` varchar(64) NULL COMMENT '资源物品标识,单笔时为买的资源的id, 付费产品包时为通过哪个资源id而产生的点击购买行为,团购时为团购配置表的id,问答提问和偷听均为问题的id',
`product_id` varchar(64) NULL COMMENT 'payment_type为2时-NULL, payment_type为3时-绑定的付费产品包id,payment_type为4时留空',
`count` int(11) NULL DEFAULT "1" COMMENT '购买数量,默认为1,团购时按实际情况填写',
`channel_id` varchar(64) NULL COMMENT '渠道id',
`channel_info` varchar(64) NULL DEFAULT "" COMMENT '渠道来源',
`share_user_id` varchar(64) NULL COMMENT '若是来自分享,填写分享人的id',
`share_type` int(11) NULL COMMENT '分享类型 0-音频分享 1-日签分享 2-专栏分享 4-邀请卡分享 5-推广分销分享 6- 推广分销平台',
`purchase_name` text NULL,
`img_url` varchar(256) NULL COMMENT '资源配图url',
`cu_id` varchar(64) NULL DEFAULT "" COMMENT '用户优惠券id',
`cou_price` int(11) NULL DEFAULT "0" COMMENT '优惠价格:分',
`discount_id` varchar(64) NULL DEFAULT "" COMMENT '折扣id',
`discount_price` int(11) NULL DEFAULT "0" COMMENT '折扣减免的价格:分',
`price` int(11) NULL COMMENT '价格(分)',
`order_state` int(11) NULL DEFAULT "0" COMMENT '订单状态:0-未支付 1-支付成功 2-支付失败 3-自动退款成功 4-预定(如问答的提问,未使用) 5(未使用) 6-订单过期自动取消 7-手动取消订单 8-主动全部退款中 9-主动全部退款失败 10-主动退款成功',
`goods_type` int(11) NULL DEFAULT "0" COMMENT '商品类型(0-虚拟商品 1-实物商品)',
`ship_state` int(11) NULL DEFAULT "0" COMMENT '发货状态(0-禁止发货 1-待发货 2-已发货 3-已收货) (目前仅用于实物商品)',
`out_order_id` varchar(192) NULL COMMENT '成功支付的外部订单号(out_orders)',
`transaction_id` varchar(64) NULL COMMENT '微信支付交易单号',
`wx_app_type` int(11) NULL DEFAULT "1" COMMENT '数据来源 0-小程序 1-公众号 10-开放平台 11-PC通用版 12-App 13-线下订单 20-抖音小程序 21-app内嵌H5',
`period` int(11) NULL COMMENT '有效期(秒)null则不限时间',
`use_collection` int(11) NULL DEFAULT "0" COMMENT '是否是来自代收 0-否 1-是',
`settle_status` int(11) NULL DEFAULT "0" COMMENT '结算状态(0-未结算;1-结算中;2-结算完成)',
`distribute_type` int(11) NULL DEFAULT "0" COMMENT '是否为分销订单,默认0-普通 1-分销订单',
`distribute_price` int(11) NULL COMMENT '分销提成(分)',
`distribute_percent` int(11) NULL COMMENT '分销比例(百分点1-100)',
`superior_distribute_user_id` varchar(64) NULL COMMENT '上级分销用户id',
`superior_distribute_price` int(11) NULL COMMENT '上级分销提成(分)',
`superior_distribute_percent` int(11) NULL COMMENT '上级分销比例(百分点1-100)',
`related_id` varchar(64) NULL COMMENT '订单关联的id 分销时为t_distribute_detail表的id;若payment_type为问答提问,则存储答主id,若payment_type为13,14时存小团id;活动购票则存票种id',
`is_renew` int(11) NULL DEFAULT "0" COMMENT '是否是续费订单:默认0-普通订单、1-会员续费、2-过期后购买、3-删除后购买',
`invalid_time` datetime NULL COMMENT '取消订单超时时间',
`pay_time` datetime NULL COMMENT '支付时间',
`settle_time` datetime NULL COMMENT '结算时间',
`refund_time` datetime NULL COMMENT '退款时间',
`refund_money` int(11) NULL COMMENT '退款金额',
`source` int(11) NULL DEFAULT "0" COMMENT '0 B端客户订单 1 小鹅通精选订单',
`agent` varchar(512) NULL COMMENT '设备信息',
`created_at` datetime NULL COMMENT '创建时间',
`updated_at` datetime NULL COMMENT '更新时间,有修改自动更新',
`que_check_state` int(11) NULL DEFAULT "0",
`partition` bigint(20) NULL COMMENT '在kafka的分区号',
`offset` bigint(20) NULL COMMENT '在kafka的分区内的偏移量位置',
`event_time` datetime NULL COMMENT 'Kafka记录的时间戳',
`operation_ts` datetime NULL COMMENT 'binlog的时间戳'
) ENGINE=OLAP
UNIQUE KEY(`partition_id`, `app_id`, `order_id`, `user_id`)
COMMENT '内部订单'
PARTITION BY LIST(`partition_id`)
(PARTITION p_00 VALUES IN ("0"),
PARTITION p_01 VALUES IN ("1"),
PARTITION p_02 VALUES IN ("2"),
PARTITION p_03 VALUES IN ("3"),
PARTITION p_04 VALUES IN ("4"),
PARTITION p_05 VALUES IN ("5"),
PARTITION p_06 VALUES IN ("6"),
PARTITION p_07 VALUES IN ("7"),
PARTITION p_08 VALUES IN ("8"),
PARTITION p_09 VALUES IN ("9"))
DISTRIBUTED BY HASH(`user_id`) BUCKETS 10
PROPERTIES (
"replication_allocation" = "tag.location.default: 3",
"bloom_filter_columns" = "alive_id, user_id, order_id",
"colocate_with" = "user_10_group",
"in_memory" = "false",
"storage_format" = "V2",
"function_column.sequence_col" = "offset",
"disable_auto_compaction" = "false"
);