StarRocks 存算分离在得物的降本增效实践

编者荐语:

得物优化数据引擎布局,近期将 4000+ 核 ClickHouse 迁移至自建 StarRocks,成本降低 40%,查询耗时减半,集群稳定性显著提升。本文详解迁移实践与成果,文末附丁凯剑老师 StarRocks Summit Asia 2024 主题演讲视频。

背景

OLAP 引擎在得物的客服、风控、供应链、投放、运营、AB 实验等大量业务场景发挥重要作用,在报表、日志、实时数仓等应用场景都有广泛的应用。

得物引入和使用 OLAP 引擎的过程中,每个业务都基于自己的需求选择当时最适合自己的引擎。现在得物内部同时使用阿里云上的 Hologres、ADB、ClickHouse 与ECS 自建的开源 ClickHouse 与 StarRocks 5 种引擎产品,从业务使用成本和运维维护的角度长远看都是不利的。

2024 年,我们开始向只保留 1 到 2 个引擎的方向努力。最近,我们把一套 4000+ 核的业务,最复杂的 ClickHouse 集群迁移到了存算分离的自建 StarRocks 上,成本节约 40%,查询耗时降低一半,单节点不可用导致的集群不可用耗时从 15 分钟减少到了 30s。

ClickHouse 在大数据量下的困境

ClickHouse 虽然单机性能首屈一指,但分布式架构存在水平扩展性、元数据管理、数据一致性、join 查询性能等一系列问题。被迁移的这个 ClickHouse 集群服务于得物的智能运营平台,使用了超过 4000 核,存储超过 500TB。随着业务增长,集群面临一些实际问题。

物化视图缺乏透明改写能力

智能运营平台日常需要查询周/月/季/年 环比/同比,查询时间跨度长,并且为了加速查询建立了 40+ 物化视图。ClickHouse 没有自动的透明物化视图改写能力,需要由外部代码主动管理、创建物化视图和改写 SQL 去查询物化视图。在需要重刷历史数据时,由外部代码管理的物化视图的重刷尤为复杂。

缺乏离线导入功能

开源 ClickHouse 缺少 bulkload 能力,智能运营需要每天从离线平台导入大量数据到 ClickHouse,导入链路存在格式转换,效率低的问题并且会占用大量 ClickHouse 集群资源,导入链路的数据产出有时会晚于基线。

图片

扩容困难

虽然使用了很多物化视图,但集群负载仍然开始接近硬件能力上限。业务想要继续扩容,但面临了两个问题:

  1. 垂直扩容没有空间:集群使用的 ClickHouse 单机规格已经是顶配,没有升配空间

  2. 水平扩容停机需停机一周:因为 ClickHouse 水平扩容后为了查询正确性考虑,已经按指定字段分桶的表,需要重新导入数据才能正确的 resharding,这个过程需要一周的停服扩容和导入。

业务方只能搭建了一个小一些的备份集群,存储最核心的数据,与主集群构成双活来分流部分查询,来减小主集群负载,这样增加了 50%+ 成本

在得物增加了对 StarRocks 的研发投入后,智能运营下定决心基于 StarRocks 存算分离做 POC,并最终顺利迁移到自建的 StarRocks 上。

基于 StarRocks 降本增效

存算分离带来成本下降

StarRocks 3.0 起支持存算分离,在 3.3 版本已经比较成熟了。

StarRocks 存算分离架构:

图片

(CN 是 Compute Node,是无状态计算节点+本地缓存盘)

1.1 安全可靠使用的单副本

对比存算一体的 3 副本模式,存算分离使用单副本。存算分离的全量数据数据存储在远端对象存储上(上图的 Distributed Storage,我们使用的是阿里云的 OSS),即使 CN 节点挂了,其他 CN 节点也仍然可以查询到数据(虽然需要重新拉取缓存数据,查询耗时会增加),所以是可以安全可靠使用的单副本模式。这带来 2/3 的存储成本下降(本地盘只作为 data cache 之用)。

1.2 只缓存必要数据

并且存算分离不需要把所有的数据都存储在本地盘,而只需要缓存常用数据即可,在单副本之上又节省大笔存储成本,并且查询性能在使用本地缓存后能做性能一致。

并且大量使用物化视图,减少基表实际需要存储在 data cache 中的数据量

图片

上图说明 506TB 的数据实际只在缓存中存储了 342TB

经过评估存算分离部署模式能带来 40%+ 的成本下降,存储成本下降 1 - (1/3*3/5)=4/5。

1.3 扩缩容无需搬迁数据

StarRocks 存算一体可以任意水平扩容,无需停机,扩容后自动均衡搬迁数据。

StarRocks 存算分离更做到了扩缩容无需搬迁数据,扩容的新节点马上就可以被利用,这在使用容器方案部署 StarRocks 时,尤为方便。

在复杂 SQL join 能力上大幅领先 ClickHouse

图片

https://docs.starrocks.io/zh/docs/benchmarking/SSB_Benchmarking/

StarRocks 更适合星型模型,并且 StarRocks 与 ClickHouse 单表查询性能不相伯仲(数据来源:clickbench 单机性能测试 https://benchmark.clickhouse.com/)

ClickHouse 支持的 join 类型非常有限且使用复杂,StarRocks 支持各种 Join 类型且符合标准 SQL 语法的预期,这让用户无需特别关注 Join 的特殊写法带来的性能问题(指 ClickHouse 的分布式和 local 表 join 问题),专注于业务逻辑即可。

高效的离线导入

从 ClickHouse 换成 StarRocks 后,离线导入的流程发生了变化。

首先在离线平台新建一个 OSS 外表,然后执行离线平台的 insert sql select 语句从离线平台读取数据以 parquet 格式写入到 OSS 外表中,然后 StarRocks 从对象存储(OSS)直接 broker load 导入数据。对比 ClickHouse 只能 insert 导入,虽然还是使用 StarRocks 集群资源,但通过控制 Broker Load 并发可以把集群资源的消耗控制在可接受范围内。压测显示离线导入耗时比 ClickHouse 方案减少 2/3

图片

重度使用物化视图进行提效

4.1 透明物化视图改写

查询可以自动透明改写到物化视图,用户无需改 SQL,并且保证数据的正确性。以往需要用户在外围主动管理 ClickHouse 物化视图构建,数据重刷和查询改写,这引入了额外的复杂性。现在物化视图由 StarRocks 自管理,不再需要外部代码主动改写,减少了出错的可能,也提供了不侵入用户逻辑即可提升性能的方式。

4.2 使用技巧

1、不命中物化视图时,在资源组中限制大表时间跨度超过8天就不允许查询。

图片

2、approx_count_distinct 改写成 hll_union_agg(hll_hash(col)) 让查基表与查物化视图的结果完全一致

3、使用明细物化视图减少数据读取量

4、物化视图只基于单表,方便在各种 join sql 语句中复用

5、一个物化视图包括尽量多的指标,查询时一次性查多个指标

6、materialized_view_rewrite_mode=‘force‘ 让一个查询中多个 countdistinct也能命中物化视图

图片

4.3 物化视图推荐

手工对 SQL 分析和创建物化视图毕竟效率有限,所以我们开发了物化视图推荐功能。

1、通过在 FE 中记录 SQL 结构,在外部实现基于单表的物化视图推荐程序

2、能做到对表/物化视图字段的在过滤条件中的命中次数进行统计,用来判断哪些字段做排序键能适配更多的查询

图片

3、能做到对单表的子语句用到的指标和维度列进行分析,找到有高收益的潜在物化视图,并且排除已经存在的物化视图。

4、物化视图启用 collocate group

现在物化视图推荐功能已经初步上线,并还在持续优化中。

4.4 优化选择策略和性能

1、优化选择的性能,跳过物化视图与无关表的匹配(https://github.com/StarRocks/starrocks/pull/51010)。

2、提早剔除一些不包含查询需要的列的物化视图,减少了后续匹配测试的开销(https://github.com/StarRocks/starrocks/pull/51044)。

3、优先选中排序键匹配查询过滤条件的物化视图,再优先选行数最少的物化视图(https://github.com/StarRocks/starrocks/pull/51511)。

4.5 扩展物化视图可用场景

物化视图作为提升查询性能的最关键也是最有效的手段,在 3.3 刚发布时存在一些 BUG,导致很多场景下物化视图不能被命中。其中社区帮助修复一些问题,我们也修复 8 个命中问题,并且都已经提了 PR 并合并

(https://github.com/StarRocks/starrocks/pull/46472

https://github.com/StarRocks/starrocks/pull/47648

https://github.com/StarRocks/starrocks/pull/48001

https://github.com/StarRocks/starrocks/pull/48092

https://github.com/StarRocks/starrocks/pull/48142

https://github.com/StarRocks/starrocks/pull/48773

https://github.com/StarRocks/starrocks/pull/48984

https://github.com/StarRocks/starrocks/pull/49168)

4.6 修复物化视图刷新问题

1、支持刷新顺序为从新分区到老分区,这样最近的数据能最快得到加速(https://github.com/StarRocks/starrocks/pull/46691)。

2、修复了 force 刷新不生效的问题(https://github.com/StarRocks/starrocks/pull/52081)

3、修复物化视图在 image 创建后被非预期 inactive,重启后被强制刷新的问题(https://github.com/StarRocks/starrocks/pull/51388)。

4、反馈给社区修复了 fast schema evolution 导致的 MV 非预期刷新问题

具体迁移过程

图片

ClickHouse 灰度迁移 StarRocks 

图片

智能运营并不直接查询 StarRocks,而是经过中间的 ONE DSL 平台翻译 DSL(一种类 SQL)成 ClickHouse/StarRocks SQL 后发给后端引擎。通过查询时指定 DSL目标翻译类型,决定发到 ClickHouse 或者 StarRocks,这样在迁移过程中可以按接口灰度,然后逐个的迁移,有问题可以随时单独回滚某个接口。

语法兼容

2.1 兼容 ClickHouse 函数

  • 我们仿造 StarRocks 中已有的 Trino 的 AstBuilder 实现了 ClickHouse 的 AstBuilder,通过新增 sql_dialect=clickhouse 选项,让兼容改动不污染 StarRocks 原来的行为

  • 我们兼容了业务方用到的 72 个函数,覆盖了最常用 ClickHouse 函数,业务方大部分情况下不需要修改查询 SQL,从而减小了迁移需要的工时。可以做到一个 ClickHouse 函数对应一个 StarRocks 函数或者多个函数的组合,并且将来新增一个 ClickHouse 函数映射是非常容易的。

  • 我们还实现了 ClickHouse 的 ArrayJoin 函数,能在 StarRocks 中使用一样的方式进行列转行:

-- StarRocks 原生写法

select u from tbl, unnest(array_column)

-- ArrayJoin 的写法

select arrayJoin(array_column) from tbl

不过 ClickHouse 的 arrayJoin 语法仍然是不支持的,需要手工改写成 StarRocks的 unnest 语法。

  • 此外,我们还实现了 ClickHouse 式的别名引用,可以在 select 的后段引用前段定义的别名(https://github.com/StarRocks/starrocks/pull/43919):

    Select id as id_alias, sum(a) as b, concat(b, ',', '_') from xx where  id_alias > 100 group by id_alias

2.2 ClickHouse表/物化视图转换工具

在引擎之外做了转换工具,能够以程序的方式将 ClickHouse 的建表和建物化视图的 DDL 转为 StarRocks 的 DDL,节约了手工转换的时间的同时也避免手工转换时可能发生的改写错误。

优化查询性能

3.1 修复特定性能问题

  1. 前面提到的修复多个场景的物化视图命中问题和优化物化视图选择策略性能

  2. 分区字段查询带函数导致物化视图分区裁剪失败(https://github.com/StarRocks/starrocks/pull/46786)

  3. 优化数值与字符串类型隐式转换(https://github.com/StarRocks/starrocks/pull/50168):对应 sql 性能提升 20 倍

  4. 优化 date/datetime 被当做字符串使用时的规则,从而命中稀疏索引命中(https://github.com/StarRocks/starrocks/pull/50643):对应 sql 性能提升 30 倍

  5. 减少查询时存算分离 staros 的 rpc 调用次数(https://github.com/StarRocks/starrocks/pull/46913) + 简易 rpc 结果缓存:查询耗时普遍减少 3s+

3.2 创建大量物化视图

通过持续对 I/O 高/CPU 高的查询针对性优化,发现有大量查询是可以用物化视图加速的。在原有 ClickHouse 迁移过来的物化视图之外,又增加了许多物化视图。目前为止已经有 140+ 物化视图。最大的 3 张表占总存储的 50%,对应了 60+ 物化视图。

3.3 表结构优化

StarRocks 所有的表结构都继承自 ClickHouse 的表结构,在实际线上运行过程中,发现了很多 schema 不合理的地方。通过对表和物化视图的排序键、分桶键、分桶数量的优化让其符合最常用的过滤条件中的字段的顺序,性能得到极大提升(如何设计合理排序键,以便查询利用前缀索引加速https://docs.starrocks.io/zh/docs/table_design/indexes/Prefix_index_sort_key/)。比如某张表的排序键优化后,查询性能提升了 150 倍

3.4 找到问题 SQL 让用户修改写法

通过持续对 I/O 高/CPU 高的查询针对性优化,发现有很多 StarRocks rule 不能等价转换,但从业务角度看是等价的小改动,可以显著提升性能的场景。

1、换种写法改进 plan

比如下面的极端 case 的改动提升了 250 倍性能,因为它导致估算的行数变少,从而优化了 join order 的顺序,生成了更好的 plan。

brand_id IN (SELECT brand_id FROM olap_znyy.st_itg_spu_info_all WHERE brand_level_name IN ('A级品牌', 'B级品牌', 'C级品牌'))
改成
brand_id IN (SELECT distinct brand_id FROM olap_znyy.st_itg_spu_info_all WHERE brand_level_name IN ('A级品牌', 'B级品牌', 'C级品牌'))

2、把 limit 提前到 join 语句里

业务上会先 join 维度表取得更多字段,最后再 order by join 左分支中的字段再 limit。改成把 limit 放到 join 左分支中,然后再 join 维度表。这样减少了 join 的行数,降低 70% 耗时。

图片

3、去除 join key 上不必要的函数调用

业务方 join on upper(query) 上,但所有 join 到的表的数据其实都是小写(这个信息只有业务方自己才知道),根本不需要转成大写后再 join。去除 upper 函数再 join提升至少一倍性能。

4、去除不必要的 toString

用户喜欢 join 时把数值字段 toString 之后 join,这样去掉 toString 也可以减少计算量提升性能。除了 join key,还有很多 select 地方也喜欢用 toString,也都是非必要的。

5、子查询合并,消除 join。收益性能提升约 50%

图片

6、维度表过滤条件下推,收益:查询超时->0.1s

图片

运维和可观测性增强

除了上面引擎方面的改动,还配合业务方的管理需求,支持了一些特定的 API,比如:

1. 资源水位 API

2. SQL 复杂度因子 API

3. 根据表名获取物化视图列表和物化视图的具体列信息 API

4. 指定 custom_query_id,可以异步 kill query 的能力(https://github.com/StarRocks/starrocks/pull/47632;https://github.com/StarRocks/starrocks/pull/48114)

成果展示

得到社区的给力支持,以及与智能运营团队紧密的合作,我们最终顺利从ClickHouse 迁移到 StarRocks,并且在查询性能耗时减少为 ClickHouse 查询耗时的一半。

以下是获得的收益:

  1. 成本收益:智能运营底层 AP 引擎费用下降 40%,存储费用下降 5/6。

  2. 性能和体验收益:智能运营的大盘的 P95 耗时从最初的 8.5s 降低到当前的 4.3s;P0页面低基维度的耗时从最初的 9.07s 降低到 4.77s,高基维的 P95耗时从 24.38s 降低到 11.94s; 查询成功率从 98.57% 提升到 99.44%。

  3. 数据时效性收益:在双跑期间 ClickHouse 的基线 SLA 达成率是 99.42%,StarRocks 的基线 SLA 达成率是 100%。

  4. 稳定性收益:集群因为单节点异常导致集群不可用的时间从 15min 缩短到 30s 内。

我们与社区保持了密切的接触,会提交一些重大 issue,同时也贡献我们的修复给社区。迁移过程中共提交 PR 28 个,已 merge 24 个(https://github.com/StarRocks/starrocks/pulls?q=is%3Apr+author%3Akaijianding)。在迁移过程中,开发了 ClickHouse 函数兼容等 10+ 功能,修复 40+ 个问题(包括反馈给社区修复的)。

总结

此次迁移达成了预期的成本和性能的收益目标,也拓展了集群未来的成长空间,也让业务团队和引擎团队都更加的了解 StarRocks,收获大量迁移经验,为将来迁移其他业务提供了有说服力的范例。

在迁移过程中,我们与社区保持了紧密的联系,获得了社区大量帮助,也贡献了大量 patch 给社区,减少社区其他人需要踩的坑。在我们得物内部 StarRocks 的未来规划中,我们也将继续深度参与社区。

https://www.bilibili.com/video/BV16vCAYZE8d/?vd_source=1cb452610138142d1300dd37a6162a88

更多交流,联系我们:StarRocks

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/500453.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue视频录制 限制大小,限制时长

<template><div style"height: 100vh;background: #000;"><span style"color: #fff;font-size: 18px;">切换数量&#xff1a;{{ devices.length }}</span><video ref"video" autoplay muted playsinline></vid…

若依框架之简历pdf文档预览功能

一、前端 &#xff08;1&#xff09;安装插件vue-pdf&#xff1a;npm install vue-pdf &#xff08;2&#xff09;引入方式&#xff1a;import pdf from "vue-pdf"; &#xff08;3&#xff09;components注入方式&#xff1a;components:{pdf} &#xff08;4&…

永磁同步电机负载估计算法--自适应龙伯格观测器

一、原理介绍 龙贝格扰动观测器的参数可以通过带宽配置法进行整定&#xff0c;将观测器带宽设为L&#xff0c;选取大的L可以加快观测器的收敛速度&#xff0c;但是L过大会导致系统阶跃响应出现超调、稳态性能差等问题。因此&#xff0c;在龙贝格观测器中引入表征系统状态变量x…

Python机器学习笔记(十七、分箱、离散化、线性模型与树)

数据表示的最佳方法&#xff1a;取决于数据的语义&#xff0c;所使用的模型种类。 线性模型与基于树的模型&#xff08;决策树、梯度提升树和随机森林&#xff09;是两种成员很多同时又非常常用的模 型&#xff0c;它们在处理不同的特征表示时就具有非常不同的性质。我们使用w…

Spring Boot介绍、入门案例、环境准备、POM文件解读

文章目录 1.Spring Boot(脚手架)2.微服务3.环境准备3.1创建SpringBoot项目3.2导入SpringBoot相关依赖3.3编写一个主程序&#xff1b;启动Spring Boot应用3.4编写相关的Controller、Service3.5运行主程序测试3.6简化部署 4.Hello World探究4.1POM文件4.1.1父项目4.1.2父项目的父…

嵌入式入门Day35

网络编程 Day2 套接字socket基于TCP通信的流程服务器端客户端TCP通信API 基于UDP通信的流程服务器端客户端 作业 套接字socket socket套接字本质是一个特殊的文件&#xff0c;在原始的Linux中&#xff0c;它和管道&#xff0c;消息队列&#xff0c;共享内存&#xff0c;信号等…

安卓系统主板_迷你安卓主板定制开发_联发科MTK安卓主板方案

安卓主板搭载联发科MT8766处理器&#xff0c;采用了四核Cortex-A53架构&#xff0c;高效能和低功耗设计。其在4G网络待机时的电流消耗仅为10-15mA/h&#xff0c;支持高达2.0GHz的主频。主板内置IMG GE832 GPU&#xff0c;运行Android 9.0系统&#xff0c;内存配置选项丰富&…

centos,789使用mamba快速安装R及语言包devtools

如何进入R语言运行环境请参考&#xff1a;Centos7_miniconda_devtools安装_R语言入门之R包的安装_r语言devtools包怎么安装-CSDN博客 在R里面使用安装devtools经常遇到依赖问题&#xff0c;排除过程过于费时&#xff0c;使用conda安装包等待时间长等。下面演示centos,789都是一…

人工智能(AI)简史:推动新时代的科技力量

一、人工智能简介 人工智能&#xff08;AI&#xff0c;Artificial Intelligence&#xff09;是计算机科学的一个分支&#xff0c;旨在研究和开发可以模拟、扩展或增强人类智能的系统。它涉及多种技术和方法&#xff0c;包括机器学习、深度学习、自然语言处理&#xff08;NLP&a…

【笔记】在虚拟机中通过apache2给一个主机上配置多个web服务器

&#xff08;配置出来的web服务器又叫虚拟主机……&#xff09; 下载apache2 sudo apt update sudo apt install apache2 &#xff08;一&#xff09;ip相同 web端口不同的web服务器 进入 /var/www/html 创建站点一和站点二的目录文件&#xff08;目录文件名自定义哈&#x…

linux装git

前言 以 deepin 深度系统为例&#xff0c;安装命 令行版 Git 非常简单。 安装 注意&#xff1a;需要输入账号密码&#xff0c;否则无法进行。 打开终端&#xff0c;执行如下命令即可。 sudo apt-get install git成功 如下图所示&#xff0c;输入 git &#xff0c;命令识别即…

【Spark】架构与核心组件:大数据时代的必备技能(下)

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《大数据前沿&#xff1a;技术与应用并进》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、什么是Apache Spark 2、Spark 的应用场景&…

NLP中的神经网络基础

一&#xff1a;多层感知器模型 1&#xff1a;感知器 解释一下&#xff0c;为什么写成 wxb>0 &#xff0c;其实原本是 wx > t ,t就是阈值&#xff0c;超过这个阈值fx就为1&#xff0c;现在把t放在左边。 在感知器里面涉及到两个问题&#xff1a; 第一个&#xff0c;特征提…

第十一章 图论

题目描述&#xff1a; 阿里这学期修了计算机组织和架构课程。他了解到指令之间可能存在依赖关系&#xff0c;比如WAR&#xff08;读后写&#xff09;、WAW、RAW。 如果两个指令之间的距离小于安全距离&#xff0c;则会导致危险&#xff0c;从而可能导致错误的结果。因此&#…

嵌入式系统 第七讲 ARM-Linux内核

• 7.1 ARM-Linux内核简介 • 内核&#xff1a;是一个操作系统的核心。是基于硬件的第一层软件扩充&#xff0c; 提供操作系统的最基本的功能&#xff0c;是操作系统工作的基础&#xff0c;它负责管理系统的进程、内存、设备驱动程序、文件和网络系统&#xff0c; 决定着系统的…

win11蓝屏死机 TPM-WMI

1. 打开win11的事件查看器&#xff0c;定位错误 最近两次都是 KB5016061&#xff1a;安全启动数据库和 DBX 变量更新事件 - Microsoft 支持 事件源 TPM-WMI 事件 ID 1796 2. 解决方案 打开注册表&#xff1a;计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Contro…

Linux命令——3.网络与用户

文章目录 一、网络1.网络测试与诊断2.网络接口配置3.无线网络配置4.防火墙与网络管理6.防火墙管理1&#xff09;firewalld命令2&#xff09;iptables命令 二、用户和群组1.管理员模式2.用户账户管理1&#xff09;useradd创建2&#xff09;usermod修改3&#xff09;userdel 删除…

机器学习算法基础知识1:决策树

机器学习算法基础知识1&#xff1a;决策树 一、本文内容与前置知识点1. 本文内容2. 前置知识点 二、场景描述三、决策树的训练1. 决策树训练方式&#xff08;1&#xff09;分类原则-Gini&#xff08;2&#xff09;分类原则-entropy&#xff08;3&#xff09;加权系数-样本量&am…

_使用CLion的Vcpkg安装SDL2,添加至CMakelists时报错,编译报错

语言&#xff1a;C20 编译器&#xff1a;gcc 14.2 摘要&#xff1a;初次使用Vcpkg添加SDL2&#xff0c;出现CMakelists找不到错误、编译缺失main错误、运行失败错误。 CMakelists缺失错误&#xff1a; 使用CLion的Vcpkg安装SDL2时&#xff0c;按照指示把对应代码添加至CMakel…

Lumos学习王佩丰Excel第二十二讲:制作甘特图与动态甘特图

一、制作双向条形图 1. 分离坐标轴 2. 自定义坐标轴数字格式&#xff1a;加分号加正常数字 3. 修改图表背景 修改图片艺术效果&#xff1a;虚化图片 二、制作甘特图 1、甘特图定义 甘特图&#xff08;Gantt chart&#xff09;又称为横道图、条状图&#xff08;Bar chart&…