clickhouse聚合查询:分布式表

 

需求:clickhouse可以做聚合查询吗?也就是说有2个clickhouse,都有一个数据库是logs_saas的logs表,我通过superset查询时logs_saas数据库的logs表时能把在第一个和第二个clickhouse的查询结果合并在一起在页面展示,这2个clickhouse的logs_saas数据库的logs表结构是一样的,但数据是不一样的。

 

方案一:使用分布式表(Distributed Table)

架构原理

Superset -> ClickHouse1(分布式表)-> [ClickHouse1本地表 + ClickHouse2本地表]

具体实现步骤

步骤1:确保两个ClickHouse都能相互访问

在两个ClickHouse服务器的配置文件中(/etc/clickhouse-server/config.xml):

<!-- 允许跨服务器查询 -->
<listen_host>0.0.0.0</listen_host>

重启ClickHouse服务:

sudo systemctl restart clickhouse-server

步骤2:在ClickHouse1上创建集群配置

创建配置文件 /etc/clickhouse-server/config.d/clusters.xml

<yandex>
    <remote_servers>
        <two_nodes_cluster>  <!-- 集群名称 -->
            <shard>
                <!-- 第一个分片:ClickHouse1 -->
                <replica>
                    <host>192.168.1.100</host>  <!-- ClickHouse1的IP -->
                    <port>9000</port>
                    <user>default</user>
                    <password></password>
                </replica>
            </shard>
            <shard>
                <!-- 第二个分片:ClickHouse2 -->
                <replica>
                    <host>192.168.1.101</host>  <!-- ClickHouse2的IP -->
                    <port>9000</port>
                    <user>default</user>
                    <password></password>
                </replica>
            </shard>
        </two_nodes_cluster>
    </remote_servers>
</yandex>

重启ClickHouse1:

sudo systemctl restart clickhouse-server

 

步骤3:在两个ClickHouse上确保表结构一致

分别在两个ClickHouse上创建相同的表结构:

-- 在 ClickHouse1 和 ClickHouse2 上都执行
CREATE DATABASE IF NOT EXISTS logs_saas;

CREATE TABLE IF NOT EXISTS logs_saas.logs_local
(
    id UInt64,
    timestamp DateTime,
    user_id String,
    event_type String,
    event_data String,
    date Date DEFAULT toDate(timestamp)
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(date)
ORDER BY (date, timestamp, user_id)
SETTINGS index_granularity = 8192;

步骤4:在ClickHouse1上创建分布式表

sql
-- 只在ClickHouse1上执行
CREATE TABLE logs_saas.logs_all
(
    id UInt64,
    timestamp DateTime,
    user_id String,
    event_type String,
    event_data String,
    date Date
)
ENGINE = Distributed(
    'two_nodes_cluster',  -- 集群名称(与配置一致)
    'logs_saas',          -- 数据库名
    'logs_local',         -- 本地表名
    rand()               -- 分片键(随机分布)
);

步骤5:在Superset中配置

只需要连接ClickHouse1,然后查询分布式表:

sql
-- 在Superset中查询,会自动查询两个节点
SELECT 
    toDate(timestamp) as day,
    count() as total_events,
    uniq(user_id) as daily_users
FROM logs_saas.logs_all
WHERE date >= '2024-01-01'
GROUP BY day
ORDER BY day DESC;

验证分布式查询是否工作

-- 在ClickHouse1上执行,查看查询分发情况
EXPLAIN PLAN
SELECT count() FROM logs_saas.logs_all;

-- 查看每个节点的数据分布
SELECT 
    _shard_num,  -- 分片编号
    count() as row_count
FROM logs_saas.logs_all
GROUP BY _shard_num;



posted @ 2025-12-25 11:44  苦逼yw  阅读(4)  评论(0)    收藏  举报