[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驱动会处理与集群的通信,并将查询发送到正确的位置。

相关推荐
程序媛-徐师姐3 分钟前
Java 基于SpringBoot+vue框架的老年医疗保健网站
java·vue.js·spring boot·老年医疗保健·老年 医疗保健
yngsqq4 分钟前
c#使用高版本8.0步骤
java·前端·c#
流星白龙6 分钟前
【C++习题】10.反转字符串中的单词 lll
开发语言·c++
尘浮生13 分钟前
Java项目实战II基于微信小程序的校运会管理系统(开发文档+数据库+源码)
java·开发语言·数据库·微信小程序·小程序·maven·intellij-idea
MessiGo14 分钟前
Python 爬虫 (1)基础 | 基础操作
开发语言·python
小白不太白95018 分钟前
设计模式之 模板方法模式
java·设计模式·模板方法模式
Tech Synapse20 分钟前
Java根据前端返回的字段名进行查询数据的方法
java·开发语言·后端
xoxo-Rachel26 分钟前
(超级详细!!!)解决“com.mysql.jdbc.Driver is deprecated”警告:详解与优化
java·数据库·mysql
乌啼霜满天24928 分钟前
JDBC编程---Java
java·开发语言·sql