文章目錄
- 1 ELK替換
- 1.1 Elasticsearch vs ClickHouse
- 1.2 環境部署
- 1.2.1 zookeeper 集群部署
- 1.2.2 Kafka 集群部署
- 1.2.3 FileBeat 部署
- 1.2.4 clickhouse 部署
- 1.2.4.1 準備步驟
- 1.2.4.2 添加官方存儲庫
- 1.2.4.3 部署&啟動&連接
- 1.2.4.5 基本配置服務
- 1.2.4.6 測試創建數據庫和表
- 1.2.4.7 部署遇到問題
- 1.2.4.7.1 clikhouse 客戶端無法查詢 kafka 引擎表
- 1.2.4.7.2 clickhouse 創建本地節點表,無法開啟本地表 macro
- 1.2.4.7.3 clickhouse 中節點數據已經存在
- 1.2.4.7.4 分布式集群表無法查詢
- 1.2.4.8 clickhouse其他表
- 1.2.4.8.1 分布式表
- 1.2.4.8.2 物化視圖
1 ELK替換
點擊了解 日志之ELK使用講解
1.1 Elasticsearch vs ClickHouse
ClickHouse
是一款高性能列式分布式數據庫管理系統,對 ClickHouse
進行了測試,發現有下列優勢:
ClickHouse
寫入吞吐量大
單服務器日志寫入量在50MB
到200MB/s
,每秒寫入超過60w
記錄數,是 ES 的 5 倍以上。
在ES
中比較常見的寫Rejected
導致數據丟失、寫入延遲等問題,在ClickHouse
中不容易發生。- 查詢速度快
官方宣稱數據在pagecache
中,單服務器查詢速率大約在2-30GB/s
;沒在pagecache
的情況下,查詢速度取決于磁盤的讀取速率和數據的壓縮率。經測試ClickHouse
的查詢速度比 ES 快 5-30 倍以上。 - ClickHouse 比 ES 服務器成本更低
一方面ClickHouse
的數據壓縮比比 ES 高,相同數據占用的磁盤空間只有 ES 的 1/3 到 1/30,節省了磁盤空間的同時,也能有效的減少磁盤 IO,這也是ClickHouse查詢效率更高的原因之一。
另一方面ClickHouse
比ES
占用更少的內存,消耗更少的 CPU 資源。預估用 ClickHouse 處理日志可以將服務器成本降低一半。
支持功能\開源項目 | ElasticSearch | ClickHouse |
---|---|---|
查詢 | java | c++ |
存儲類型 | 文檔存儲 | 列式數據庫 |
分布式支持 | 分片和副本都支持 | 分片和副本都支持 |
擴展性 | 高 | 低 |
寫入速度 | 慢 | 快 |
CPU/內存占用 | 高 | 低 |
存儲占用(54G日志數據導入) | 高 94G(174%) | 低 23G(42.6%) |
精確匹配查詢速度 | 一般 | 快 |
模糊匹配查詢速度 | 快 | 慢 |
權限管理 | 支持 | 支持 |
查詢難度 | 低 | 高 |
可視化支持 | 高 | 低 |
使用案例 | 很多 | 攜程 |
維護難度 | 低 | 高 |
- 成本分析
在沒有任何折扣的情況下,基于 aliyun 分析
成本項 | 標準 | 費用 | 說明 | 總費用 |
---|---|---|---|---|
zookeeper 集群 | 2核4g 共享計算型 n4 50G SSD 云盤 | 222/月 | 3臺高可用 | 666/月 |
kafka 集群 | 4核 8g 共享標準型 s650G SSD 云盤300G 數據盤 | 590/月 | 3臺高可用 | 1770/月 |
filebeat 部署 | 混部相關的應用,會產生一定的內存以及磁盤開銷,對應用的可用性會造成一定的影響。 | |||
clickhouse | 16核32g 共享計算型 n450G SSD 云盤1000G 數據盤 | 2652/月 | 2臺高可用 | 5304/月 |
總費用 | 7740/月 |
1.2 環境部署
1.2.1 zookeeper 集群部署
點擊了解 zookeeper之Linux環境下的安裝
yum install java-1.8.0-openjdk-devel.x86_64
/etc/profile 配置環境變量
更新系統時間
yum install ntpdate
ntpdate asia.pool.ntp.orgmkdir zookeeper
mkdir ./zookeeper/data
mkdir ./zookeeper/logs
wget --no-check-certificate https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.7.1/apache-zookeeper-3.7.1-bin.tar.gz
tar -zvxf apache-zookeeper-3.7.1-bin.tar.gz -C /usr/zookeeperexport ZOOKEEPER_HOME=/usr/zookeeper/apache-zookeeper-3.7.1-bin
export PATH=$ZOOKEEPER_HOME/bin:$PATH進入ZooKeeper配置目錄
cd$ZOOKEEPER_HOME/conf新建配置文件
vi zoo.cfgtickTime=2000
initLimit=10
syncLimit=5
dataDir=/usr/zookeeper/data
dataLogDir=/usr/zookeeper/logs
clientPort=2181
server.1=zk1:2888:3888
server.2=zk2:2888:3888
server.3=zk3:2888:3888在每臺服務器上執行,給zookeeper創建myid
echo"1" > /usr/zookeeper/data/myid
echo"2" > /usr/zookeeper/data/myid
echo"3" > /usr/zookeeper/data/myid進入ZooKeeper bin目錄
cd$ZOOKEEPER_HOME/bin
sh zkServer.sh start
1.2.2 Kafka 集群部署
點擊了解 Kafka安裝以及驗證
mkdir -p /usr/kafka
chmod 777 -R /usr/kafka
wget --no-check-certificate https://mirrors.tuna.tsinghua.edu.cn/apache/kafka/3.2.0/kafka_2.12-3.2.0.tgz
tar -zvxf kafka_2.12-3.2.0.tgz -C /usr/kafka不同的broker Id 設置不一樣,比如 1,2,3
broker.id=1
listeners=PLAINTEXT://ip:9092
socket.send.buffer.bytes=102400
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600
log.dir=/usr/kafka/logs
num.partitions=5
num.recovery.threads.per.data.dir=3
offsets.topic.replication.factor=2
transaction.state.log.replication.factor=3
transaction.state.log.min.isr=3
log.retention.hours=168
log.segment.bytes=1073741824
log.retention.check.interval.ms=300000
zookeeper.connect=zk1:2181,zk2:2181,zk3:2181
zookeeper.connection.timeout.ms=30000
group.initial.rebalance.delay.ms=0后臺常駐進程啟動kafka
nohup /usr/kafka/kafka_2.12-3.2.0/bin/kafka-server-start.sh /usr/kafka/kafka_2.12-3.2.0/config/server.properties >/usr/kafka/logs/kafka.log >&1 &/usr/kafka/kafka_2.12-3.2.0/bin/kafka-server-stop.sh$KAFKA_HOME/bin/kafka-topics.sh --list --bootstrap-server ip:9092$KAFKA_HOME/bin/kafka-console-consumer.sh --bootstrap-server ip:9092 --topic test --from-beginning$KAFKA_HOME/bin/kafka-topics.sh --create --bootstrap-server ip:9092 --replication-factor 2 --partitions 3 --topic xxx_data
1.2.3 FileBeat 部署
sudo rpm --import https://packages.elastic.co/GPG-KEY-elasticsearch
Create a file with a .repo extension (for example, elastic.repo) in your /etc/yum.repos.d/ directory and add the following lines:
在/etc/yum.repos.d/ 目錄下創建elastic.repo[elastic-8.x]
name=Elastic repository for 8.x packages
baseurl=https://artifacts.elastic.co/packages/8.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-mdyum install filebeat
systemctl enable filebeat
chkconfig --add filebeat
FileBeat 配置文件說明,坑點 1(需設置 keys_under_root: true)。如果不設置kafka 的消息字段如下:
文件目錄:/etc/filebeat/filebeat.yml
filebeat.inputs:
- type: logenabled: truepaths:- /root/logs/xxx/inner/*.logjson:
如果不設置該索性,所有的數據都存儲在message里面,這樣設置以后數據會平鋪。keys_under_root: true
output.kafka:hosts: ["kafka1:9092", "kafka2:9092", "kafka3:9092"]topic: 'xxx_data_clickhouse'partition.round_robin:reachable_only: falserequired_acks: 1compression: gzip
processors:
剔除filebeat 無效的字段數據- drop_fields: fields: ["input", "agent", "ecs", "log", "metadata", "timestamp"]ignore_missing: falsenohup ./filebeat -e -c /etc/filebeat/filebeat.yml > /user/filebeat/filebeat.log &
輸出到filebeat.log文件中,方便排查
1.2.4 clickhouse 部署
1.2.4.1 準備步驟
ClickHouse 官方 RPM 包通常針對 x86_64 架構編譯,并依賴 SSE 4.2 指令集,檢查當前CPU是否支持SSE 4.2,如果不支持,需要通過源代碼編譯構建
grep -q sse4_2 /proc/cpuinfo && echo"SSE 4.2 supported" || echo"SSE 4.2 not supported"
返回 "SSE 4.2 supported" 表示支持,返回 "SSE 4.2 not supported" 表示不支持
創建數據保存目錄,將它創建到大容量磁盤掛載的路徑
mkdir -p /data/clickhouse
修改/etc/hosts文件,添加clickhouse節點
舉例:
10.190.85.92 bigdata-clickhouse-01
10.190.85.93 bigdata-clickhouse-02
服務器性能參數設置
- cpu頻率調節,將CPU頻率固定工作在其支持的最高運行頻率上,而不動態調節,性能最好
echo'performance' | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
- 內存調節,不要禁用
overcommit
echo 0 | tee /proc/sys/vm/overcommit_memory
- 始終禁用透明大頁(
transparent huge pages
),它會干擾內存分配器,從而導致顯著的性能下降
echo 'never' | tee /sys/kernel/mm/transparent_hugepage/enabled
1.2.4.2 添加官方存儲庫
# 安裝 yum-utils(用于管理 YUM 倉庫)
yum install yum-utils # 導入 ClickHouse 的 GPG 密鑰(用于驗證包的真實性)
rpm --import https://repo.clickhouse.com/CLICKHOUSE-KEY.GPG#運行命令后,可以檢查是否成功導入密鑰
# 如果成功導入,你會看到類似 gpg-pubkey-... --> GPG key for ClickHouse 的輸出
rpm -q gpg-pubkey --qf '%{name}-%{version}-%{release} --> %{summary}\n'# 添加 ClickHouse 倉庫
yum-config-manager --add-repo https://repo.clickhouse.com/rpm/stable/x86_64
1.2.4.3 部署&啟動&連接
部署服務,ClickHouse
提供兩個主要包:clickhouse-server
(服務端)和 clickhouse-client
(客戶端)
# 查看clickhouse可安裝的版本
yum list | grep clickhouse# 安裝 ClickHouse 服務端和客戶端
yum -y install clickhouse-server clickhouse-client
# 如果要指定版本
# yum install -y clickhouse-server-23.4.2.1 clickhouse-client-23.4.2.1# 檢查 ClickHouse 版本以確認安裝成功:
clickhouse-client --version
輸出示例:
ClickHouse client version 24.3.2.1 (official build).
啟動服務,ClickHouse
安裝后會創建一個 systemd
服務,名為 clickhouse-server
。
# 啟動服務
systemctl start clickhouse-server#設置開機自啟:
systemctl enable clickhouse-server#檢查服務狀態:
systemctl status clickhouse-server#檢查服務日志:
cat /var/log/clickhouse-server/clickhouse-server.log
常見問題可能是權限或配置錯誤
連接服務,使用 clickhouse-client
連接到服務端,測試是否正常工作
#本地連接
clickhouse-client
默認連接 localhost:9000,用戶為 default,無密碼。#如果設置了密碼,可以用:
clickhouse-client --password運行簡單查詢
在客戶端提示符下運行:
SELECT 1;
1.2.4.5 基本配置服務
ClickHouse
的配置文件默認位于 /etc/clickhouse-server/
,主要文件為 config.xml
和 users.xml
修改監聽地址(允許遠程訪問): 默認只監聽本地(127.0.0.1)。若需遠程訪問,編輯 /etc/clickhouse-server/config.xml
vi /etc/clickhouse-server/config.xml找到 <listen_host>,修改為:<listen_host>0.0.0.0</listen_host>
0.0.0.0 表示監聽所有網絡接口。
設置默認用戶密碼: 編輯 /etc/clickhouse-server/users.xml
vi /etc/clickhouse-server/users.xml
找到 <default> 用戶的配置,添加或修改密碼:<password>your_password</password>或者使用 SHA256 哈希密碼:echo -n "your_password" | sha256sum
將哈希值填入:<password_sha256_hex>your_hashed_password</password_sha256_hex>#重啟服務以應用配置:
systemctl restart clickhouse-server
修改日志級別為information
,默認是trace
,修改/etc/clickhouse-server/config.xml
配置文件
<level>information</level>
執行日志所在目錄:
- 正常日志:
/var/log/clickhouse-server/clickhouse-server.log
- 異常錯誤日志:
/var/log/clickhouse-server/clickhouse-server.err.log
1.2.4.6 測試創建數據庫和表
進入客戶端:clickhouse-client
-- 創建數據庫:
CREATE DATABASE test;
-- 使用數據庫:
USE test;
-- 創建表:
CREATE TABLE visits (id UInt64,duration Float64,url String,created DateTime
) ENGINE = MergeTree()
PRIMARY KEY id
ORDER BY id;-- 插入數據:
INSERT INTO visits (id, duration, url, created) VALUES (1, 10.5, 'example.com', now());-- 查詢數據:
SELECT * FROM visits;
1.2.4.7 部署遇到問題
clickhouse
部署過程中遇到的一些問題如下:
1.2.4.7.1 clikhouse 客戶端無法查詢 kafka 引擎表
Kafka 引擎的特性:
ClickHouse
的Kafka 引擎表
是一種流式引擎(stream-like engine)
,設計目的是從Kafka
消費數據,并將其傳遞給其他表(通常是物化視圖
或普通表
)進行存儲和處理。- 默認情況下,
ClickHouse
禁止直接查詢Kafka 引擎表
(SELECT
操作),因為:Kafka 引擎表
本質上是一個數據流
,每次查詢都會觸發從Kafka
消費數據的操作,可能導致重復消費或不一致的結果。Kafka
引擎表不存儲數據,數據僅在Kafka
中,查詢可能會消耗大量資源(例如從 Kafka 的最早偏移量開始讀取)。
ClickHouse
引入了安全限制,防止用戶意外執行可能導致性能問題或數據不一致的查詢
CREATE TABLE default.kafka_clickhouse_inner_log ON CLUSTER clickhouse_cluster (log_uuid String ,date_partition UInt32 ,event_name String ,activity_name String ,activity_type String ,activity_id UInt16
) ENGINE = Kafka SETTINGSkafka_broker_list = 'kafka1:9092,kafka2:9092,kafka3:9092',kafka_topic_list = 'data_clickhouse',kafka_group_name = 'clickhouse_xxx',kafka_format = 'JSONEachRow',kafka_row_delimiter = '\n',kafka_num_consumers = 1;
ON CLUSTER clickhouse_cluster
是 ClickHouse
的 DDL 語法,用于在集群的所有節點上同步執行 DDL 語句。
解決方案:
需要在clickhouse client
創建加上 --stream_like_engine_allow_direct_select 1
1.2.4.7.2 clickhouse 創建本地節點表,無法開啟本地表 macro
Code: 62. DB::Exception: There was an error on [127.0.0.1:9000]: Code: 62. DB::Exception: No macro 'shard' in config while processing substitutions in '/clickhouse/tables/default/bi_inner_log_local/{shard}' at '50' or macro is not supported here. (SYNTAX_ERROR) (version 22.5.2.53 (official build)). (SYNTAX_ERROR) (version 22.5.2.53 (official build))
創建本地表(使用復制去重表引擎)
create table default.bi_inner_log_local ON CLUSTER clickhouse_cluster (log_uuid String ,date_partition UInt32 ,event_name String ,activity_name String ,credits_bring Int16 ,activity_type String ,activity_id UInt16
) ENGINE = ReplicatedReplacingMergeTree('/clickhouse/tables/default/bi_inner_log_local/{shard}','{replica}')PARTITION BY date_partitionORDER BY (event_name,date_partition,log_uuid)SETTINGS index_granularity = 8192;
解決方案:在不同的 clickhouse
節點上配置不同的 shard
,每一個節點的 shard
名稱不能一致。
<macros><shard>01</shard><replica>example01-01-1</replica>
</macros>
1.2.4.7.3 clickhouse 中節點數據已經存在
報錯:
Code: 253. DB::Exception: There was an error on : Code: 253. DB::Exception: Replica /clickhouse/tables/default/bi_inner_log_local/01/replicas/example01-01-1 already exists. (REPLICA_IS_ALREADY_EXIST) (version 22.5.2.53 (official build)). (REPLICA_IS_ALREADY_EXIST) (version 22.5.2.53 (official build))
解決方案:進入 zookeeper
客戶端刪除相關節點,然后再重新創建 ReplicatedReplacingMergeTree
表。這樣可以保障每一個 clickhouse
節點都會去消費 kafka partition
的數據。
1.2.4.7.4 分布式集群表無法查詢
報錯:
Code: 516. DB::Exception: Received from 127.0.0.1:9000. DB::Exception: default: Authentication failed: password is incorrect or there is no user with such name. (AUTHENTICATION_FAILED) (version 22.5.2.53 (official build))
解決方案:
<!--分布式表配置-->
<remote_servers><clickhouse_cluster><!--集群名稱, 可以自定義, 后面在新建庫、表的時候需要用到集群名稱--><shard><!--內部復制(默認false), 開啟后, 在分布式表引擎下, 數據寫入時--><!--每個分片只會去尋找一個節點寫, 并不是每個都寫--><internal_replication>true</internal_replication><replica><host>ip1</host><port>9000</port><user>default</user><password>xxxx</password></replica></shard><shard><internal_replication>true</internal_replication><replica><host>ip2</host><port>9000</port><user>default</user><password>xxxx</password></replica></shard></clickhouse_cluster>
</remote_servers>
1.2.4.8 clickhouse其他表
1.2.4.8.1 分布式表
創建分布式表(根據 log_uuid 對數據進行分發,相同的 log_uuid 會發送到同一個 shard 分片上,用于后續合并時的數據去重):
CREATE TABLE default.bi_inner_log_all ON CLUSTER clickhouse_cluster
AS default.bi_inner_log_local
ENGINE = Distributed(clickhouse_cluster, default, bi_inner_log_local, xxHash32(log_uuid));
AS default.bi_inner_log_local
:表示新表 default.bi_inner_log_all
的表結構(列定義)與已有表 default.bi_inner_log_local
相同。復制 default.bi_inner_log_local 的列定義(列名、類型等),但不復制數據。
ENGINE = Distributed(clickhouse_cluster, default, bi_inner_log_local, xxHash32(log_uuid))
:指定表的引擎為 Distributed
,表示這是一個分布式表
。
Distributed
引擎的參數:
clickhouse_cluster
:集群名稱,指定查詢分發的目標集群(與 ON CLUSTER 的集群名一致)。default
:本地表的數據庫名,表示目標本地表位于 default 數據庫。bi_inner_log_local
:本地表名,表示分布式表會將查詢分發到名為 bi_inner_log_local 的本地表。xxHash32(log_uuid)
:分片鍵(sharding key
),用于決定數據分發到哪個分片。
xxHash32
是一個哈希函數,對 log_uuid 列計算哈希值。
ClickHouse
根據哈希值將數據或查詢分發到不同的分片,確保負載均衡。
Distributed
引擎的作用
- 不存儲數據:
分布式表(default.bi_inner_log_all
)本身不存儲數據,僅作為一個邏輯層。
它將查詢分發到集群中所有節點的本地表(default.bi_inner_log_local
),并匯總結果。 - 查詢分發:
當查詢分布式表時,例如:SELECT * FROM default.bi_inner_log_all WHERE date_partition = 20230101;
ClickHouse 會將查詢分發到集群中所有節點的default.bi_inner_log_local
表。
每個節點獨立執行查詢,返回結果。
當前節點(發起查詢的節點)匯總所有節點的結果,返回給客戶端。 - 數據寫入:
如果向分布式表插入數據,例如:INSERT INTO default.bi_inner_log_all VALUES (...);
ClickHouse
會根據分片鍵(xxHash32(log_uuid)
)計算哈希值,將數據分發到對應的分片(節點)的default.bi_inner_log_local
表。 - 分片鍵 xxHash32(log_uuid)
分片鍵決定數據如何分發到集群中的分片。
xxHash32(log_uuid) 對 log_uuid 列計算 32 位哈希值,ClickHouse 根據哈希值決定數據存儲在哪個分片。
1.2.4.8.2 物化視圖
創建物化視圖,把 Kafka
消費表消費的數據同步到 ClickHouse
分布式表。
CREATE MATERIALIZED VIEW default.view_bi_inner_log ON CLUSTER clickhouse_cluster TO default.bi_inner_log_all AS
SELECT log_uuid ,
date_partition ,
event_name ,
activity_name ,
credits_bring ,
activity_type ,
activity_id
FROM default.kafka_clickhouse_inner_log;
TO default.bi_inner_log_all
:
TO
是物化視圖的語法,用于指定目標表(target table
)。default.bi_inner_log_all
是目標表的名稱,表示物化視圖會將查詢結果插入到 default 數據庫中的 bi_inner_log_all 表。
作用:- 物化視圖會自動監聽源表(default.kafka_clickhouse_inner_log)的新數據。
- 每次有新數據插入到源表時,物化視圖會執行 SELECT 查詢,并將結果插入到目標表 default.bi_inner_log_all
AS:
- AS 是物化視圖語法的固定部分,用于引入物化視圖的 SELECT 查詢。
- 它表示:物化視圖的邏輯是基于后面的 SELECT 語句定義的。