如何在ClickHouse中使用DigitalOcean Spaces存储桶作为分层存储?

0 股票
0
0
0
0

介绍

ClickHouse 是一款开源的列式数据库管理系统,尤其擅长执行高性能 OLAP 查询和实时分析。然而,ClickHouse 的数据存储扩展可能面临挑战,尤其是在数据量增长的情况下。一种有效的解决方案是使用分层存储,它可以将不常用的数据迁移到更经济的存储位置,同时将常用数据保留在速度更快、成本更高的存储位置。ClickHouse 支持多种数据存储后端,包括本地磁盘和 DigitalOcean Spaces 等远程存储选项。在管理大量数据时,通常需要使用多个存储设备。.

DigitalOcean Spaces 是一种对象存储服务,可以作为一层集成到 ClickHouse 分层存储架构中。本指南将引导您完成将 DigitalOcean Spaces 配置为 ClickHouse 集群分层存储选项的步骤。.

在本指南中,我们将设置一个简单的 Go 应用程序,用于向 ClickHouse 发送批量日志。首先,日志将存储在热存储(默认磁盘,也称为本地磁盘)中,然后在指定的时间间隔(2 分钟)后,它们将被移动到冷存储(例如,基于 S3 的存储,如 DO Spaces)。.

先决条件

开始之前,请确保您已准备好以下物品:

  • DigitalOcean上的云账户。.
  • DigitalOcean Spaces 存储桶。.
  • DigitalOcean Spaces 的访问密钥。.
  • ClickHouse配置和对象存储的基本介绍。.

步骤 1 — 创建和配置 DigitalOcean 空间

登录您的 DigitalOcean 云账户并创建一个新的空间(存储桶)。此存储桶将用作不常用数据的分层存储。.

  • 前往控制面板的“空间”部分。.

  • 点击“创建新空间”,输入名称,选择区域,并设置权限。.

  • 记下端点 URL。.

  • 请记下访问密钥和秘密密钥,因为在后续步骤中需要用到它们。.

至此,您的存储桶已创建完成,可以与 ClickHouse 集成。.

步骤 2 — 在 Docker 容器中设置 ClickHouse 服务器

首先,创建一个文件夹并将其命名为“clickhouse”。.

mkdir clickhouse

在此文件夹中创建一个 Dockerfile,并将值 {YOUR_AWS_ACCESS_KEY_ID} 和 {YOUR_AWS_SECRET_ACCESS_KEY} 替换为您的访问密钥和秘密密钥。.

FROM clickhouse/clickhouse-server:latest
# Copy the config file to the container
COPY storage.xml /etc/clickhouse-server/config.d/storage.xml
# Copy the S3 table creation script
COPY create.sql /docker-entrypoint-initdb.d/
# Set environment variables for S3 credentials
ENV AWS_ACCESS_KEY_ID={YOUR_AWS_ACCESS_KEY_ID}
ENV AWS_SECRET_ACCESS_KEY={YOUR_AWS_SECRET_ACCESS_KEY}
# Expose ClickHouse HTTP and native ports
EXPOSE 8123 9000
USER clickhouse
# --config-file ./programs/server/config.xml
CMD ["clickhouse-server", "--config-file", "/etc/clickhouse-server/config.xml"]

描述:

  • access_key_id 和 secret_access_key:这些是您访问 DigitalOcean Spaces 的凭证。.

警告:为了简化本指南,我们已将凭据包含在 Dockerfile 中,但不建议在生产环境中采用这种方法。.

步骤 3 — 配置 ClickHouse 以兼容 S3 存储

在此步骤中,您将配置 ClickHouse,使其使用 DigitalOcean Spaces 作为存储系统中的一个层。这需要在 ClickHouse 安装目录下的 config.xml 文件中添加存储配置。.

要将 Spaces 存储桶用作存储磁盘,必须先在 ClickHouse 配置文件中声明它。您可以修改现有的 config.xml 文件,或者最好在 conf.d 文件夹中添加一个新文件,该文件稍后会合并到 config.xml 中。.

<clickhouse>
<storage_configuration>
<disks>
<s3>
<type>s3</type>
<endpoint>{YOUR_S3_SPACES_BUCKET_URL}</endpoint>
<use_environment_credentials>true</use_environment_credentials>
</s3>
</disks>
</storage_configuration>
</clickhouse>

本节配置远程磁盘(DigitalOcean Space),ClickHouse 可以使用该磁盘存储不常用的数据。.

注意:请将值 {YOUR_S3_SPACES_BUCKET_URL} 替换为您的端点 URL。.

步骤 4 — 创建具有分层存储的表

现在,在 ClickHouse 中创建一个使用分层存储的表。您可以指定多个存储策略,以确定哪些数据存储在本地磁盘上,哪些数据存储在远程磁盘(空间)上。.

制定数据保留策略,将较旧的数据在指定时间段后迁移到 DigitalOcean Spaces:

CREATE TABLE IF NOT EXISTS tiered_logs (
event_time DateTime,
level String,
message String
) ENGINE = MergeTree
ORDER BY (event_time)
TTL toDateTime(event_time) + INTERVAL 2 MINUTE TO VOLUME 'cold'
SETTINGS storage_policy = 's3_tiered';

描述:

  • 默认值:这是本地磁盘存储,用于存储最近或经常使用的数据。.
  • s3:是远程存储(DigitalOcean Spaces),较旧的数据会迁移到那里。.

此配置可确保新数据写入本地磁盘,而旧数据自动迁移到 DigitalOcean Spaces。.

步骤 5 — 运行 ClickHouse 服务器

要启动 ClickHouse 服务器,请运行以下命令:

docker build -t clickhouse-demo .
docker run -d --name clickhouse-demo -p 8123:8123 -p 9000:9000 clickhouse-demo

网络端口
  • 8123:这是用于通过 HTTP 接口与 ClickHouse 通信的 HTTP 端口(http://localhost:8123/play)。您可以使用此端口通过浏览器或命令行工具(例如 curl 或 Postman)运行 SQL 查询。它通常用于通过 HTTP 与 ClickHouse 交互的 Web 应用程序或客户端。.
  • 9000:此 TCP 端口是 ClickHouse 客户端和服务器使用 ClickHouse 主协议相互通信的主要端口。.
  • 参考资料:https://clickhouse.com/docs/en/guides/sre/network-ports

验证方式:

docker ps

步骤 6 — 运行一个简单的 Go 程序来发送日志

在一个新文件夹中,有一个名为 main.go 创建一个将日志发送到 ClickHouse 的程序。.

package main
import (
"database/sql"
"fmt"
"log"
"os"
"time"
"github.com/ClickHouse/clickhouse-go"
"github.com/sirupsen/logrus"
)
type ClickHouseHook struct {
db *sql.DB
entries []logrus.Entry
batchSize int
}
// NewClickHouseHook establishes a connection to ClickHouse using the provided DSN.
func NewClickHouseHook(dsn string, batchSize int) (*ClickHouseHook, error) {
db, err := sql.Open("clickhouse", dsn)
if err != nil {
return nil, err
}
if err := db.Ping(); err != nil {
if exception, ok := err.(*clickhouse.Exception); ok {
log.Fatalf("[%d] %s \n%s\n", exception.Code, exception.Message, exception.StackTrace)
} else {
log.Fatal(err)
}
}
return &ClickHouseHook{db: db, batchSize: batchSize}, nil
}
// Fire is triggered by Logrus to log entries to ClickHouse.
func (hook *ClickHouseHook) Fire(entry *logrus.Entry) error {
hook.entries = append(hook.entries, *entry)
if len(hook.entries) >= hook.batchSize {
if err := hook.flush(); err != nil {
return err
}
}
return nil
}
// flush sends the collected log entries to ClickHouse in a batch.
func (hook *ClickHouseHook) flush() error {
tx, err := hook.db.Begin()
if err != nil {
return err
}
stmt, err := tx.Prepare("INSERT INTO tiered_logs (event_time, level, message) VALUES (?, ?, ?)")
if err != nil {
return err
}
defer stmt.Close()
for _, entry := range hook.entries {
if _, err := stmt.Exec(entry.Time, entry.Level.String(), entry.Message); err != nil {
return err
}
}
if err := tx.Commit(); err != nil {
return err
}
// Clear the entries after flushing
hook.entries = nil
return nil
}
// Levels returns the logging levels for which the hook is triggered.
func (hook *ClickHouseHook) Levels() []logrus.Level {
return logrus.AllLevels
}
func main() {
// ClickHouse DSN (replace with your credentials and host)
dsn := "tcp://localhost:9000?database=default&username=default&password=&debug=true"
// Create ClickHouse hook with a batch size of 5
hook, err := NewClickHouseHook(dsn, 5)
if err != nil {
log.Fatalf("failed to connect to ClickHouse: %v", err)
}
defer hook.db.Close()
// Set up logrus
logger := logrus.New()
logger.Out = os.Stdout
logger.SetFormatter(&logrus.TextFormatter{
FullTimestamp: true,
})
logger.AddHook(hook)
// Log some entries
for i := 0; i < 10; i++ {
logger.WithFields(logrus.Fields{
"iteration": i,
}).Info("This is an info log entry")
time.Sleep(time.Second)
}
// Flush any remaining log entries before exiting
if err := hook.flush(); err != nil {
log.Fatalf("failed to flush logs to ClickHouse: %v", err)
}
fmt.Println("Logs sent to ClickHouse.")
}

安装软件包依赖项:

go mod init example.com/clickhouse-logging
go get github.com/ClickHouse/clickhouse-go
go get github.com/sirupsen/logrus

运行应用程序:

go run main.go

步骤 7 — 确认结果

要启动 ClickHouse 客户端,请运行以下命令:

docker exec -it clickhouse-demo clickhouse-client

要验证 ClickHouse 集群中的日志:

SELECT * FROM tiered_logs

检查此日志条目的存储磁盘时,我们发现它存储在默认(本地)磁盘上,也称为热存储。.

SELECT name, disk_name FROM system.parts WHERE table = 'tiered_logs';

在 CREATE TABLE 查询中指定的两分钟间隔之后,您可以检查这些报告是否已移动到 S3 磁盘(远程存储桶/空间)——也称为冷存储。.

我们还可以从 DigitalOcean 云平台的用户界面中看到,我们的存储桶现在包含数据:

结果

按照本指南操作,您已成功将 DigitalOcean Spaces 配置为 ClickHouse 的分层存储选项。此配置允许您将不常用的数据迁移到经济高效的对象存储,从而优化存储成本并提高性能,同时为活跃数据保持高性能存储。.

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

您可能也喜欢