作者介绍: 马成,慧策 JAVA 高级研发工程师
慧策(原旺店通)是一家技术驱动型智能批发服务商,基于云计算 PaaS、SaaS 模式,以一体化智能批发解决方案,帮忙批发企业数字化智能化降级,实现企业规模化倒退。凭借技术、产品、服务劣势,慧策现已成为行业影响力品牌并被批发企业宽泛认可。2021 年 7 月,慧策实现最新一轮 D 轮 3.12 亿美元的融资,累计实现四轮逾 4.52 亿美元的融资,与诸多国内一流企业、行业头部企业并列而行,被寰球顶尖投资公司看好。
业务需要
慧经营是一款数据分析产品,次要提供经营剖析、经营剖析、应收对账三大性能,面向企业的经营、经营、财务三个角色。如图所示,慧经营上游为常见的电商平台、直播平台以及慧策次要的产品旺店通,这些平台在交易过程中会产生大量的数据,包含支出、老本以及多种费用相干的数据。这些数据都比拟扩散,如果客户手动进行数据汇总和剖析,过程繁琐、难度较高且展现不够直观。而慧经营能够在客户受权下获取、汇总这些数据,依据客户需要提供经营剖析、报表生成、账单汇总等多项数据分析服务,以帮忙客户更好地经营店铺。
为了能承载上述数据相干的服务,咱们在零碎架构设计之初须要思考以下几点:
- 低成本:慧经营的付费模式为按需付费,这要求架构必须具备轻量化、易保护的个性。基于这点思考,首先排除基于 Hadoop 的生态架构,尽管 Hadoop 足够成熟,然而组件依赖度较高、繁琐简单,无论是运维老本还是应用老本都十分高。
- 高性能:电商数据为慧经营的次要数据起源,数据维度丰盛,ETL 复杂度高;另外,在很多应用场景中明细查问与聚合查问是并存的,既须要够疾速定位数据范畴,又须要高效的计算能力,因而须要一个弱小的 OLAP 引擎来撑持。
- 正当资源分配:客户规模差别较大,有月单量只有 1 万的小客户,也有月单量高达千万级别的大客户,资源正当调配在这样的场景下异样重要,因而要求 OLAP 引擎能够在不影响用户体验的前提下,能够依据客户的需要进行资源分配,防止大小查问资源抢占带来的性能问题。
- 高并发:可能接受上游平台多起源、高并发的大量数据的简单 ETL,尤其在 618、双 11 这样的业务高峰期,须要具备高效查问能力的同时,可能承当大量的写入负载。
架构演进
架构 1.0
基于以上思考,咱们在架构 1.0 中引入 Clickhouse 作为 OLAP 引擎。从上图可看出该架构是一个齐全基于后端 Java 以及 Spring 的技术架构,通过 Binlog 同步的形式通过 Canal 和 Kafka 将数据从 MySQL 同步至 Clickhouse,来承接前端的各种经营剖析报表服务。
架构 1.0 在上线不久后就遭逢了慢查问问题。在晚期客户和数据量较少时,查问性能尚可满足客户需要,然而随着数据量的一直增大,受限于 MySQL 自身的个性,ETL 效率逐步低到无奈令人承受,尤其在面对大客户场景时,即便命中索引、扫描数据范畴仅在百万级别,MySQL 应答该场景也已非常吃力。其次,面对激增的数据,ClikHouse 的多表 Join 也遭逢性能问题,因为其简直不反对分布式 Join,只管提供了 Join 语义、但在应用上对多表 Join 的撑持较弱、简单的关联查问经常会引起 OOM。
在 ClickHouse 单机性能不能撑持业务时,咱们思考扩大搭建集群以进步性能,而 ClickHouse 分布式场景须要依赖 Zookeeper,同时须要独自保护一套分布式表,这将使运维治理的难度和老本一直升高。
除此之外,ClickHouse 还有几个较大的问题,背离了咱们最后对架构的选型要求:
- 不反对高并发,即便一个查问也会用服务器一半的 CPU。对于三正本的集群,通常会将 QPS 管制在 100 以下。
- ClickHouse 的扩容缩容简单且繁琐,目前做不到主动在线操作,须要自研工具反对。
- ClickHouse 的 ReplacingMergeTree 模型必须增加 final 关键字能力保障严格的唯一性,而设置为 final 后性能会急剧下降。
架构 2.0
咱们在架构 2.0 中引入 Apache Doris 作为 OLAP 引擎,并进行了一次整体的架构降级。抉择 Apache Doris 的次要起因有如下几条:
- 应用成本低: 只有 FE 和 BE 两类过程,部署简略,反对弹性扩缩容,不依赖其余组件,运维老本非常低;同时兼容 MySQL 协定 和规范 SQL,开发人员学习难度小,我的项目整体迁徙应用老本也比拟低。
- Join 性能优异: 我的项目存在很多历史慢 SQL,均为多张大表 Join,Apache Doris 良好的 Join 性能给咱们提供了一段优化革新的缓冲期。
- 社区活跃度高: 社区技术气氛浓重,且 SelectDB 针对社区有专职的技术支持团队,在应用过程中遇到问题均能疾速失去响应解决。
如上图所示,咱们将本来基于 MySQL 的根底数据存储迁徙到 Doris 中,同时将大部分的 ETL 迁徙至在 Doris 外部进行,MySQL 只用于存储配置信息。同时引入了 Flink,DolphinScheduler 等组件,胜利构建了一套以 Doris 为外围、架构简洁、运维简略的数据生产体系。
全新的架构也给咱们带来的显著的收益:
- ETL 效率极大晋升:慧经营的数据维度丰盛、ETL 复杂度高,得益于 Apache Doris 弱小的运算能力及丰盛的数据模型,将 ETL 过程放在 Doris 外部进行后效率失去显著晋升;
- Join 耗时大幅升高:查问性能同样失去极大晋升,在 SQL 未通过革新的状况下,多表 Join 查问耗时相较于过来有了大幅升高。
- 并发表现出色:在业务查问高峰期可达数千 QPS,而 Apache Doris 面对高并发查问时始终体现安稳;
- 存储空间节俭:Apache Doris 的列式存储引擎实现了最高 1:10 的数据压缩率,使得存储老本失去无效升高。
- 运维便捷:Apache Doris 架构简略、运维成本低,扩容降级也十分不便,咱们前后对 Doris 进行了 3 次降级扩容,根本都在很短的工夫内实现。
在应用 Apache Doris 的过程中,咱们对 Doris 如何更好地利用也进行了摸索,在此期间总结出许多实践经验,通过本文分享给大家。
实际利用
分辨别桶优化
在执行 SQL 时,SQL 的资源占用和分辨别桶的大小有着亲密的关系,正当的分辨别桶将无效晋升资源的利用率,同时防止因资源抢占带来的性能降落。
因而咱们在建设事实表分区时,会依据客户的数据规模提供相匹配的分区计划,比方数据规模较小按年分区、规模大按月分区。在这种分区形式下,能够无效防止小查问占用过多资源问题,而大客户的应用体验也因为细粒度的分区形式失去了晋升。
CREATE TABLE DWD_ORDER_... (...)
...
PARTITION BY RANGE(tenant,business_date)
(PARTITION p1_2022_01_01 VALUES [("1", '2022- 01- 01'), ("1", '2023- 01- 01')),
PARTITION p2_2022_01_01 VALUES [("2", '2022- 01- 01'), ("2", '2022- 07- 01')),
PARTITION p3_2022_01_01 VALUES [("3", '2022- 01- 01'), ("3", '2022- 04- 01')),
PARTITION p4_2022_01_01 VALUES [("4", '2022- 01- 01'), ("4", '2022- 02- 01')),
...
)
而分桶的设置上咱们采纳了最新版本中减少的主动分桶推算性能,应用形式十分便捷,不必再去测算和预估每张表的数据量以及对应 Tablet 的增长关系,零碎主动帮忙咱们推算出正当分桶数,晋升性能的同时也使得系统资源失去更好利用。
参考文章:一文教你玩转 Apache Doris 分辨别桶新性能|新版本揭秘
多租户和资源隔离计划
在 SaaS 业务场景中,多租户和资源划分是架构设计过程中必不可少的局部。多租户(Multi-Tenancy)指的是单个集群能够为多个不同租户提供服务,并且仍可确保各租户间数据隔离性。通过多租户能够保证系统共性的局部被共享,共性的局部被独自隔离。
对于咱们来说,客户规模差别较大,有月单量只有 1 万的小客户,也有月单量高达千万级别的大客户,资源的正当调配与隔离在这样的场景下异样重要。如果为每个租户创立一个数据库集群,则集群规模不可控且造成资源节约。如果多个租户共享一套数据库集群,用户的需要能够互相弥补,总体来时能够有很大的资源节约,并且计算规模越大老本越低,而在应答客户查问时,能够依据客户的数据规模和查问需要将资源池划分给各客户。
这里咱们采纳了 Apache Doris 的节点资源组来辨别大小客户,防止了不同租户以及查问间的资源抢占问题。
节点资源组划分
节点资源划分指将一个 Doris 集群内的 BE 节点设置标签(Tag),标签雷同的 BE 节点组成一个资源组(Resource Group),资源组能够看作是数据存储和计算的一个治理单元。数据入库的时候依照资源组配置将数据的正本写入到不同的资源组中,查问的时候依照资源组的划分应用对应资源组上的计算资源对数据进行计算。
例如咱们将一个集群中的 3 个 BE 节点划分为 2 个资源组,别离为资源组 A 和资源组 B,BE-1 和 BE-2 属于资源组 A,BE-3 属于资源组 B。资源组 A 有 2 正本的数据,资源组 B 有一个正本的数据。那么当客户 A 在写入数据和查问数据的时候会依照资源组配置应用资源组 A 上的存储和计算资源,当客户 B 写入数据和查问数据的时候会依照资源组配置应用资源组 B 上 的存储和计算资源。这样便能能很好的实现同一个集群,为不同租户提供不同的负载能力。
具体操作如下:
- 设置标签:
为 BE 节点设置标签。假如以后 Doris 集群有 3 个 BE 节点。别离为 host[1-3]
。在初始状况下,所有节点都属于一个默认资源组(Default)。
咱们能够应用以下命令将这 6 个节点划分成 3 个资源组:group_a
、group_b
:
alter system modify backend "host1:9050" set ("tag.location" = "group_a");
alter system modify backend "host2:9050" set ("tag.location" = "group_a");
alter system modify backend "host3:9050" set ("tag.location" = "group_b");
这里咱们将 host[1-2]
组成资源组 group_a
, host[3]
组成资源组 group_b
。
- 设置资源组数据调配策略
正本散布策略定义:资源组划分好后,咱们能够将客户数据的不同正本散布在不同资源组内。假如一张用户表 UserTable。咱们心愿资源组 A 内寄存 2 个正本,资源组 B 寄存 1 分正本
create table UserTable (k1 int, k2 int)
distributed by hash(k1) buckets 1
properties("replication_allocation"="tag.location.group_a:2, tag.location.group_b:1")
资源组绑定:通过设置客户的资源组应用权限,来限度某一客户的数据导入和查问只能应用指定资源组中的节点来执行。
set property for 'user_a' 'resource_tags.location' = 'group_a';
set property for 'user_b' 'resource_tags.location' = 'group_b';
这里将 user_a
和 group_a
资源绑定,user_b
和 group_b
资源绑定。绑定实现后,user_a
在发动对 UserTable 表的查问时,只会拜访 group_a
资源组内节点上的数据正本,并且查问仅会应用 group_a
资源组内的节点计算资源。
通过 Apache Doris 提供多租户和资源隔离计划,可能将集群资源更正当的调配给各 客户 ,能够让多租户在同一 Doris 集群内进行数据操作时,缩小相互之间的烦扰,同时达到资源老本的无效升高。
高并发场景的反对
高并发也通常是 SaaS 服务场景面临的挑战,一方面是慧经营曾经为泛滥客户提供了剖析服务,须要去同时承载大规模客户的并发查问和拜访,另一方面,在每日早晚业务高峰期也会面临更多客户的同时在线,通常 QPS 最高可达数千,而这也是 Apache Doris 体现得十分杰出的中央。在上游 Flink 高频写入的同时,Apache Doris 体现极为安稳,随着查问并发的晋升,查问耗时相较于平时简直没有太大的稳定。
应答高并发场景的关键在于利用好分辨别桶裁剪、索引、缓存等零碎机制来缩小底层数据扫描。在 Doris 中会将数据表的前几列作为排序键来构建前缀索引,同时还有 ZoneMap 以及 Bloom Filter 等索引。在执行查问时,通过分辨别桶裁剪以及索引能够疾速过滤到不在查问范畴内的数据,缩小 CPU 和 IO 的压力。
在与社区的沟通中还理解到,行将公布的新版本还将进一步晋升并发反对,引入行存储格局、短门路优化以及预处理语句等来实现上万 QPS 的超高并发,能够满足更高并发要求的 Data Serving 场景,这也是咱们非常期待的性能。
数据生命周期治理
咱们自研了一套生命周期管理工具,基于资源的调配,能够提供客户级定制化冷却策略。依据各个业务场景的客户需要及付费状况,提供不同长度的数据保留策略,同时得益于 Apache Doris 提供的 OutFile 性能,实现删除或者导出 S3 两种冷却形式,当咱们再次须要这些数据时,可通过 Load 的形式从 S3 导回数据。
除了通过 OutFile 将数据文件导出至 S3 以外,社区在后续版本中还将提供分区级别的冷热数据拆散策略。以后咱们数据分区都是基于日期范畴来设置,因而能够利用工夫分区进行冷热数据的划分。通过配置分区级别的 Freeze Time,转冷后的历史数据能够主动下沉至老本更低的对象存储上。在面对历史冷数据的查问时,Doris 会主动拉取对象存储上的数据并在本地 Cache 以减速查问,而无需执行导入操作。通过冷热数据拆散以及冷数据 Cache,既能保障最大水平的资源节俭,也能保障冷数据的查问性能不受影响。
总结布局
收益
引入 Apache Doris 之后,新架构的整体查问响应速度都有了较大的晋升,存储老本显著升高,后续咱们将持续摸索 Doris 新个性,进一步实现降本增效。
布局
- 目前正在强化 Apache Doris 的元数据管理建设,咱们心愿通过该服务能更好的帮助开发人员应用 Doris,包含数据血统追踪等;
- 尝试应用更多 Apache Doris 的新性能,在 1.2.0 版本中新增的 Java UDF 性能能够极大升高数据出入库的频率,更便捷地在 Doris 外部进行数据 ETL,这一性能咱们正在尝试应用中;
- 摸索更好的资源分配计划,包含 SQL 代理以及尝试 Doris 后续提供的 Spill 性能,以更好进行资源分配利用。
最初,再次感激 Apache Doris 社区和 SelectDB 技术团队在咱们应用过程中提供的许多领导和帮忙,提出问题都会及时的响应并尽快帮助解决,将来咱们也心愿深度参加到社区建设中,为社区的倒退出一份力。