You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by xx...@apache.org on 2022/04/21 08:21:19 UTC

[kylin] branch document updated: Add new blog:Kylin on Cloud

This is an automated email from the ASF dual-hosted git repository.

xxyu pushed a commit to branch document
in repository https://gitbox.apache.org/repos/asf/kylin.git


The following commit(s) were added to refs/heads/document by this push:
     new 06ebc6c13f Add new blog:Kylin on Cloud
06ebc6c13f is described below

commit 06ebc6c13faccef289379471f238ba510d0b94e4
Author: yaqian.zhang <59...@qq.com>
AuthorDate: Thu Apr 21 14:58:39 2022 +0800

    Add new blog:Kylin on Cloud
---
 .../blog/2022-04-20-kylin4-on-cloud-part1.cn.md    | 318 +++++++++++++++++++++
 .../blog/2022-04-20-kylin4-on-cloud-part2.cn.md    | 264 +++++++++++++++++
 .../images/blog/kylin4_on_cloud/0_deploy_kylin.png | Bin 0 -> 125108 bytes
 .../blog/kylin4_on_cloud/10_full_build_cube.png    | Bin 0 -> 89575 bytes
 .../blog/kylin4_on_cloud/11_kylin_job_complete.png | Bin 0 -> 87734 bytes
 .../kylin4_on_cloud/12_destroy_job_cluster.png     | Bin 0 -> 412858 bytes
 .../blog/kylin4_on_cloud/13_check_aws_stacks.png   | Bin 0 -> 115170 bytes
 .../blog/kylin4_on_cloud/14_kylin_web_ui.png       | Bin 0 -> 85659 bytes
 .../blog/kylin4_on_cloud/15_query_in_kylin.png     | Bin 0 -> 164620 bytes
 .../images/blog/kylin4_on_cloud/16_mdx_web_ui.png  | Bin 0 -> 11299 bytes
 .../blog/kylin4_on_cloud/17_connect_to_kylin.png   | Bin 0 -> 65469 bytes
 .../blog/kylin4_on_cloud/18_exit_management.png    | Bin 0 -> 11723 bytes
 .../blog/kylin4_on_cloud/19_kylin_running.png      | Bin 0 -> 82450 bytes
 website/images/blog/kylin4_on_cloud/1_table_ER.png | Bin 0 -> 90017 bytes
 .../blog/kylin4_on_cloud/20_import_dataset.png     | Bin 0 -> 47446 bytes
 .../blog/kylin4_on_cloud/21_tableau_connect.png    | Bin 0 -> 518516 bytes
 .../blog/kylin4_on_cloud/22_tableau_server.png     | Bin 0 -> 132583 bytes
 .../blog/kylin4_on_cloud/23_tableau_dataset.png    | Bin 0 -> 210129 bytes
 .../kylin4_on_cloud/24_tableau_covid19_map.png     | Bin 0 -> 419395 bytes
 .../blog/kylin4_on_cloud/25_tableau_province.png   | Bin 0 -> 272614 bytes
 .../blog/kylin4_on_cloud/26_tableau_us_covid19.png | Bin 0 -> 623458 bytes
 .../blog/kylin4_on_cloud/27_tableau_taxi_1.png     | Bin 0 -> 529359 bytes
 .../blog/kylin4_on_cloud/27_tableau_taxi_2.png     | Bin 0 -> 535572 bytes
 .../blog/kylin4_on_cloud/28_tableau_taxi_3.png     | Bin 0 -> 394678 bytes
 .../blog/kylin4_on_cloud/29_tableau_taxi_4.png     | Bin 0 -> 386881 bytes
 .../blog/kylin4_on_cloud/2_step_overview.jpg       | Bin 0 -> 399800 bytes
 .../blog/kylin4_on_cloud/30_excel_connect.png      | Bin 0 -> 664276 bytes
 .../blog/kylin4_on_cloud/31_excel_server.png       | Bin 0 -> 175105 bytes
 .../blog/kylin4_on_cloud/32_tableau_dataset.png    | Bin 0 -> 184982 bytes
 .../blog/kylin4_on_cloud/33_tableau_covid19_1.png  | Bin 0 -> 184123 bytes
 .../blog/kylin4_on_cloud/34_excel_covid20_2.png    | Bin 0 -> 850686 bytes
 .../blog/kylin4_on_cloud/35_excel_taxi_1.png       | Bin 0 -> 431425 bytes
 .../blog/kylin4_on_cloud/36_excel_taxi_2.png       | Bin 0 -> 850052 bytes
 website/images/blog/kylin4_on_cloud/37_jdk_8.png   | Bin 0 -> 43895 bytes
 .../images/blog/kylin4_on_cloud/38_demo_result.png | Bin 0 -> 96980 bytes
 .../blog/kylin4_on_cloud/39_check_s3_demo.png      | Bin 0 -> 120578 bytes
 .../blog/kylin4_on_cloud/3_kylin_cluster.jpg       | Bin 0 -> 155291 bytes
 .../4_deploy_cluster_successfully.png              | Bin 0 -> 105262 bytes
 .../blog/kylin4_on_cloud/5_check_aws_stacks.png    | Bin 0 -> 202840 bytes
 .../blog/kylin4_on_cloud/6_list_cluster_node.png   | Bin 0 -> 237378 bytes
 .../blog/kylin4_on_cloud/7_query_in_spark_sql.png  | Bin 0 -> 12961 bytes
 .../images/blog/kylin4_on_cloud/8_kylin_web_ui.png | Bin 0 -> 38877 bytes
 .../kylin4_on_cloud/9_reload_kylin_metadata.png    | Bin 0 -> 82291 bytes
 .../images/blog/kylin4_on_cloud/kylin_on_cloud.png | Bin 0 -> 61487 bytes
 44 files changed, 582 insertions(+)

diff --git a/website/_posts/blog/2022-04-20-kylin4-on-cloud-part1.cn.md b/website/_posts/blog/2022-04-20-kylin4-on-cloud-part1.cn.md
new file mode 100644
index 0000000000..91331e7334
--- /dev/null
+++ b/website/_posts/blog/2022-04-20-kylin4-on-cloud-part1.cn.md
@@ -0,0 +1,318 @@
+---
+layout: post-blog
+title: Kylin on Cloud —— 两小时快速搭建云上数据分析平台(上)
+date: 2022-04-20 11:00:00
+author: Yaqian Zhang
+categories: cn_blog
+---
+
+## 背景
+
+Apache Kylin 是基于预计算和多维模型的多维数据库,支持 SQL 标准查询接口,在 Kylin 中用户可以通过创建 Model 定义表关系,通过创建 Cube 定义维度和度量,然后构建 Cube 对需要聚合的数据进行预计算,将预计算好的数据保存起来,用户执行查询时便可以直接在经过预计算的数据上进行进一步的聚合或者直接返回查询结果,成倍提升查询效率。
+
+随着 Kylin 4.0 新架构的版本发布与更新,Kylin 具备了在脱离 Hadoop 的云环境下进行集群部署的能力;为了使用户能够轻松地在云上部署 Kylin,Kylin 社区又于近日开发了云上部署工具,用户使用部署工具只需执行一行命令便可以得到一个完备的 kylin 集群,获得高效快速的分析体验;2022 年1月份,Kylin 社区发布了 mdx for kylin 来加强 Kylin 作为多维数据库的业务表达能力,MDX for Kylin 提供了 MDX 的查询接口,mdx for kylin 可以在 Kylin 已经定义好的多维模型的基础上更进一步的创建业务指标,将 Kylin 中的数据模型转换为业务友好的语言,赋予数据业务价值,方便对接 Excel、Tableau 等 BI 工具进行多维分析。
+
+基于以上一系列的技术支撑,用户不仅可以方便快捷的在云上部署 Kylin 集群,创建多维模型,体验经过预计算的快速查询响应,还能够结合 MDX for Kylin 对业务指标进行定义和管理,将 DW 技术层提升到业务语义层。
+
+用户可以在 Kylin + MDX for Kylin 之上直接对接 BI 工具进行多维数据分析,也可以以此为底座建设指标平台等复杂应用。相比于直接基于 Spark、Hive 等在运行时进行 Join 和聚合查询的计算引擎之上构建指标平台,利用 Kylin 可以依托于多维模型和预计算技术,以及 mdx for kylin 的语义层能力,满足指标平台所需要的海量数据计算、极速查询响应、统一的多维模型、对接多种 BI、基础的业务指标管理等多种关键功能。
+
+本文的以下部分将会带领读者,从一个数据工程师的角度,快速体验在云上搭建基于 Kylin 的数据分析平台(Kylin on Cloud),在亿行级数据之上获得高性能低成本的查询体验,并通过 mdx for kylin 管理业务指标,直接对接 BI 工具快速生成报表。
+
+本教程每一个步骤都有详细说明,并附有配图和检查点,帮助新手上路。读者只需要准备一个 AWS 账号,预计这个过程需要大约 2 小时,花费 ¥100 左右。
+
+![](/images/blog/kylin4_on_cloud/0_deploy_kylin.png)
+
+## 业务场景
+
+自 2020 年初以来 COVID-19 在全世界范围内快速传播,对人们的衣食住行尤其是出行习惯造成极大影响。这次数据分析结合 COVID-19 疫情数据和 2018 年以来纽约出租车出行数据,通过分析疫情指标和各种出行指标,比如确诊人数、病死率、出租车订单数、平均出行距离等,来洞察纽约市出租车行业受疫情影响的变化趋势,以支撑决策。
+
+### 业务问题
+
+- 多指标联合分析各个国家地区疫情严重程度
+- 纽约市各个街区出行指标对比,比如订单数数量、出行里程等
+- 疫情对于出租车订单数量有无明显影响
+- 疫情之后的出行习惯变化,更偏向远程出行还是近程
+- 疫情严重程度与出租车出行次数是否强相关
+
+### 数据集
+
+#### COVID-19 数据集
+
+COVID-19 数据集包括一张事实表 `covid_19_activity` 和一张维度表 `lookup_calendar`。
+
+其中,`covid_19_activity` 记录每一天全球范围内不同地区的确诊和死亡数字;`lookup_calendar` 为日期维度表,保存了时间的扩展信息,比如每一个日期对应的年始、月始等,`covid_19_activity` 和 `lookup_calendar` 之间通过日期进行关联。
+
+COVID-19 数据集相关信息如下:
+
+| ------------------------|------------------------------------------------------------------------------------------------------------------|
+| 数据大小                 |  235 MB                                                                                                           |
+| 事实表数据行数            |  2,753,688                                                                                                        |
+| 数据日期                 |  2020-01-21~2022-03-07                                                                                            |
+| 数据集提供方下载地址       |  https://data.world/covid-19-data-resource-hub/covid-19-case-counts/workspace/file?filename=COVID-19+Activity.csv |
+| 数据集 S3 地址           |  s3://public.kyligence.io/kylin/kylin_demo/data/covid19_data/                                                     |
+
+#### 纽约市出租车订单数据集
+
+纽约市出租车订单数据集包括一张事实表 `taxi_trip_records_view` 和两张维度表 `newyork_zone`、`lookup_calendar`。
+
+其中,`taxi_trip_records_view` 中的一条记录对一次出租车出行,记录了出发地点 ID、到达地点 ID、出行时长、订单金额、出行距离等;`newyork_zone` 记录了地点 ID 所对应的行政区等信息,`taxi_trip_records_view` 分别通过 `PULocationID` 和 `DOLocationID` 两个列与 `newyork_zone` 建立关联关系,统计出发街区和到达街区信息;`lookup_calendar` 与 `COVID-19` 数据集中的维度表为同一张表,`taxi_trip_records_view` 与 `lookup_calendar` 通过日期进行关联。
+
+纽约市出租车订单数据集相关信息如下:
+
+| ------------------------|----------------------------------------------------------------------|
+| 数据大小                  |  19 G                                                                |
+| 事实表数据行数             |  226,849,274                                                         |
+| 数据日期                  |  2018-01-01~2021-07-31                                               |
+| 数据集提供方下载地址        |  https://www1.nyc.gov/site/tlc/about/tlc-trip-record-data.page       |
+| 数据集 S3 地址            |  s3://public.kyligence.io/kylin/kylin_demo/data/trip_data_2018-2021/ |
+
+
+
+#### ER 关系图
+
+新冠疫情数据集和纽约市出租车订单数据集的 ER 关系图如下图所示:
+
+![](/images/blog/kylin4_on_cloud/1_table_ER.png)
+
+### 指标设计
+
+针对需要分析的业务场景和业务问题,我们设计了以下原子指标和业务指标:
+
+###### 1.原子指标
+
+原子指标指的是在 Kylin Cube 中创建的各种度量,它们通常是在单一列上面进行聚合计算,相对比较简单。
+
+- Covid19 病例数 sum(covid_19_activity.people_positive_cases_count)
+- Covid19 病死数 sum(covid_19_activity. people_death_count)
+- 新增 Covid19 病例数 sum(covid_19_activity. people_positive_new_cases_count)
+- 新增 Covid19 病死数 sum(covid_19_activity. people_death_new_count)
+- 出租车出行里程 sum(taxi_trip_records_view. trip_distance)
+- 出租车订单交易额 sum(taxi_trip_records_view. total_amount)
+- 出租车出行数量 count()
+- 出租车出行时长 sum(taxi_trip_records_view.trip_time_hour)
+
+###### 2.业务指标
+
+业务指标是指基于原子指标定义的各种复合运算,具有具体的业务含义。
+
+- 各原子指标的月累计MTD、年累计YTD
+- 各原子指标的月增速MOM、年增速YOY
+- Covid19 病死率:死亡人数/确诊人数
+- 出租车平均出行速度:出租车出行里程/出租车出行时间
+- 出租车出行平均里程:出租车出行里程/出租车出行数量
+
+## 操作步骤概览
+
+搭建基于 Apache Kylin 的云上数据分析平台并进行数据分析的主要操作步骤如下图:
+
+![](/images/blog/kylin4_on_cloud/2_step_overview.jpg)
+
+## 集群架构
+
+使用云上部署工具部署出的 Kylin 集群架构如图所示:
+
+![](/images/blog/kylin4_on_cloud/3_kylin_cluster.jpg)
+
+## Kylin on Cloud 部署
+
+### 环境要求
+
+- 需要本地机器已安装 git,用于下载部署工具代码;
+- 需要本地机器已安装 Python 3.6.6 及以上版本,用于运行部署工具。
+
+### AWS 权限检查与初始化
+
+登录 AWS 账号,根据 [准备文档](https://github.com/apache/kylin/blob/kylin4_on_cloud/readme/prerequisites.md) 来检查用户权限、创建部署工具需要的 Access Key、IAM Role、Key Pair 和 S3 工作目录。后续的 AWS 操作都会以这个帐号的身份执行。
+
+### 配置部署工具
+
+1.执行下面的命令获得 Kylin on AWS 部署工具的代码
+
+```shell
+git clone -b kylin4_on_cloud --single-branch https://github.com/apache/kylin.git && cd kylin
+```
+
+2.在本地机器初始化 python 虚拟环境
+
+检查 python 环境,需要 Python 3.6.6 以上:
+
+```shell
+python --version
+```
+
+初始化 python 虚拟环境,安装依赖:
+
+```shell
+bin/init.sh
+source venv/bin/activate
+```
+
+3.修改配置文件 `kylin_configs.yaml`
+
+打开部署工具代码中的 kylin_configs.yaml,将文件中的配置项替换为实际值:
+
+- `AWS_REGION`: EC2 节点位置 Region,默认为 cn-northwest-1
+- `${IAM_ROLE_NAME}`: 提前创建的 IAM Role 名称,比如 kylin_deploy_role
+- `${S3_URI}`: 用于部署 kylin 的 S3 工作目录,比如 s3://kylindemo/kylin_demo_dir/
+- `${KEY_PAIR}`: 提前创建的 Key pairs 名字,比如 kylin_deploy_key
+- `${Cidr Ip}`: 允许访问 EC2 实例的 IP 地址范围,比如 10.1.0.0/32,通常设为您的外网 IP 地址,确保创建的 EC2 实例只有您能访问
+
+出于读写分离隔离构建和查询资源的考虑,在以下的步骤中会先启动一个构建集群用于连接 Glue 建表、加载数据源、提交构建任务进行预计算,然后销毁构建集群,保留元数据,启动带有 MDX for Kylin 的查询集群,用于创建业务指标、连接 BI 工具执行查询,进行数据分析。Kylin on AWS 集群使用 RDS 存储元数据,使用 S3 存储构建后的数据,并且支持从 AWS Glue 中加载数据源,除了 EC2 节点之外使用的资源都是持久化的,不会随着节点的删除而消失,所以在没有查询或者构建任务时,用户可以随时销毁构建或查询集群,只要保留元数据、S3 工作目录即可。
+
+### Kylin 构建集群
+
+#### 启动 Kylin 构建集群
+
+1.通过如下命令启动构建集群。根据网络情况不同,部署启动可能需要 15-30 分钟。
+
+```shell
+python deploy.py --type deploy --mode job
+```
+
+2.构建集群部署成功后,命令窗口可以看到如下输出:
+
+![](/images/blog/kylin4_on_cloud/4_deploy_cluster_successfully.png)
+
+#### 检查 AWS 服务
+
+1.进入 AWS 控制台的  CloudFormation 界面,可以看到 Kylin 部署工具一共起了 7 个 stack:
+
+![](/images/blog/kylin4_on_cloud/5_check_aws_stacks.png)
+
+2.用户可以通过 AWS 控制台查看 EC2 节点的详细信息,也可以在命令行界面使用如下命令列出所有 EC2 节点的名字、私有 IP 和公有 IP:
+
+```shell
+python deploy.py --type list
+```
+
+![](/images/blog/kylin4_on_cloud/6_list_cluster_node.png)
+
+#### 体验 spark-sql 原生查询速度
+
+为了直观的感受到预计算给查询性能带来的提升,在构建 cube 之前,我们先在 spark-sql 中体验原生的查询速度:
+
+1.首先,我们通过 kylin 节点的公有 IP 登录到该 kylin 所在的 EC2 机器,并切换到 root 用户,执行 ~/.bash_profile 使提前设置的环境变量生效:
+
+```shell
+ssh -i "${KEY_PAIR}" ec2-user@${kylin_node_public_ip}
+sudo su
+source ~/.bash_profile
+```
+
+2.然后进入 `$SPARK_HOME` 并修改配置文件 `conf/spark-defaults.conf`,将 `spark_master_node_private_ip` 修改为 spark master 节点的私有 IP:
+
+```shell
+cd $SPARK_HOME
+vim conf/spark-defaults.conf
+
+# 将 spark_master_node_private_ip 替换为真实 spark master 节点的私有ip
+spark.master spark://spark_master_node_private_ip:7077
+```
+
+`spark-defaults.conf` 中关于 driver 和 executor 的资源配置与 kylin 查询集群的资源配置是一致的。
+
+3.在 spark-sql 中建表
+
+测试所用数据集的所有数据存放在位于 `cn-north-1` 和 `us-east-1` 地区的 S3 bucket 中,如果你的 S3 bucket 位于 `cn-north-1` 或者 `us-east-1`,那么你可以直接执行建表 sql;否则需要执行以下脚本复制数据到 `kylin_configs.yaml` 中设置的 S3 工作目录下,并修改建表 sql:
+
+```shell
+## AWS CN 用户
+aws s3 sync s3://public.kyligence.io/kylin/kylin_demo/data/ ${S3_DATA_DIR} --region cn-north-1
+
+## AWS Global 用户
+aws s3 sync s3://public.kyligence.io/kylin/kylin_demo/data/ ${S3_DATA_DIR} --region us-east-1
+
+# 修改建表 sql
+sed -i "s#s3://public.kyligence.io/kylin/kylin_demo/data/#${S3_DATA_DIR}#g" /home/ec2-user/kylin_demo/create_kylin_demo_table.sql
+```
+
+执行建表 sql:
+
+```shell
+bin/spark-sql -f /home/ec2-user/kylin_demo/create_kylin_demo_table.sql
+```
+
+4.在 spark-sql 中执行查询
+
+进入 spark-sql:
+
+```shell
+bin/spark-sql
+```
+
+在 spark-sql 中执行查询:
+
+```sql
+use kylin_demo;
+select TAXI_TRIP_RECORDS_VIEW.PICKUP_DATE, NEWYORK_ZONE.BOROUGH, count(*), sum(TAXI_TRIP_RECORDS_VIEW.TRIP_TIME_HOUR), sum(TAXI_TRIP_RECORDS_VIEW.TOTAL_AMOUNT)
+from TAXI_TRIP_RECORDS_VIEW
+left join NEWYORK_ZONE
+on TAXI_TRIP_RECORDS_VIEW.PULOCATIONID = NEWYORK_ZONE.LOCATIONID
+group by TAXI_TRIP_RECORDS_VIEW.PICKUP_DATE, NEWYORK_ZONE.BOROUGH;
+```
+
+然后可以看到,在资源与 kylin 查询集群配置相同的情况下,使用 spark-sql 直接查询耗时超过100s:
+
+![](/images/blog/kylin4_on_cloud/7_query_in_spark_sql.png)
+
+5.查询执行成功后必须退出 spark-sql 再进行下面的步骤,防止占用资源。
+
+#### 导入 Kylin 元数据
+
+1.进入 `$KYLIN_HOME`
+
+```shell
+cd $KYLIN_HOME
+```
+
+2.导入元数据
+
+```shell
+bin/metastore.sh restore /home/ec2-user/meta_backups/
+```
+
+3.重载元数据
+
+根据 EC2 节点的公有 IP,在浏览器输入 `http://${kylin_node_public_ip}:7070/kylin` 进入 kylin web 页面,并使用 ADMIN/KYLIN 的默认用户名密码登录:
+
+![](/images/blog/kylin4_on_cloud/8_kylin_web_ui.png)
+
+通过 System -> Configuration -> Reload Metadata 重载 Kylin 元数据:
+
+![](/images/blog/kylin4_on_cloud/9_reload_kylin_metadata.png)
+
+如果用户想要了解如何手动创建 Kylin 元数据中所包含的 Model 和 Cube,可以参考:(Create model and cube in kylin)[https://cwiki.apache.org/confluence/display/KYLIN/Create+Model+and+Cube+in+Kylin]。
+
+#### 执行构建
+
+提交 cube 构建任务,由于在 model 中未设置分区列,所以这里直接对两个 cube 进行全量构建:
+
+![](/images/blog/kylin4_on_cloud/10_full_build_cube.png.png)
+
+![](/images/blog/kylin4_on_cloud/11_kylin_job_complete.png)
+
+#### 销毁构建集群
+
+构建完成之后,执行集群销毁命令销毁构建集群,默认情况下会保留 RDS stack、monitor stack 和 vpc stack:
+
+```shell
+python deploy.py --type destroy
+```
+
+集群销毁成功:
+
+![](/images/blog/kylin4_on_cloud/12_destroy_job_cluster.png)
+
+#### 检查 AWS 资源
+
+集群销毁成功后,可以到 AWS 控制台的 `CloudFormation` 服务确认是否存在资源残留,由于默认会保留元数据 RDS、监控节点和 VPC 节点,所以集群销毁后 CloudFormation 页面还会存在以下三个 Stack:
+
+![](/images/blog/kylin4_on_cloud/13_check_aws_stacks.png)
+
+下面启动查询集群时仍然会使用这三个 Stack 中的资源,这样我们可以保证查询集群和构建集群使用同一套元数据。
+
+
+以上部分为 `Kylin on Cloud —— 两小时快速搭建云上数据分析平台` 的上篇,下篇请查看:[Kylin on Cloud —— 两小时快速搭建云上数据分析平台(下)](../kylin4-on-cloud-part2/)
+
+
+
diff --git a/website/_posts/blog/2022-04-20-kylin4-on-cloud-part2.cn.md b/website/_posts/blog/2022-04-20-kylin4-on-cloud-part2.cn.md
new file mode 100644
index 0000000000..08d7c5f744
--- /dev/null
+++ b/website/_posts/blog/2022-04-20-kylin4-on-cloud-part2.cn.md
@@ -0,0 +1,264 @@
+---
+layout: post-blog
+title: Kylin on Cloud —— 两小时快速搭建云上数据分析平台(下)
+date: 2022-04-20 11:00:00
+author: Yaqian Zhang
+categories: cn_blog
+---
+
+以下部分为 `Kylin on Cloud —— 两小时快速搭建云上数据分析平台` 的下篇,上篇请查看:[Kylin on Cloud —— 两小时快速搭建云上数据分析平台(上)](../kylin4-on-cloud-part1/)
+
+### Kylin 查询集群
+
+#### 启动 Kylin 查询集群
+
+1.在启动构建集群时使用的 kylin_configs.yaml 的基础上,打开 mdx 开关:
+
+```
+ENABLE_MDX: &ENABLE_MDX 'true'
+```
+
+2.然后执行部署命令启动集群:
+
+```
+python deploy.py --type deploy --mode query
+```
+
+#### 体验 kylin 的查询速度
+
+1.查询集群启动成功后,先执行 `python deploy.py --type list` 命令来列出所有节点信息,然后在浏览器输入 http://${kylin_node_public_ip}:7070/kylin 检查 kylin UI:
+
+![](/images/blog/kylin4_on_cloud/14_kylin_web_ui.png)
+
+2.在 Insight 页面执行与之前在 spark-sql 中相同的 sql:
+
+```
+select TAXI_TRIP_RECORDS_VIEW.PICKUP_DATE, NEWYORK_ZONE.BOROUGH, count(*), sum(TAXI_TRIP_RECORDS_VIEW.TRIP_TIME_HOUR), sum(TAXI_TRIP_RECORDS_VIEW.TOTAL_AMOUNT)
+from TAXI_TRIP_RECORDS_VIEW
+left join NEWYORK_ZONE
+on TAXI_TRIP_RECORDS_VIEW.PULOCATIONID = NEWYORK_ZONE.LOCATIONID
+group by TAXI_TRIP_RECORDS_VIEW.PICKUP_DATE, NEWYORK_ZONE.BOROUGH;
+```
+
+![](/images/blog/kylin4_on_cloud/15_query_in_kylin.png)
+
+可以看到,在查询击中 cube 的情况下,也就是查询结果直接来自于预计算后的数据,只使用了大概 4 秒的时间就返回了查询结果,大大节省了查询时间。
+
+### 预计算降低查询成本
+
+在对比原生 SparkSql 和 Kylin 查询速度的测试中,我们使用的数据集是纽约市出租车订单数据,事实表共有 2 亿+ 数据。从对比结果可以看到,在上亿的大数据分析场景下,Kylin 能够显著提升查询效率,通过一次构建加速上千上万次业务查询,极大的降低查询成本。
+
+### 配置语义层
+
+#### 向 MDX for Kylin 导入 Dataset
+
+在 `MDX for Kylin` 中可以根据所连接的 Kylin 中的 Cube 来创建 `Dataset`,定义 Cube 关系,创建业务指标。为方便体验,用户可以直接从 S3 下载 Dataset 文件导入到 `MDX for Kylin` 中:
+
+1.从 S3 下载 Dataset 文件到本地机器
+
+```
+wget https://s3.cn-north-1.amazonaws.com.cn/public.kyligence.io/kylin/kylin_demo/covid_trip_project_covid_trip_dataset.json
+```
+
+2.访问 `MDX for Kylin` 界面
+
+在浏览器输入 `http://${kylin_node_public_ip}:7080` 访问 `MDX for Kylin` 页面,以 `ADMIN/KYLIN` 的用户名密码组合登录:
+
+![](/images/blog/kylin4_on_cloud/16_mdx_web_ui.png)
+
+3.确认 Kylin 连接
+
+`MDX for Kylin` 中已经配置了需要连接的 kylin 节点的信息,首次登录需要输入 kylin 节点的用户名和密码也就是 `ADMIN/KYLIN`:
+
+![](/images/blog/kylin4_on_cloud/17_connect_to_kylin.png)
+
+![](/images/blog/kylin4_on_cloud/18_exit_management.png)
+
+4.导入 Dataset
+
+连接 Kylin 成功后点击右上角的图标退出管理界面:
+
+![](/images/blog/kylin4_on_cloud/19_kylin_running.png)
+
+切换到 `covid_trip_project` 项目,在 Dataset 页面中点击 `Import Dataset`:
+
+![](/images/blog/kylin4_on_cloud/20_import_dataset.png)
+
+选择刚刚从 S3 下载的文件 `covid_trip_project_covid_trip_dataset.json` 导入。
+
+`covid_trip_dataset` 中定义了各原子指标的年累计、月累计、年增速、月增速,和时间层级、地区层级等特殊维度、度量,以及新冠肺炎病死率、出租车平均速度等业务指标。如何手动创建 Dataset 请参考:[Create dataset in MDX for Kylin](https://cwiki.apache.org/confluence/display/KYLIN/Create+Dataset+in+MDX+for+Kylin),MDX for Kylin 手册链接请参考:[MDX for Kylin 使用手册](https://kyligence.github.io/mdx-kylin/)。
+
+## 数据分析
+
+### 通过 Tableau 进行数据分析
+
+我们以本地 windows 机器上的 tableau 为例连接 MDX for Kylin 进行数据分析。
+
+1.选择 Tableau 内置的 `Microsoft Analysis Service` 来连接 `MDX for Kylin` (需要提前安装 `Microsoft Analysis Services` 驱动,可从 tableau 官网下载,[Microsoft Analysis Services 驱动下载](https://www.tableau.com/support/drivers?_ga=2.104833284.564621013.1647953885-1839825424.1608198275))
+
+![](/images/blog/kylin4_on_cloud/21_tableau_connect.png)
+
+2.在弹出的设置页面中填写 `MDX for Kylin` 的连接地址,以及用户名和密码,连接地址为 `http://${kylin_node_public_ip}:7080/mdx/xmla/covid_trip_project`:
+
+![](/images/blog/kylin4_on_cloud/22_tableau_server.png)
+
+3.选择 `covid_trip_dataset` 作为数据集:
+
+![](/images/blog/kylin4_on_cloud/23_tableau_dataset.png)
+
+4.然后即可在工作表中进行数据分析,由于我们在 `MDX for Kylin` 中已经统一定义了业务指标,所以在 tableau 中制作数据分析报表时,可以直接拖拽定义好的业务指标到工作表中进行展示。
+
+5.首先分析疫情数据,通过确诊人数、病死率两个指标来绘制国家级别的疫情地图,只需要将地区层级中的 `COUNTRY_SHORT_NAME` 放到工作表的列中 ,将事先定义好的新增确诊人数总和 `SUM_NEW_POSITIVE_CASES` 和病死率指标 `CFR_COVID19` 放到工作表的行中,然后选择以地图形式展示数据结果:
+
+![](/images/blog/kylin4_on_cloud/24_tableau_covid19_map.png)
+
+其中,图标面积代表死亡人数级别,图标颜色深浅代表病死率级别。通过疫情地图可以看出,美国和印度的确诊人数相对较多,但是这两个国家的病死率与其他大多数国家没有明显差别;而确诊人数很少的秘鲁、瓦努阿图、墨西哥等国家的病死率则居高不下。从这个现象入手,也许可以挖掘到更深层次的原因。
+
+由于我们设置了地区层级,所以可以将国家级别的疫情地图下钻到省级别,查看各个国家内部各个地区的疫情情况:
+
+![](/images/blog/kylin4_on_cloud/25_tableau_province.png)
+
+在 province 级别的疫情地图放大看美国的疫情状况:
+
+![](/images/blog/kylin4_on_cloud/26_tableau_us_covid19.png)
+
+可以发现,美国每个州的病死率没有明显差距,都在 0.01 左右;在确诊人数上,California、Texas、Florida 以及纽约市几个地区明显偏高,这几个地区经济发达、人口众多,新冠肺炎确诊人数也随之攀升。下面针对纽约市出租车数据集,结合疫情发展情况,分析疫情形势下人们乘坐出租车出行的数据变化。
+
+6.对于纽约市出租车订单数据集,分别从以下两个业务问题入手:
+
+- 分析纽约市各个街区出行特征,对比订单数量、出行速度等出行指标
+
+将 lookup 表 `PICKUP_NEWYORK_ZONE` 中的字段 `BOROUGH` 拖拽到工作表的列中,将指标 `ORDER_COUNT`、`trip_mean_speed` 拖拽到工作表的行中,以符号地图的方式展示,颜色深浅代表平均速度、面积大小代表订单数量,可以看到从曼哈顿区出发的出租车订单比别的街区总和都要高,但是平均速度最小,Queens 街区次之,Staten Island 则是出租车活动最少的一个街区。从 Bronx 出发的出租车平均速度高达 82 英里/小时,比其他街区的平均速度都高出几倍。从这些出行特征可以映射出纽约市各个街区的人口密集程度以及经济发达程度。
+
+![](/images/blog/kylin4_on_cloud/27_tableau_taxi_1.png)
+
+然后将 lookup 表 `PICKUP_NEWYORK_ZONE` 中的字段 `BOROUGH` 换成 `DROPOFF_NEWYORK_ZONE` 中的 `BOROUGH`,统计出租车订单到达街区的数量和平均速度:
+
+![](/images/blog/kylin4_on_cloud/27_tableau_taxi_2.png)
+
+相比出发街区的数据,brookly、Queens 和 Bronx 三个街区的到达数据都有比较明显的差别,从比例关系上来看,到达 brookly 和 Bronx 的出租车订单要远远多于从 Brookly 和 Bronx 出发的订单,到达 Queens 街区的订单数量则明显小于从 Queens 街区出发的订单。
+
+- 疫情前后纽约市居民乘坐出租车的出行习惯变化,更偏向远程出行还是近程
+
+通过平均出行里程分析居民出行习惯变化,将维度 `MONTH_START` 拖拽到工作表的行,将指标 `trip_mean_distance` 拖拽到工作表的列:
+
+![](/images/blog/kylin4_on_cloud/28_tableau_taxi_3.png)
+
+根据柱状图的结果可以发现,疫情前后人们的出行习惯发生了明显的变化,从 2020.03 开始平均出行里程有明显升高,甚至有的月份发生数倍增长,并且疫情开始后每个月的平均出行里程变的很不稳定。基于这种数据表现,我们可以再结合月份维度的疫情数据进行联合分析,将 `SUM_NEW_POSITIVE_CASES` 和 `MTD_ORDER_COUNT` 拖拽到工作表的行中,并在筛选器中增加筛选条件 `PROVINCE_STATE_NAME=New York`:
+
+![](/images/blog/kylin4_on_cloud/29_tableau_taxi_4.png)
+
+可以看到一个有趣的现象,疫情初期刚刚爆发的时候出租车订单量急剧减少,而平均出行里程增大,说明大家减少了很多不必要的短距离出行,或者采用出租车以外的更安全的交通方式进行了短距离出行。对比三种数据的曲线变化,可以看到疫情严重程度和人们的出行情况表现出很高的相关性,疫情严重时出租车订单量减少,平均出行里程攀升,然后疫情好转,出租车订单量增大,平均出行里程回落。
+
+### 通过 Excel 进行数据分析
+
+有了 `MDX for Kylin` 的帮助,我们在 Excel 中也可以连接 Kylin 进行大数据分析。这次测试中,我们使用本地 windows 机器上的 Excel 连接 MDX for Kylin 进行演示。
+
+1.打开 Excel,选择 数据 -> 获取数据 -> 来自数据库 -> 自 `Analysis Services`:
+
+![](/images/blog/kylin4_on_cloud/30_excel_connect.png)
+
+2.在数据连接向导中填写MDX for Kylin 连接信息,服务器名称为 `http://${kylin_node_public_ip}:7080/mdx/xmla/covid_trip_project`:
+
+![](/images/blog/kylin4_on_cloud/31_excel_server.png)
+
+![](/images/blog/kylin4_on_cloud/32_tableau_dataset.png)
+
+3.然后为当前的数据连接创建数据透视表,在数据透视表字段中,我们可以看到,在 Excel 中连接 `MDX for Kylin` 中的 dataset 获取数据信息,可以与 Tableau 保持完全一致,无论分析人员是在 Tableau 还是 Excel 中进行分析,都是在一致的数据模型、维度和业务指标的基础上,达到统一语义的效果。
+
+4.在 Tableau 中我们对 `covid19` 和 `newyork_trip_data` 两个数据集进行了疫情地图绘制和趋势分析。在 Excel 中对于同样的数据集和数据场景,我们可以查看更多的明细数据。
+
+- 对于疫情数据,为数据透视表选取地区层级字段 `REGION_HIERARCHY`,以及事先定义好的新增病例数总和 `SUM_NEW_POSITIVE_CASES` 和病死率指标 `CFR_COVID19`:
+
+![](/images/blog/kylin4_on_cloud/33_tableau_covid19_1.png)
+
+由于地区层级的最上层为 `CONTINENT_NAME`,所以默认展示洲级别的确诊人数和病死率,可以看到确诊人数最多的洲是欧洲,病死率最高的是非洲。在这张数据透视表中我们可以方便的下钻到更下层的地区级别查看更细粒度的明细数据,比如查看亚洲国家的疫情数据,并根据确诊人数进行降序排序:
+
+![](/images/blog/kylin4_on_cloud/34_excel_covid20_2.png)
+
+数据显示,亚洲国家中确诊人数排名前三的国家分别是印度、土耳其和伊朗。
+
+- 对于纽约市出租车订单数据,针对 “疫情对于出租车订单数量有无明显影响” 的问题,首先从年份的维度上查看出租车订单数量的年累计和增速,新建透视表选择时间层级维度 `TIME_HIERARCHY`、`YOY_ORDER_COUNT` 和 `YTD_ORDER_COUNT`:
+
+![](/images/blog/kylin4_on_cloud/35_excel_taxi_1.png)
+
+可以看到,2020 年疫情爆发导致出租车订单数量急剧减少,2020年订单量增速为 -0.7079,减少了 70% 的出行订单,2021 年订单量增速仍为负数,但是相比 2020 年疫情初期订单量减少速度放缓了许多。
+
+展开时间层级,可以查看季度级别、月级别直到天级别的订单累计值,选择 `MOM_ORDER_COUNT` 和 `ORDER_COUNT` 到透视表中还可以同时查看月度订单增速以及各个时间层级的订单数量:
+
+![](/images/blog/kylin4_on_cloud/36_excel_taxi_2.png)
+
+2020 年 3 月份,订单增速为 -0.52,出租车订单已经出现明显减少,4 月份更是跌至 -0.92,减少了 90% 的订单,后期开始慢慢增长,但是也始终远低于疫情之前的数量。
+
+### 通过 API 集成 Kylin 到数据分析平台
+
+除了 Excel、Tableau 这种商业 BI 工具,很多企业内部会开发自己的数据分析平台,在这类自研数据分析平台上,用户仍然可以通过调用 API 的方式将 Kylin + MDX for Kylin 作为分析平台的基础底座,保证统一的数据口径。在这次演示中,我们将展示如何通过 Olap4j 向 MDX for Kylin 发送查询,获得分析结果,Olap4j 是一个与 JDBC 驱动类似,能够访问任意 OLAP 服务的 Java 库。
+
+我们提供了一个简单的 demo 可以方便用户直接进行测试,源码位于 [mdx query demo](https://github.com/apache/kylin/tree/mdx-query-demo):
+
+1.下载 demo 演示相关 jar 包:
+
+```
+wget https://s3.cn-north-1.amazonaws.com.cn/public.kyligence.io/kylin/kylin_demo/mdx_query_demo.tgz
+tar -xvf mdx_query_demo.tgz
+cd mdx_query_demo
+```
+
+2.运行 demo
+
+运行 demo 之前保证运行环境安装了 java8:
+
+![](/images/blog/kylin4_on_cloud/37_jdk_8.png)
+
+运行 demo 需要两个参数,mdx 节点的 ip 和 需要运行的 mdx 查询,端口默认为 7080,这里的 mdx 节点 ip 就是 kylin 节点的 public ip:
+
+```
+java -cp olap4j-xmla-1.2.0.jar:olap4j-1.2.0.jar:xercesImpl-2.9.1.jar:mdx-query-demo-0.0.1.jar io.kyligence.mdxquerydemo.MdxQueryDemoApplication "${kylin_node_public_ip}" "${mdx_query}"
+```
+
+如果用户在运行 demo 时没有通过命令行输入需要执行的 mdx 语句,则会默认执行以下 mdx 语句统计从出发街区的维度上各个街区的订单数量和平均里程:
+
+```
+SELECT
+{[Measures].[ORDER_COUNT],
+[Measures].[trip_mean_distance]}
+DIMENSION PROPERTIES [MEMBER_UNIQUE_NAME],[MEMBER_ORDINAL],[MEMBER_CAPTION] ON COLUMNS,
+NON EMPTY [PICKUP_NEWYORK_ZONE].[BOROUGH].[BOROUGH].AllMembers
+DIMENSION PROPERTIES [MEMBER_UNIQUE_NAME],[MEMBER_ORDINAL],[MEMBER_CAPTION] ON ROWS
+FROM [covid_trip_dataset]
+```
+
+在这次演示中我们直接执行默认查询,执行成功之后,经过简单处理的查询结果会输出到命令行:
+
+![](/images/blog/kylin4_on_cloud/38_demo_result.png)
+
+可以看到,运行 Demo 之后成功获得了需要查询的数据,数据结果显示,从 Manhattan 出发的出租车订单数量最多,订单平均里程只有大约 2.4 英里,符合 Manhattan 地理面积小且人口稠密的特点;而从 Bronx 的订单平均里程达到 33 英里,成倍的高于其他任何街区,可能是由于 Bronx 地处偏僻的缘故。
+
+与 Tableau 和 Excel 相同,在 Demo 中编写的 mdx 语言中可以直接使用在 Kylin 以及 MDX for Kylin 中定义的指标。在企业自研数据分析平台中,用户可以对查询返回的数据结果进行进一步分析,根据展示需求生成报表。
+
+### 统一的数据口径
+
+通过以三种不同的数据分析方式连接 Kylin + MDX for Kylin 进行数据分析展示,我们可以发现,借助 Kylin 多维数据库和 MDX for Kylin 语义层功能,无论用户在业务场景中使用哪种方式分析数据,都可以使用相同的数据模型和业务指标,达到统一数据口径的目的。
+
+## 销毁集群
+
+### 销毁查询集群
+
+在上述分析完成之后,我们可以执行集群销毁命令来销毁查询集群。如果用户希望同时销毁 Kylin 以及 MDX for Kylin 的元数据库 RDS、监控节点以及 VPC,那么可以执行集群销毁命令:
+
+```
+python deploy.py --type destroy-all
+```
+
+### 检查 AWS 资源
+
+在销毁所有集群资源后,`CloudFormation` 中不会保留与部署工具相关的任何 Stack。如果用户想要删除 S3 中与部署工具相关的文件以及数据,可以手动删除 S3 工作目录下的以下文件夹:
+
+![](/images/blog/kylin4_on_cloud/39_check_s3_demo.png)
+
+## 总结
+
+通过这次演示教程,只需要一个 AWS 账号,用户就可以使用云上部署工具,借助于 Kylin 的预计算技术和多维模型,以及MDX for Kylin 的基础指标管理,快速且方便的搭建基于 Kylin + MDX for Kylin 的云上大数据分析平台,对接各种 BI 工具进行技术验证,达到降本增效、统一数据口径的目的。
+
+
+
diff --git a/website/images/blog/kylin4_on_cloud/0_deploy_kylin.png b/website/images/blog/kylin4_on_cloud/0_deploy_kylin.png
new file mode 100644
index 0000000000..1b846c4a4d
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/0_deploy_kylin.png differ
diff --git a/website/images/blog/kylin4_on_cloud/10_full_build_cube.png b/website/images/blog/kylin4_on_cloud/10_full_build_cube.png
new file mode 100644
index 0000000000..77a9c176bc
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/10_full_build_cube.png differ
diff --git a/website/images/blog/kylin4_on_cloud/11_kylin_job_complete.png b/website/images/blog/kylin4_on_cloud/11_kylin_job_complete.png
new file mode 100644
index 0000000000..24ec405734
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/11_kylin_job_complete.png differ
diff --git a/website/images/blog/kylin4_on_cloud/12_destroy_job_cluster.png b/website/images/blog/kylin4_on_cloud/12_destroy_job_cluster.png
new file mode 100644
index 0000000000..914f01b923
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/12_destroy_job_cluster.png differ
diff --git a/website/images/blog/kylin4_on_cloud/13_check_aws_stacks.png b/website/images/blog/kylin4_on_cloud/13_check_aws_stacks.png
new file mode 100644
index 0000000000..9aaf8576a1
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/13_check_aws_stacks.png differ
diff --git a/website/images/blog/kylin4_on_cloud/14_kylin_web_ui.png b/website/images/blog/kylin4_on_cloud/14_kylin_web_ui.png
new file mode 100644
index 0000000000..eb035db6d4
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/14_kylin_web_ui.png differ
diff --git a/website/images/blog/kylin4_on_cloud/15_query_in_kylin.png b/website/images/blog/kylin4_on_cloud/15_query_in_kylin.png
new file mode 100644
index 0000000000..bb1a825b2f
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/15_query_in_kylin.png differ
diff --git a/website/images/blog/kylin4_on_cloud/16_mdx_web_ui.png b/website/images/blog/kylin4_on_cloud/16_mdx_web_ui.png
new file mode 100644
index 0000000000..5a81e21c22
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/16_mdx_web_ui.png differ
diff --git a/website/images/blog/kylin4_on_cloud/17_connect_to_kylin.png b/website/images/blog/kylin4_on_cloud/17_connect_to_kylin.png
new file mode 100644
index 0000000000..f124b5b365
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/17_connect_to_kylin.png differ
diff --git a/website/images/blog/kylin4_on_cloud/18_exit_management.png b/website/images/blog/kylin4_on_cloud/18_exit_management.png
new file mode 100644
index 0000000000..4e8fbc25ab
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/18_exit_management.png differ
diff --git a/website/images/blog/kylin4_on_cloud/19_kylin_running.png b/website/images/blog/kylin4_on_cloud/19_kylin_running.png
new file mode 100644
index 0000000000..c7947601e6
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/19_kylin_running.png differ
diff --git a/website/images/blog/kylin4_on_cloud/1_table_ER.png b/website/images/blog/kylin4_on_cloud/1_table_ER.png
new file mode 100644
index 0000000000..5a09bd4680
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/1_table_ER.png differ
diff --git a/website/images/blog/kylin4_on_cloud/20_import_dataset.png b/website/images/blog/kylin4_on_cloud/20_import_dataset.png
new file mode 100644
index 0000000000..3a0fdd53fe
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/20_import_dataset.png differ
diff --git a/website/images/blog/kylin4_on_cloud/21_tableau_connect.png b/website/images/blog/kylin4_on_cloud/21_tableau_connect.png
new file mode 100644
index 0000000000..257aa679e3
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/21_tableau_connect.png differ
diff --git a/website/images/blog/kylin4_on_cloud/22_tableau_server.png b/website/images/blog/kylin4_on_cloud/22_tableau_server.png
new file mode 100644
index 0000000000..df22c3c253
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/22_tableau_server.png differ
diff --git a/website/images/blog/kylin4_on_cloud/23_tableau_dataset.png b/website/images/blog/kylin4_on_cloud/23_tableau_dataset.png
new file mode 100644
index 0000000000..742ed113d5
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/23_tableau_dataset.png differ
diff --git a/website/images/blog/kylin4_on_cloud/24_tableau_covid19_map.png b/website/images/blog/kylin4_on_cloud/24_tableau_covid19_map.png
new file mode 100644
index 0000000000..6e1b6cafbd
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/24_tableau_covid19_map.png differ
diff --git a/website/images/blog/kylin4_on_cloud/25_tableau_province.png b/website/images/blog/kylin4_on_cloud/25_tableau_province.png
new file mode 100644
index 0000000000..7364020780
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/25_tableau_province.png differ
diff --git a/website/images/blog/kylin4_on_cloud/26_tableau_us_covid19.png b/website/images/blog/kylin4_on_cloud/26_tableau_us_covid19.png
new file mode 100644
index 0000000000..86c48dfc3f
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/26_tableau_us_covid19.png differ
diff --git a/website/images/blog/kylin4_on_cloud/27_tableau_taxi_1.png b/website/images/blog/kylin4_on_cloud/27_tableau_taxi_1.png
new file mode 100644
index 0000000000..40fa6dbc22
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/27_tableau_taxi_1.png differ
diff --git a/website/images/blog/kylin4_on_cloud/27_tableau_taxi_2.png b/website/images/blog/kylin4_on_cloud/27_tableau_taxi_2.png
new file mode 100644
index 0000000000..c98a424de2
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/27_tableau_taxi_2.png differ
diff --git a/website/images/blog/kylin4_on_cloud/28_tableau_taxi_3.png b/website/images/blog/kylin4_on_cloud/28_tableau_taxi_3.png
new file mode 100644
index 0000000000..50751de2fd
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/28_tableau_taxi_3.png differ
diff --git a/website/images/blog/kylin4_on_cloud/29_tableau_taxi_4.png b/website/images/blog/kylin4_on_cloud/29_tableau_taxi_4.png
new file mode 100644
index 0000000000..2e16e137fa
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/29_tableau_taxi_4.png differ
diff --git a/website/images/blog/kylin4_on_cloud/2_step_overview.jpg b/website/images/blog/kylin4_on_cloud/2_step_overview.jpg
new file mode 100644
index 0000000000..c2a1f1efe1
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/2_step_overview.jpg differ
diff --git a/website/images/blog/kylin4_on_cloud/30_excel_connect.png b/website/images/blog/kylin4_on_cloud/30_excel_connect.png
new file mode 100644
index 0000000000..7a18fea437
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/30_excel_connect.png differ
diff --git a/website/images/blog/kylin4_on_cloud/31_excel_server.png b/website/images/blog/kylin4_on_cloud/31_excel_server.png
new file mode 100644
index 0000000000..e3785388c1
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/31_excel_server.png differ
diff --git a/website/images/blog/kylin4_on_cloud/32_tableau_dataset.png b/website/images/blog/kylin4_on_cloud/32_tableau_dataset.png
new file mode 100644
index 0000000000..ab0961b790
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/32_tableau_dataset.png differ
diff --git a/website/images/blog/kylin4_on_cloud/33_tableau_covid19_1.png b/website/images/blog/kylin4_on_cloud/33_tableau_covid19_1.png
new file mode 100644
index 0000000000..781cc8d5ea
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/33_tableau_covid19_1.png differ
diff --git a/website/images/blog/kylin4_on_cloud/34_excel_covid20_2.png b/website/images/blog/kylin4_on_cloud/34_excel_covid20_2.png
new file mode 100644
index 0000000000..eb42b5a6de
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/34_excel_covid20_2.png differ
diff --git a/website/images/blog/kylin4_on_cloud/35_excel_taxi_1.png b/website/images/blog/kylin4_on_cloud/35_excel_taxi_1.png
new file mode 100644
index 0000000000..76fb12ae6f
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/35_excel_taxi_1.png differ
diff --git a/website/images/blog/kylin4_on_cloud/36_excel_taxi_2.png b/website/images/blog/kylin4_on_cloud/36_excel_taxi_2.png
new file mode 100644
index 0000000000..bee1af746a
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/36_excel_taxi_2.png differ
diff --git a/website/images/blog/kylin4_on_cloud/37_jdk_8.png b/website/images/blog/kylin4_on_cloud/37_jdk_8.png
new file mode 100644
index 0000000000..f0b95034d5
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/37_jdk_8.png differ
diff --git a/website/images/blog/kylin4_on_cloud/38_demo_result.png b/website/images/blog/kylin4_on_cloud/38_demo_result.png
new file mode 100644
index 0000000000..1555ba909f
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/38_demo_result.png differ
diff --git a/website/images/blog/kylin4_on_cloud/39_check_s3_demo.png b/website/images/blog/kylin4_on_cloud/39_check_s3_demo.png
new file mode 100644
index 0000000000..acf27ac55e
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/39_check_s3_demo.png differ
diff --git a/website/images/blog/kylin4_on_cloud/3_kylin_cluster.jpg b/website/images/blog/kylin4_on_cloud/3_kylin_cluster.jpg
new file mode 100644
index 0000000000..ef9327a3e9
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/3_kylin_cluster.jpg differ
diff --git a/website/images/blog/kylin4_on_cloud/4_deploy_cluster_successfully.png b/website/images/blog/kylin4_on_cloud/4_deploy_cluster_successfully.png
new file mode 100644
index 0000000000..6c4989a8b2
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/4_deploy_cluster_successfully.png differ
diff --git a/website/images/blog/kylin4_on_cloud/5_check_aws_stacks.png b/website/images/blog/kylin4_on_cloud/5_check_aws_stacks.png
new file mode 100644
index 0000000000..f894544c47
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/5_check_aws_stacks.png differ
diff --git a/website/images/blog/kylin4_on_cloud/6_list_cluster_node.png b/website/images/blog/kylin4_on_cloud/6_list_cluster_node.png
new file mode 100644
index 0000000000..09babe4f30
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/6_list_cluster_node.png differ
diff --git a/website/images/blog/kylin4_on_cloud/7_query_in_spark_sql.png b/website/images/blog/kylin4_on_cloud/7_query_in_spark_sql.png
new file mode 100644
index 0000000000..c53a69f8ff
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/7_query_in_spark_sql.png differ
diff --git a/website/images/blog/kylin4_on_cloud/8_kylin_web_ui.png b/website/images/blog/kylin4_on_cloud/8_kylin_web_ui.png
new file mode 100644
index 0000000000..8bec70bbe1
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/8_kylin_web_ui.png differ
diff --git a/website/images/blog/kylin4_on_cloud/9_reload_kylin_metadata.png b/website/images/blog/kylin4_on_cloud/9_reload_kylin_metadata.png
new file mode 100644
index 0000000000..3ce9b6bad4
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/9_reload_kylin_metadata.png differ
diff --git a/website/images/blog/kylin4_on_cloud/kylin_on_cloud.png b/website/images/blog/kylin4_on_cloud/kylin_on_cloud.png
new file mode 100644
index 0000000000..d27bb2c162
Binary files /dev/null and b/website/images/blog/kylin4_on_cloud/kylin_on_cloud.png differ