本文导读:
约苗平台是国内目前最大的成人预防接种治理服务平台。近年来,随着各性能的不断完善,用户数量一直增多,越来越多注册数据、疫苗类别点击数据、页面浏览时长等数据被生成和积攒,如何无效利用这些数据进行解决剖析,对于约苗进步工作效率、优化经营决策有着不容小觑的作用。基于此约苗平台历经三代架构演进,最终通过 Apache Doris 重构了数据平台架构,对立了数据源进口,实现了近 300 倍的查问提速,目前已在音讯零碎、经营平台、数据平台、日志零碎中失去宽泛的利用,接入近百亿的数据量,并且在继续减少中。
作者:李俊龙,马太科技(约苗平台)研发工程师
四川马太科技有限公司是一家扎根于疾病防控畛域,具备业余的研发与经营团队的互联网公司,长期致力于改善和晋升中国公众疾病防控程度,助力“衰弱中国 2030”。旗下领有国内用户量最大的成人疾病预防信息与服务平台“约苗”(以下简称“约苗平台”)。“约苗平台”使用互联网+模式流传衰弱科普知识,为疾病防控提供先进的服务和管理工具。围绕公共卫生服务机构的疾病预防业务,发展政策、疾病教育及预约服务。倒退至今已是国内最大的成人预防接种治理服务平台,作为连贯公共卫生服务机构与公众的桥梁,现已连靠近 5000 家公共卫生服务机构和 4000 余万用户,累计提供 2000 余万次疫苗预约服务,并产生科普内容阅读数 3.3 亿次。
业务背景
随着约苗平台各性能的不断完善,用户数量一直增多,越来越多注册、疫苗类别点击、页面浏览时长等数据被生成和积攒,如何无效利用这些数据进行解决剖析,对于进步工作效率、优化经营决策、减少下单率有着不容小觑的作用,因而咱们决定搭建约苗数据架构,通过数据分析处理结果赋能业务倒退,从而进步企业竞争力。
基于此,咱们踏上了数据架构搭建及优化之路,为满足不同场景下的数据处理和剖析需要,相干场景对数据架构提出了以下几点要求:
- 用户行为剖析 : 通过用户浏览内容或页面的时长进行用户分层、把握用户行为爱好,通过对新用户的增量和用户活跃度进行统计,以便工作人员调整经营策略,进步用户留存率和活跃度。在该场景下,要求所有查问须要在 5s 内返回后果。
- 平台告诉: 约苗平台音讯推送服务蕴含 App 推送、内置告诉、短信、信公众号推送,在该场景下,冀望可达到毫秒级查问响应,解决 **C 端告诉查问提早的问题。
- 市场报表统计: 市场部每天需对相干业务进行报表统计,但因为数据量微小,通常会呈现查问速度较慢的问题,这将重大影响产出计算,冀望能够实现秒级查问响应。
为了满足要求,约苗的数据架构曾经经验了三代演进。第一代架构基于 Elasticsearch,第二代架构引入了 ClickHouse,目前正在应用的是基于 Apache Doris 的第三代架构。本文将具体介绍这三代架构的演进历程和搭建教训。
基于 Elasticsearch 的第一代架构
第一代数据架构是基于 Elasticsearch 来构建的,次要用于解决来自业务各零碎和日志零碎的数据。其中,业务数据首先存储在 MySQL 中,而后应用 Flink CDC 对 MySQL Binlog 监听,将数据同步到 Elasticsearch 中。当展现层发动聚合申请时,Elasticsearch 中的数据进入聚合层对应的服务中实时计算,最终将后果输入到展现端。
架构搭建完后咱们立刻投入生产来验证成果,但在应用中咱们发现 Elasticsearch 在高并发读取和写入的过程中提早十分高,而为改善该问题,咱们又增设了多套集群配置,但依然于事无补。除此之外,Elasticsearch 得数据查问性能也会随着数据增长而降落。在这个状况下,如果想要进步 Elasticsearch 响应速度,还需进一步减少集群配置,以进步 Elasticsearch 集群负载能力,老本投入十分大。
引入 ClickHouse 的第二代架构
基于上述问题,咱们对架构进行了降级。为防止架构演进对代码带来过大冲击,咱们保留了第一代架构中根本的数据同步逻辑,在其根底上减少了 Apisix、Kafka、ClickHouse 同步流程,在此基础上对 Flink 同步流程进行了优化。为了升高 Elasticsearch 的压力,咱们将日志数据、行为数据和文件系统数据进行了整体的迁徙都 ClickHouse。在 ClickHouse 同步流程中,咱们应用 APISIX 的 Kafka-Logger 对行为采集和日志零碎的数据进行间接上报,应用同步工具对上报数据进行荡涤过滤,最终存储到 ClickHouse 中。在应用 Flink 同步时,咱们引入了 RabbitMQ 音讯组件来保障数据同步的稳定性(因历史起因未应用 Kafka,倡议尽量应用对立的音讯队列组件)。
在应用过程中咱们发现 ClickHouse 性能诚然强悍,但须要一直进行调优,工程师的学习老本十分高,同时随着用户的体量的一直回升,用户活跃度的继续进步,ClickHouse 的运维治理和调优老本也逐渐攀高。而过高的集群压力再次导致 C 端局部业务呈现数据同步和查问呈现长达 5s 的提早,这仍旧没有解决基本问题。
基于 Doris 的新一代架构
抉择 Doris 的起因
为彻底解决晚期架构呈现的问题,咱们进行了深度调研,旨在抉择更适宜咱们的实时数据仓库。在初步理解后,咱们首先放弃了 Hadoop。一方面,Hadoop 的开发和运维难度较大,会减少咱们的工作量;另一方面,Hadoop 更适宜解决大数据量的批处理场景,而咱们须要反对流批一体,以解决 C 端用户的查问提早较高的问题。进一步理解之后,咱们排除了 Kudu 选项。这是因为 Kudu 应用老本十分高,特地是在没有主键的状况下,Kudu 会占用大量存储资源。此外,个别状况下,为了满足读性能,Kudu 会就义写性能,这与咱们的业务需要不符。在多方面的理解和比照后,咱们发现 Apache Doris 最合乎咱们的要求,因为 Doris 具备以下劣势:
- 反对更灵便的查问:Doris 能够反对灵便且多变的数据分析需要,以满足需要方针对不同群体高频次的营销流动。
- 反对联邦查问:Apache Doris 1.2 版本推出了多源数据目录(Multi-Catalog)通过简略的命令便能够不便地连贯到各自内部数据源并主动同步元数据,实现数据进口对立,实现对立的剖析体验。
- 查问性能优异:Doris Join 能力弱小,依靠列式存储引擎、古代的 MPP 架构、向量化查问引擎、预聚合物化视图、数据索引的实现,在低提早和高吞吐查问上,都达到了极速性能。
- 运维难度低:Doris 对于集群和和数据正本治理上做了很多自动化工作,使得集群运维起来十分的简略,简直能够实现零门槛运维。与此同时,Apache Doris 社区十分沉闷,响应迅速,并且 SelectDB 为社区提供了一支专职的工程师团队,收费为用户提供技术支持服务。
数据架构的重建
引入 Doris 后,咱们对数据架构进行了重构,Doris 的地位及作用可从上方架构图得悉。
由图可知,Doris 的数据起源十分多样化,包含通过 Flink-CDC、Binlog 的业务数据,经由 Kafka 的行为数据和日志数据,以及从自研的全量 / 增量工具同步的其余数据。此外,还有局部通过 Doris Stream Load 和 Routine Load 同步的数据。这些来自不同工具的数据对立由 ETL 解决,最终存储到 Kafka 或 Doris 集群中。其中存储到 Kafka 中的数据会通过 Routine Load 高效写入到 Doris 中,最终由 Doris 对立提供数据服务。Doris 的引入解决了各类同步工具的数据源对立的问题,不再须要保护大量配置,而对立数据进口也让数据处理变得更加简略和高效。
在新一代架构中,Doris 已齐全取代了 ClickHouse,相比于 ClickHouse,Doris 具备更好的性能和更宽泛的适用性,在约苗所服务的业务已逐渐从统计分析扩大到业务零碎。基于 Doris 的高性能、高并发的反对,约苗平台的用户端相干业务提早问题也失去了胜利解决,使得数据查问和剖析更加及时和精确。
新数据架构搭建教训
在新架构的应用过程中,咱们积攒了许多实践经验,心愿可能与大家分享。以下是咱们总结进去的一些教训:
Routine Load 实现 数据疾速导入
在数据导入方面,咱们强烈建议应用 Stream Load 和 Routine Load 这两种工具,因为它们的性能远远高于其余导入形式。
Stream Load 和 Routine Load 是 Doris 常见的两种数据导入形式,Stream load 是一个同步的导入形式,用户通过发送 HTTP 协定发送申请将本地文件或数据流导入到 Doris 中。Routine Load 性能反对用户提交一个常驻的导入工作,通过一直的从指定的数据源读取数据,将数据导入到 Doris 中。
咱们已经尝试过其余的数据导入形式,通过屡次压力测试和性能比照,并联合咱们的理论数据类型,最终抉择了 Stream Load 和 Routine Load 进行数据导入。Routine Load 是一种高效、稳固的数据导入工具,它依赖于 Kafka 并具备极好的可靠性。与其余数据导入形式相比,Routine Load 反对的配置丰盛,可能依据配置来过滤和合并数据,同时须要开明的网络策略也更少,可能很好地满足同步数据的需要。最重要的是,Routine Load 能够达到每分钟数百万行的数据导入,完全符合咱们对数据导入速度的要求。
在应用 Routine Load 进行数据导入时,难免会呈现全量和增量数据同时同步的状况,或者在多线程生产下呈现数据积压的状况,这就须要保证数据的一致性。因而咱们能够通过 Doris 反对的 Sequence 列来保证数据的一致性,用户能够在导入时指定 Sequence 列,雷同 Key 列下,REPLACE 聚合类型的列将依照 Sequence 列的值进行替换,较大值能够替换较小值,反之则无奈替换。该办法将程序的确定交给了用户,由用户管制替换程序。具体的实现形式如下:
- 在定义表时,先定义一个列,比方定义为
order_id
。 - 接着在创立 Routine Load 时指定依据
order_id
列进行写入,以保证数据写入程序。 - 在写入数据时,须要保障每条数据都领有
order_id
列有值。 - 在进行全量同步时,能够应用
Java-sync
来实现,全量同步时须要保障order_id
始终为 0。 - 在进行增量同步时,能够应用读取 Binlog 的形式进行同步,增量同步的
order_id
须要从 1 开始。另外能够记录增量同步的order_id
值,以保证数据精确写入 Unique 表。
分辨别桶 和查问实际
在应用 Doris 进行数据存储时,建表时须要尽量贴近理论应用场景,以此来创立分区列和分桶列。这里将分享咱们咱们在创立表时的一些教训。
- 分区:分区是建设一张大表时十分要害的因素,它间接影响到能够检索到的数据大小和须要解决的数据量。如果一个分区的数据量太大,那么就须要更多的 CPU 和内存来解决,从而导致查问效率升高。如果利用工夫分区,能够思考应用动静分区来让 Doris 自行治理分区。动静分区能够依据工夫主动创立新的分区,并删除旧的分区,从而保持数据的最新性和存储效率。同时,动静分区还能够帮忙咱们保留局部数据或者辨别冷热数据,从而更好地治理数据存储和查问。
- 分桶:思考在一个分区下如何让分桶足够平衡,是每个表必须要做的事件。如果分桶列数太多,可能会影响点查问的性能,如果分桶不够平衡,查问速度会受到最大桶解决工夫的影响。因而须要在性能和查问需要之间做出取舍。另外,举荐大家应用 Apache Doris 1.2.2 版本的 Auto Bucket 主动分桶推算性能,分桶个数不再依赖于人工设置,通过规定的智能计算即可保障正当的数据划分,升高用户学习老本的同时还能够最大化晋升用户开发效率。
举例来说,当咱们须要记录行为记录宽表时,个别会应用 Duplicate 模型进行记录。在建表时,咱们能够把report_time
、event_id
、product_id
、plate_id
、user_id
作为 Key 列,并应用 report_time
按月进行动静分区,每月记录数据 1.5 TB 左右,应用 product_id
、plate_id
、event_id
进行主动分桶。
在应用过程中咱们发现,当某一类事件远远超过了其余事件的总数时,会重大导致数据歪斜重大。为了解决这个问题,咱们减少了在分桶列后新增了user_id
,从而达到了数据平衡的成果。通过这一优化,查问速度由原来的 13s 晋升到 5s。另外咱们在这个根底上应用了物化视图进一步对查问性能进行优化,物化视图染指之后,查问速度从 5 秒晋升到毫秒级别。
Doris 在约苗的利用实际
灵便组合查问,进步广告投放效率
因为疫苗的特殊性,业务侧同学在推广的过程中须要更精准的用户信息,例如年龄、性别、地区等业务同学指定的信息。这种状况下,数据平台就须要提供具体的用户群体信息,以帮忙业务同学实现精细化信息触达。
在接入 Doris 后,咱们次要利用 Doris 的 Join 实现了一套齐全能够反对任意字段组合查问的工具。相似于常见的 SQL 管理工具,不同的是,无需自行编写 SQL,只需抉择须要的字段进行组合配置即可查问,失去想要的后果,以此来满足需要多变的业务场景,从而进步业务侧工作效率。同时,Doris 还具备高效的数据写入和查问能力,使得经营人员能够更加疾速地获取所需数据,进行数据分析和利用开发。
基于此,业务同学能够通过多种业务数据联结检索,疾速筛选出满足本人需要的用户信息,并导出最终检索后果。例如,能够对年龄在 19 岁至 45 岁之间,浏览过 HPV 九价疫苗页面并且页面停留时长大于 1 分钟的用户数据进行检索,并导出后果。通过这一形式,业务同学能够疾速获取指标用户信息,从而精准地进行营销推广和流动推送。
联邦查问实际 ,百万数据分钟级导入
在应用 Doris 之前,某些业务场景须要数据组的共事自行编写大量简单代码来实现数据导入工作。在接入 Doris 之后,咱们利用 Muti-Catalog 性能建设了 ES 和 MySQL 的表面,在遇到数据导入工作时,咱们仅须要花几分钟工夫编写 SQL,依附 Doris 疾速实现数据导入工作。同样的数据导入工作(80 万数据的)之前须要 1 -2 天的工夫实现,而应用 Doris 之后,仅仅须要几分钟即可实现数据导入。
除此之外,Apache Doris 提供的 Multi Catalog 性能也帮忙咱们的对立了来自多种同步工具的数据源,胜利对立了数据进口,使得数据处理变得更加简略和高效,同时咱们也无需投入过多的人力和精力去保护大量其余数据相干的配置,极大的节约了老本的投入。
Join 能力加持,实现 300 倍查问速度晋升
除此之外,Doris 的 Join 性能非常优异,当 Doris 集群实现业务数据的全同步后,咱们对 1 亿 和近百亿的两张表进行 Join 操作,能够在 5 秒内输入数据后果,相较之前有靠近 300 倍的查问速度晋升。为了验证其是否偶尔,咱们接着对 10 张别离有 4000 万数据的表进行 Join,Doris 能够在 10s 内返回查问后果。而在物化视图加持下,能够达到毫秒级别的查问响应。这充分说明了 Doris 在解决大规模数据的劣势。
极低运维老本,助力降本提效
在之前的架构中,咱们应用 ClickHouse 进行数据存储和查问,并且须要独自保护 Zookeeper 来治理集群的配置信息和状态信息,这些都减少了零碎的运维老本和难度。而 Doris 架构简略,只有 FE 和 BE 两个过程,扩缩容快捷不便,运维难度和老本失去极大的升高,此外,Doris 还提供了更加敌对和易用的数据备份和复原性能,可无效保障数据的安全性和完整性。
总结布局
以后约苗曾经基于 Apache Doris 搭建了一套残缺的实时数据仓库,并在音讯零碎、经营平台、数据平台、日志零碎中失去宽泛的利用,目前曾经接入百亿级别的数据量,并且在继续减少中。将来咱们将基于 Doris 一直摸索,扩充 Doris 应用范畴,逐步推广至秒杀、订阅、黑名单、预约等各个业务场景,同时咱们也将尝试应用 Doris 的新个性,以实际后果回馈社区,为社区倒退献一份力,为社区做出实质性的奉献。
最初,感激 SelectDB 技术团队长期以来疾速响应和技术支持,为咱们稳固高效利用 Doris 保驾护航。