[SQL系列]从零开始学Clickhouse——集群篇

在上一篇中,我们通过Docker构建了一个简单的单点Clickhouse,但是如果要做大数据的处理的话,Clickhouse集群是必不可少的,今天我们先用Docker简单地搭建一个Clickhouse集群。

容器逐个部署

使用Docker部署ClickHouse集群涉及几个步骤,包括创建Docker网络、配置ClickHouse容器以及设置集群的各个节点。

1. 创建Docker网络

首先,需要创建一个Docker网络,以确保ClickHouse容器可以相互通信。

docker network create --subnet=172.18.0.0/16 clickhouse_network

如果遇到了这个问题"Error response from daemon: Pool overlaps with other one on this address space",那说明docker已经建立了对应的子网,占据了地址,我们可以改一下,比如说--subnet=172.16.0.0/16,如果此处冲突了。下一步的docker run指定的ip也需要修改。

2. 启动ClickHouse服务器

接着,启动ClickHouse服务器实例。假设我们要部署一个具有三个节点的集群。

对于每个节点,运行一个ClickHouse容器,并加入之前创建的网络:

docker run -d --name clickhouse-server-1 \
  --ip 172.18.0.2 \
  --network clickhouse_network \
  -p 8123:8123 \
  -p 9000:9000 \
  -v /path/to/configs:/var/lib/clickhouse \
  yandex/clickhouse-server

docker run -d --name clickhouse-server-2 \
  --ip 172.18.0.3 \
  --network clickhouse_network \
  yandex/clickhouse-server

docker run -d --name clickhouse-server-3 \
  --ip 172.18.0.4 \
  --network clickhouse_network \
  yandex/clickhouse-server

这里-p 8123:8123-p 9000:9000表示将容器的端口映射到宿主机,这样可以通过宿主机的端口访问ClickHouse服务。-v参数用于将宿主机的配置文件目录挂载到容器中,以自定义配置。

上面的格式是在bash下的格式,如果在Powershell,需要把斜杠去掉。 上面的容器是yandex/clickhouse-server,也可以修改成clickhouse/clickhouse-server,这个容器上一篇文章中下载过了。

3. 配置ClickHouse集群

每个ClickHouse节点都需要在其配置文件config.xml中设置集群配置。你需要编辑每个节点的config.xml文件,添加集群配置信息。

docker exec -it clickhouse-server-1 bash
cd /etc/clickhouse-server

//下载vim
apt-get update
apt-get install vim

vim config.xml
//按照下面的内容修改,修改完后
//先按Esc,:wq回车就保存好了

以下是示例配置:

<clickhouse>
  <!-- Other configurations... -->
  <remote_servers>
    <cluster_1>
      <shard>
        <internal_replication>true</internal_replication>
        <replica>
          <host>clickhouse-server-1</host>
          <port>9000</port>
        </replica>
      </shard>
      <shard>
        <internal_replication>true</internal_replication>
        <replica>
          <host>clickhouse-server-2</host>
          <port>9000</port>
        </replica>
      </shard>
      <shard>
        <internal_replication>true</internal_replication>
        <replica>
          <host>clickhouse-server-3</host>
          <port>9000</port>
        </replica>
      </shard>
    </cluster_1>
  </remote_servers>
  <!-- Other configurations... -->
</clickhouse>

确保<host>标签中的值与Docker容器名称一致。

修改结束之后,可以用exit退出当前容器,也可以ctrl+p+q退出

4. 重启ClickHouse服务器

配置完成后,需要重启所有ClickHouse服务器以使配置生效。

docker restart clickhouse-server-1 clickhouse-server-2 clickhouse-server-3

5. 验证集群

使用ClickHouse客户端连接到任意一个节点,并运行以下命令来验证集群是否配置正确:

docker exec -it clickhouse-server-1 clickhouse-client --query "SELECT * FROM system.clusters"

这个查询应该返回你配置的集群信息。

6. 删除集群

docker stop clickhouse-server-1 clickhouse-server-2 clickhouse-server-3

docker rm clickhouse-server-1 clickhouse-server-2 clickhouse-server-3

docker network rm clickhouse_network

使用Docker-compose部署

1. 编写yaml文件

使用docker-compose来搭建ClickHouse集群会更加简单和方便,因为docker-compose允许你在一个YAML文件中定义所有的服务,并且管理它们的生命周期。

version: '3'

services:
  clickhouse-server-1:
    image: yandex/clickhouse-server
    container_name: clickhouse-server-1
    networks:
      - clickhouse_network
    ports:
      - "8123:8123"
      - "9000:9000"
    volumes:
      - /path/to/configs-1:/var/lib/clickhouse

  clickhouse-server-2:
    image: yandex/clickhouse-server
    container_name: clickhouse-server-2
    networks:
      - clickhouse_network
    volumes:
      - /path/to/configs-2:/var/lib/clickhouse

  clickhouse-server-3:
    image: yandex/clickhouse-server
    container_name: clickhouse-server-3
    networks:
      - clickhouse_network
    volumes:
      - /path/to/configs-3:/var/lib/clickhouse

networks:
  clickhouse_network:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.18.0.0/16

上面的volumns可以不带,如果不想挂载主机路径的话,上面的network里面的subnet地址也可以因为冲突修改掉。

在这个配置文件中,我们定义了三个ClickHouse服务(clickhouse-server-1clickhouse-server-2clickhouse-server-3),它们都使用yandex/clickhouse-server镜像。每个服务都挂载了一个卷,用于存储配置文件和数据。此外,我们创建了一个名为clickhouse_network的网络,用于服务之间的通信。

2. 修改配置文件

与直接使用Docker容器一样,你需要为每个ClickHouse节点配置集群设置。编辑每个节点的config.xml文件,添加集群配置信息。由于我们使用了卷挂载,你可以在宿主机的相应路径下编辑这些配置文件。

如果没有使用-v进行挂载的话,还是得进入到每个容器里面进行修改。

3. 启动集群

配置完成后,使用以下命令启动集群:

docker-compose up -d

这将根据docker-compose.yml文件定义启动所有服务。

4. 验证集群

使用ClickHouse客户端连接到任意一个节点,并运行以下命令来验证集群是否配置正确:

docker-compose exec clickhouse-server-1 clickhouse-client --query "SELECT * FROM system.clusters"

这个查询应该返回你配置的集群信息。

5. 删除集群

docker-compose down -v --rmi all

Go使用Clickhouse

Go 复制代码
package main

import (
	"database/sql"
	"fmt"
	"log"

	_ "github.com/ClickHouse/clickhouse-go"
)

func main() {
	// 连接到ClickHouse单点
	connectToSingleNode()
	// 连接到ClickHouse集群
	connectToCluster()
}

func connectToSingleNode() {
	conn, err := sql.Open("clickhouse", "tcp://localhost:9000?debug=true")
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	var version string
	if err := conn.QueryRow("SELECT version()").Scan(&version); err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Single Node Version: %s\n", version)
}

func connectToCluster() {
	conn, err := sql.Open("clickhouse", "tcp://localhost:9000,tcp://localhost:9001,tcp://localhost:9002?debug=true")
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	var version string
	if err := conn.QueryRow("SELECT version()").Scan(&version); err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Cluster Version: %s\n", version)
}

上述分别定义了连接单点和连接集群的方法,主要是在连接地址的不同,其余的对于开发者而言都是透明的,包括切片的选取和副本。

  • connectToSingleNode函数连接到单个ClickHouse实例,它使用tcp://localhost:9000作为连接字符串。
  • connectToCluster函数连接到ClickHouse集群,它使用tcp://localhost:9000,tcp://localhost:9001,tcp://localhost:9002作为连接字符串,这样就可以连接到多个分片。

在ClickHouse中,当你连接到集群时,通常不需要手动选择分片。ClickHouse的查询处理器会自动处理分布式查询,根据查询语句和集群配置将查询分发到适当的分片上。你只需要连接到集群中的任何一个节点,ClickHouse就会负责将查询分发到所有相关的分片上,并合并结果。

然而,如果你想要手动控制查询在哪些分片上执行,你可以在查询中使用ON CLUSTER子句来指定集群的名称,以及使用SHARDREPLICA子句来指定特定的分片和副本。例如:

SELECT * FROM my_table ON CLUSTER my_cluster WHERE shard = 1

这个查询只会在集群my_cluster中编号为1的分片上执行。

在Go程序中,你仍然使用相同的连接字符串来连接到集群,无论你是在所有分片上执行查询还是在特定的分片上执行查询。ClickHouse的Go驱动会处理与集群的通信,并将查询发送到正确的位置。

相关推荐
2401_857439692 小时前
SSM 架构下 Vue 电脑测评系统:为电脑性能评估赋能
开发语言·php
SoraLuna3 小时前
「Mac畅玩鸿蒙与硬件47」UI互动应用篇24 - 虚拟音乐控制台
开发语言·macos·ui·华为·harmonyos
xlsw_3 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
神仙别闹4 小时前
基于java的改良版超级玛丽小游戏
java
Dream_Snowar4 小时前
速通Python 第三节
开发语言·python
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭4 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫4 小时前
泛型(2)
java
超爱吃士力架4 小时前
邀请逻辑
java·linux·后端
南宫生4 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石4 小时前
12/21java基础
java