byconity - 云原生大数据分析引擎 clickhouse
https://github.com/ByConity/ByConity
https://byconity.github.io/zh-cn/
# ninja
cd /opt
wget https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-linux.zip
unzip ninja-linux.zip -d /usr/local/bin/
update-alternatives --install /usr/bin/ninja ninja /usr/local/bin/ninja 1 --force
ninja --version
1.11.1
# docker
cd /data/site/docker/data/byconity/
git clone https://github.com/ByConity/ByConity
cd ByConity
git submodule update --init --recursive
git config --global --add safe.directory "*"
---
注意git异常,降级到git1
---
cd docker/builder
make build
cd docker/executable_wrapper
make image
make image_push
# run server
docker run -d --network=host --user=0:0 --restart=always --name byconity -e TZ='Asia/Shanghai' -v /etc/localtime:/etc/localtime:ro -v /data/site/docker/data/byconity/ccache:/ccache -v /data/site/docker/data/byconity/ByConity:/server --workdir /server --cap-add=SYS_PTRACE --mount type=bind,source='/data/site/docker/data/byconity/config,target=/root/app/config' --mount type=bind,source='/data/site/docker/data/byconity/logs,target=/root/app/logs' --mount type=bind,source='/data/site/docker/data/byconity/data,target=/root/app/data' byconity/byconity-builder server -C --config-file /root/app/config/server.xml
docker exec -it byconity /bin/bash
# run cli
docker run -d --network=host --user=0:0 --restart=always --name bcli -e TZ='Asia/Shanghai' -v /etc/localtime:/etc/localtime:ro -v /data/site/docker/data/byconity/ccache:/ccache -v /data/site/docker/data/byconity/git:/server --workdir /server --cap-add=SYS_PTRACE byconity/byconity-builder client --host 127.0.0.1 --port 18684
docker exec -it bcli /bin/bash
- use
-您计划部署TSO的机器,请执行 ./run.sh tso 命令来运行TSO
./run.sh tso
./run.sh rm
-运行服务器
./run.sh server
-以运行读取工作进程。您可以通过在不同的机器上重复此命令来创建多个工作进程,并将这些工作进程的信息添加到 config/cnch_config.xml 中的 service_discovery 标签中,以便服务器可以识别它们。
./run.sh read_worker
-运行写入工作进程
./run.sh writer_worker
-以运行守护进程管理器(daemon manager)
TSO和DM是轻量级服务,可以在与服务器或工作进程相同的机器上运行,以实现资源的高效利用。
./run.sh dm
-命令,或者从任何机器上执行 ./run.sh cli2 {server_address} 命令以使用clickhouse-cli界面连接到服务器
./run.sh cli
# 部署
安装 FoundationDB 和 HDFS
ByConity 使用 FoundationDB 作为元存储,使用 HDFS 作为数据存储。因此,在开始部署 ByConity 之前,我们需要先部署 FoundationDB 和 HDFS。
-部署 FoundationDB, https://apple.github.io/foundationdb/downloads.html
curl -L -o fdbserver https://github.com/apple/foundationdb/releases/download/7.1.25/fdbserver.x86_64
curl -L -o fdbmonitor https://github.com/apple/foundationdb/releases/download/7.1.25/fdbmonitor.x86_64
curl -L -o fdbcli https://github.com/apple/foundationdb/releases/download/7.1.25/fdbcli.x86_64
chmod ug+x fdbcli fdbmonitor fdbserver
-接下来我们将创建一些文件夹来存储配置、数据和日志:
mkdir -p /data/fdb_runtime/config
mkdir -p /data/fdb_runtime/data
mkdir -p /data/fdb_runtime/logs
vim /data/fdb_runtime/config/foundationdb.conf
[fdbmonitor] user = root [general] cluster-file = /data/fdb_runtime/config/fdb.cluster restart-delay = 60 [fdbserver] command = /data/foundationdb/bin/fdbserver datadir = /data/fdb_runtime/data/$ID logdir = /data/fdb_runtime/logs/ public-address = auto:$ID listen-address = public [fdbserver.4500] class=stateless [fdbserver.4501] class=transaction [fdbserver.4502] class=storage [fdbserver.4503] class=stateless
然后在相同的文件夹中创建一个名为fdb.cluster的文件,内容如下,将<your_ip_address>替换为你的机器IP地址:
vim /data/fdb_runtime/config/fdb.cluster
clusterdsc:test@<your_ip_address>:4500
我们将FDB安装为systemd服务。因此,在同一文件夹中,我们将创建名为fdb.service的文件,内容如下:
vim /data/fdb_runtime/config/fdb.service
[Unit] Description=FoundationDB (KV storage for cnch metastore) [Service] Restart=always RestartSec=30 TimeoutStopSec=600 ExecStart=/data/foundationdb/bin/fdbmonitor --conffile /data/fdb_runtime/config/foundationdb.conf --lockfile /data/fdb_runtime/fdbmonitor.pid [Install] WantedBy=multi-user.target
我们已经完成了配置文件的准备工作。现在让我们将FDB安装到systemd中。
-将服务文件复制到/etc/systemd/system/目录下:
cp fdb.service /etc/systemd/system/
-重新加载服务文件以包括新服务:
systemctl daemon-reload
-启用并启动服务:
systemctl enable fdb.service systemctl start fdb.service
-检查服务并查看它是否处于活动状态:
systemctl status fdb.service
现在我已经在一台机器上安装了FDB服务,我将重复相同的步骤在另外两台机器上安装。
在所有三台机器上安装完成之后,我们需要连接它们以形成一个集群。
现在回到第一台节点,使用fdbcli连接到FDB。
./foundationdb/bin/fdbcli -C fdb_runtime/config/fdb.cluster
执行以下命令来初始化数据库:
configure new single ssd
接下来,将三个机器都设置为coordinator,并将地址替换为你的机器地址:
coordinators <node_1_ip_address>:4500 <node_2_ip_address>:4500 <node_3_ip_address>:4500
然后退出fdbcli,你会发现fdb.cluster文件现在有了新内容:
cat fdb_runtime/config/fdb.cluster
# DO NOT EDIT! # This file is auto-generated, it is not to be edited by hand clusterdsc:wwxVEcyLvSiO3BGKxjIw7Sg5d1UTX5ad@example1.host.com:4500,example2.host.com:4500,example3.host.com:4500
将此文件复制到另外两台机器并替换旧文件,然后重新启动fdb服务:
systemctl restart fdb.service
然后返回第一台机器,再次使用fdbcli连接到FDB,并执行以下命令将冗余模式更改为triple:
configure triple
然后在fdbcli中执行status命令以查看结果,你应该看到类似以下的内容:
fdb> status Using cluster file `fdb_runtime/config/fdb.cluster'. Configuration: Redundancy mode - triple Storage engine - ssd-2 Coordinators - 3 Usable Regions - 1
这就完成了FoundationDB服务器的安装。现在你拥有了fdb.cluster文件。我们将在Byconity的配置中使用它。
-安装 HDFS
将在3台机器上设置HDFS,其中1台机器用于namenode,其他2台机器用于datanode。我参考了以下官方文档SingleCluster和ClusterSetup。我将安装HDFS版本3.3.4,因此我需要Java-8,因为这是推荐的Java版本
apt-get update
apt-get install openjdk-8-jdk
cd /opt
curl -L -o hadoop-3.3.4.tar.gz https://dlcdn.apache.org/hadoop/common/stable/hadoop-3.3.4.tar.gz
tar xvf hadoop-3.3.4.tar.gz
cd hadoop-3.3.4
vim etc/hadoop/hadoop-env.sh
export JAVA_HOME=/usr/lib/jvm/java-8-byteopenjdk-amd64 export HADOOP_HOME=/<your_directory>/hdfs/hadoop-3.3.4 export HADOOP_LOG_DIR=/<your_directory>/hdfs/logs
vim etc/hadoop/core-site.xml
<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://<your_name_node_ip_address>:12000</value> </property> </configuration>
请注意,“value”标签将是您的namenode地址的值
现在我们已经完成了所有三台机器的通用设置。从现在开始,namenode和datanode的设置是不同的。 在我们想要安装namenode的节点中,我们创建一个包含datanode列表的文件。例如,在我的情况下,我创建了datanodes_list.txt,其内容如下
cat /data/hdfs/datanodes_list.txt <datanode_1_address> <datanode_2_address>
然后创建一个目录以存储namenode运行时数据
mkdir -p /data/hdfs/root_data_path_for_namenode
vim etc/hadoop/hdfs-site.xml
<configuration> <property> <name>dfs.replication</name> <value>1</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>file:///data/hdfs/root_data_path_for_namenode</value> </property> <property> <name>dfs.hosts</name> <value>/data>/hdfs/datanodes_list.txt</value> </property> </configuration>
这就是关于namenode的全部内容。
现在对于那两个需要部署数据节点的节点,创建一个目录来存储数据节点的运行时数据。
mkdir -p /data/hdfs/root_data_path_for_datanode
vim etc/hadoop/hdfs-site.xml
<configuration> <property> <name>dfs.data.dir</name> <value>file:///data/hdfs/root_data_path_for_datanode</value> </property> </configuration>
我们已经完成了配置,现在转到namenode机器,进入hadoop目录 格式化文件系统并使用以下命令启动namenode
bin/hdfs namenode -format
bin/hdfs --daemon start namenode
然后进入另外两个数据节点机器,进入hadoop目录并使用以下命令启动数据节点
bin/hdfs --daemon start datanode
我们已经完成了HDFS的设置。现在我们将必须创建一个目录来存储数据。 因此,进入namenode机器,在hadoop目录中执行以下命令
bin/hdfs dfs -mkdir -p /user/clickhouse/
bin/hdfs dfs -chown clickhouse /user/clickhouse
bin/hdfs dfs -chmod -R 775 /user/clickhouseByConity 是分布式的云原生SQL数仓引擎,擅长交互式查询和即席查询,具有支持多表关联复杂查询、集群扩容无感、离线批数据和实时数据流统一汇总等特点。
1.简介
1.1推荐场景案例
1.通用场景
ByConity 使用大量成熟 OLAP 技术,例如列存引擎,MPP 执行,智能查询优化,向量化执行,Codegen, indexing,数据压缩,主要用于 OLAP 查询和计算场景。在实时数据接入、大宽表聚合查询、海量数据下复杂分析计算、多表关联查询场景下有非常好的性能。
| 场景分类 | 场景 | 描述 | 特点 |
|---|---|---|---|
| 交互式查询 | 用户自定义查询 | 支持多维查询分析的数据应用 | 自由维度、多表关联、响应快 |
| 自助式报表 | 支持 Tableau 等 BI 工具 | 自由维度、多表关联、响应快 | |
| 用户画像分析 | 支持 DMP 等圈人画像平台 | 自由维度、多表关联、响应快 | |
| 营销效果分析 | 支持流量效果漏斗分析 | 多表关联、实时 | |
| 行为日志分析 | 支持日志探索分析 | 日志检索、数据量大 | |
| 实时数据看板 | 实时业务监控大屏 | 支持 DataV 等可视化大屏 | 实时 |
| 直播数据统计看板 | 支持实时报表 | 实时 | |
| 业务仪表盘 | 支持报表工具 | 统计、响应快 | |
| 系统链路监控 | 支持实时监控应用 | 实时 | |
| 实时数据仓库 | 实时数据接入 | 支持实时数据写入、更新 | 实时数据写入,立即可见 |
| 准实时 ETL 计算 | 支持复杂计算,数据清洗 | 混合负载 |
2.多租户隔离和资源共享
在 ByConity 里,用户可以为查询 SQL 指定计算组,实现物理资源隔离,避免不同租户之间查询互相干扰。当然,为了提高资源利用率,ByConity 也支持计算组之间的资源租借,实现资源共享。
3.读写计算分离
ByConity 存储计算分离的架构,使其原生支持存储计算分离,insert 使用专门用于写入的计算组,select 使用专门用于读取的计算组,读写作业之间不会相互影响。
4.实时扩缩容
ByConity 存储计算分离架构设计使其完美契合有动态扩缩容需求的场景,根据实际资源需求最大化资源利用率,降低成本。ByConity 的元数据和数据存储在远端,计算节点的无状态化使扩缩容变得十分轻量,只需等计算实例启动完成,即可立即服务,无需额外的数据迁移开销,实现实时扩缩容。
1.2.主要原理概念
ByConity 的查询执行流程如下图所示,首先通过元数据服务获取查询所需要的元数据信息,然后根据用户 sql 通过优化器生成高效的查询计划,并调度到相应的计算组上去读取数据并执行,最终进行结果集的汇总并发送回客户端。为了用户更好的了解 ByConity 查询的工作原理,此章会介绍 ByConity 的主要原理。
1.元数据管理(Catalog Service)
元数据管理(Catalog Service)的功能主要是对读写请求的元数据进行读写操作。元数据服务是一个非常关键的服务,其决定了查询的可用性和正确性。在 ByConity 里,我们不仅提供了高可用,可扩展的元数据管理服务,还在其之上实现了完备的事务语义保证(ACID)。除此之外,ByConity 还借助缓存,对查询涉及到的原数据提供低延迟读取,保证查询性能高效稳定。
2.查询优化器(Query Optimizer)
- RBO:基于规则的优化能力。支持:列裁剪、分区裁剪、表达式简化、子查询解关联、谓词下推、冗余算子消除、Outer-JOIN 转 INNER-JOIN、算子下推存储、分布式算子拆分等常见的启发式优化能力。
- CBO:基于代价的优化能力。支持:Join Reorder、Outer-Join Reorder、Join/Agg Reorder、CTE、物化视图、Dynamic Filter 下推、Magic Set 等基于代价的优化能力。并且面向分布式计划融合了 Property Enforcement。
- DBO:基于数据依赖的优化能力。支持:唯一键、functional dependency、Order dependency、Inclusion dependency 等基于数据依赖关系的优化能力。
- HBO:基于查询反馈的优化能力。支持:基数估计动态调整、并行度动态调整、执行计划动态调整等基于历史执行反馈的优化能力。
3.计算组(Virtual Warehouse)
- 一种是纵向扩容,即调整计算组的 CPU 核数和内存大小;
- 另一种是横向扩容,增减计算组的数量,提升系统并发能力;
4.虚拟文件系统(Virtual File System-VFS)
5.列式存储(Columnar Storage)
6.主要流程
7.查询执行
1)用户提交 Select Query 到服务节点;
2)从元数据服务获取需要的元数据信息,对 Query 进行 Parsing,Planning,Optimising,生成执行计划;
3)服务节点根据可用的计算资源对执行计划进行调度,发送任务到计算节点;
4)计算节点接收到 Query 子查询;
5)Query 从虚拟文件系统(VFS) 获取数据,并根据 Query 的执行计划在计算节点上执行,并发回计算结果给服务节点汇总;
8.数据写入
用户提交 Write Query 到服务节点;
服务节点对写入请求根据调度策略选择合适的写入节点执行;
写入节点执行写入,将数据写到本地盘并 dump 到云存储端;
提交 part 元数据到元数据服务(Catalog Service),提交事务,写入完成;
9.计算组扩缩容
优化器(Query Optimizer) 是数据库系统的核心之一,优秀的优化器能极大提高查询性能,特别是在复杂查询场景下优化器能带来数倍至数百倍的性能提升。
# 核心优势,
1.高性能低成本
支持在海量数据规模下,通过向量化执行引擎、列式存储和CBO+RBO优化器达成亚秒级查询响应能力。同时超高压缩比率帮助用户节省大量存储空间,降低磁盘成本。
2.多种场景统一支持
支持实时数据流和离线批数据写入,具有交互式事物能力和多表关联查询能力,既可以满足线上系统的交互式查询需求,也可以满足后台实时监控、报表大屏等。
3.生态友好
兼容ClickHouse大多数接口和工具,支持Kafka、Spark、Flink等多种数据导入,也支持Superset,Tableau等数据可视化工具。
1.3.整体架构
ByConity 大体上可以分为 3 层:服务接入层,计算层和 存储层。服务接入层响应用户的查询,计算层负责计算数据,存储层存放用户数据。
1.3.1) 服务接入层
ByConity 的服务接入层接受用户的查询,首先对查询进行解析,并结合 catalog api 获取元数据信息生成高效的执行计划,然后通过资源管理器(Resource manager)获取可用的计算资源,最后把查询计划调度到适合(e.g.,拥有缓存)的计算节点进行执行。服务接入层由一个或者多个 server 构成,并支持水平扩张,充当的是响应用户服务和协调调度的角色。除了用户作业之外,在 ByConity 里还有后台任务,例如 compaction/gc 等等,这些后台任务由 Daemon manager 管理,调度到相应的 server 进行执行。
查询优化器是 ByConity 系统的核心之一,优秀的优化器能极大提高查询性能,特别是在复杂查询场景下优化器能带来数倍至数百倍的性能提升。ByConity 自研优化器基于四个大的优化方向(基于规则,基于 cost,基于数据依赖,基于反馈)提供极致优化能力。
1.3.2) 计算层
ByConity 的计算层由一个或者多个计算组构成,不同的租户可以使用不同的计算组实现物理资源隔离。资源管理器(Resource Manager)负责对计算资源进行统一的管理和调度,能够收集各个计算组的性能数据,资源使用量,为查询、写入和后台任务动态分配资源并进行动态扩缩容,提高资源使用率。
一个计算组由多个 worker 构成,每个节点收到 PlanSegment 之后,开始驱动 PlanSegment 执行,包含数据源的 PlanSegment 开始读取数据,将数据按照一定的 shuffle 规则分发到下游的各个节点上,包含 exchange 输入的 PlanSegment 等待上游的数据,如果需要继续做 shuffle 则会继续将数据下发给各个节点,多轮 stage 完成之后,结果会返回到服务端。
1.3.3) 数据存储层
ByConity 的元数据和数据都实现了存储计算分离,元数据存储在分布式 key-value store 里,数据存储在分布式文件系统或者对象存储里。
1.3.3.1) 元数据存储
ByConity 的元数据存储基于高性能的分布式 key-value store(FoundationDB)实现了一套通用的 catalog api,使得后端可插拔,方便扩展适配其他的 key-value store。ByConity 还在 catalog api 上层实现了完备事务语义(ACID)支持,提供了高效可靠的元数据服务,保证高数据质量。
1.3.3.1) 数据存储
ByConity 采用 HDFS 或 S3 等云存储服务作为数据存储层,用来存储实际数据、索引等内容。数据表的数据文件存储在远端的统一分布式存储系统中,与计算节点分离开来。ByConity 在远端分布式存储系统之上,实现了一层通用的 virtual file system api,方便底层扩展和适配不同的存储后端,例如 HDFS,Amazon S3, Google cloud storage,Azure blob storage,阿里云对象存储等等。
与主流分析数据类似,ByConity 采用列式存储格式,减少不必要的数据 IO 提高查询性能,并对数据进行高效压缩,降低存储成本。除此之外,对于连续存储的列式数据,ByConity 通过向量化执行技术,进一步提升查询性能。
2.快速上手
-连接数据库
./clickhouse-client -m -h HOST --port PORT
-创建库表
CREATE DATABASE IF NOT EXISTS helloworld; CREATE TABLE helloworld.my_first_table ( user_id UInt32, message String, timestamp DateTime ) ENGINE = CnchMergeTree() PARTITION BY timestamp ORDER BY (user_id, timestamp);
-写入和查询
INSERT INTO helloworld.my_first_table (user_id, message, timestamp) VALUES (101, 'Hello, ByConity!', now()), (102, 'Insert a lot of rows per batch', yesterday()), (102, 'Sort your data based on your commonly-used queries', today()), (101, 'Granules are the smallest chunks of data read', now() + 5); SELECT * FROM helloworld.my_first_table; SELECT * FROM helloworld.my_first_table ORDER BY timestamp; SELECT * FROM helloworld.my_first_table ORDER BY timestamp FORMAT JSON; exit;
-写入文件
假设我们有一个数据文件 data.csv
102,This is data in a file,2022-02-22 10:43:28 101,It is comma-separated,2022-02-23 00:00:00 103,Use FORMAT to specify the format,2022-02-21 10:43:30
./clickhouse-client -h {HOST} --port {PORT} --query='INSERT INTO helloworld.my_first_table FORMAT CSV' < data.csv
./clickhouse-client -h {HOST} --port {PORT} --query='SELECT * FROM helloworld.my_first_table'-查看计算组状态
SELECT * FROM system.worker_groups
Query id: f60481b4-b9a7-494d-a639-ac7be3aa5292
Row 1:
──────
id: wg_default
type: Physical
vw_uuid: 1a415df1-6265-40b3-9c00-230fc3b026c1
vw_name: vw_default
linked_id:
active_workers: 1
min_cpu_usage: 9
max_cpu_usage: 9
avg_cpu_usage: 9
min_mem_usage: 8
max_mem_usage: 8
avg_mem_usage: 8
is_auto_linked: 0
SELECT *
FROM system.workers
Query id: f2377b52-38eb-4437-9813-d34f9dd28049
Row 1:
──────
worker_id: w1
host: {HOST}
tcp_port: {TCP_PORT}
rpc_port: {RPC_PORT}
http_port: {HTTP_PORT}
exchange_port: {EXCHANGE_PORT}
exchange_status_port: {EXCHANGE_STATUS_PORT}
vw_name: vw_default
worker_group_id: wg_default
query_num: 0
cpu_usage: {xxx}
reserved_cpu_cores: 0
memory_usage: {xxx}
disk_space: {xxx}
memory_available: {xxx}
reserved_memory_bytes: 0
register_time: 2022-11-30 18:19:49
last_update_time: 2022-11-30 18:21:09
state: 1-查看历史查询
SELECT * FROM system.query_log;
3.基础使用手册
3.1 连接客户端
1) docker
docker run -it yandex/clickhouse-client --host 127.0.0.1 --port 9000 --user default --password xxxx
2) Clickhouse Client
curl -O 'https://builds.clickhouse.com/master/macos/clickhouse' \
&& chmod a+x ./clickhouse
mv ./clickhouse /usr/local/bin/
clickhouse client --host 127.0.0.1 --password xxxx
3.2 数据可视化
Grafana,Metabase,SuperSet 同连接开源 clickhouse 方法是一致的