Kafka Remote WAL 文档 - User Guide
Write-Ahead Logging(WAL)是 GreptimeDB 中的一个重要组件。每一个数据修改的操作,都会作为一个日志存储在 WAL 中,以确保数据库不会丢失缓存在内存中的数据。
在 0.5 版本之前,我们使用嵌入式的 Raft Engine 作为 WAL 的存储引擎。虽然在实际部署时我们可以将 Raft Engine 挂载到云存储上,使得 RPO 为 0,但是由于重新挂载需要时间,导致 RTO 较大。另一方面,嵌入式的 Raft Engine 也无法满足多用户订阅日志的需求,这使得 GreptimeDB 无法实现热备、region 迁移等特性。
随着 0.5 版本的发布,我们开始使用远程存储服务作为 WAL 的存储引擎,我们称这样的 WAL 为 Remote WAL。 Apache Kafka 被广泛用于流处理领域,它自身的分布式容灾能力,以及基于 Topic 的订阅机制,能够很好地满足 GreptimeDB 现阶段对 Remote WAL 的需求,因此我们在 0.5 版本中增加 Apache Kafka 作为 WAL 的可选存储引擎。
如何使用 Kafka Remote WAL
Step 1: 启动 Kafka 集群
如果您已经部署了 Kafka 集群,您可以跳过此步骤。但请您留意部署时设定的 advertised listeners,您将在 Step 2 使用它。
我们推荐使用 docker compose 启动 Kafka 集群。Kafka 支持 KRaft 和 Zookeeper 两种部署模式,您可以在这里和这里分别找到 KRaft 和 Zookeeper 两种模式的 docker compose 脚本。我们建议使用 KRaft 模式部署,正如我们使用的 docker-compose-standalone.yml 脚本。为了您的方便,我们将该脚本的内容放在下方。
version: '3.8'
services:
kafka:
image: bitnami/kafka:3.6.0
container_name: kafka
ports:
- 9092:9092
environment:
# KRaft settings
KAFKA_KRAFT_CLUSTER_ID: Kmp-xkTnSf-WWXhWmiorDg
KAFKA_ENABLE_KRAFT: "yes"
KAFKA_CFG_NODE_ID: "1"
KAFKA_CFG_PROCESS_ROLES: broker,controller
KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: 1@127.0.0.1:2181
# Listeners
KAFKA_CFG_ADVERTISED_LISTENERS: PLAINTEXT://127.0.0.1:9092
KAFKA_CFG_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
KAFKA_CFG_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:2181
ALLOW_PLAINTEXT_LISTENER: "yes"
KAFKA_BROKER_ID: "1"
如需要以其他方式启动 Kafka 集群,您可以参考 Kafka 官方文档。
假设您已经启动了 Docker,并且正确设置了 docker compose 脚本的路径,您可以在终端中执行如下命令,启动一个包含单个 broker 的 Kafka 集群。
docker compose -f docker-compose-standalone.yml up
如果一切正常,您将看到包含如下内容的输出(日志时间戳将会不同):
...
kafka | [2024-01-11 07:06:55,518] INFO KafkaConfig values:
kafka | advertised.listeners = PLAINTEXT://127.0.0.1:9092
...
kafka | [2024-01-11 07:06:55,554] INFO [KafkaRaftServer nodeId=1] Kafka Server started (kafka.server.KafkaRaftServer)
Step 2: 配置 GreptimeDB
目前,GreptimeDB 默认使用 Raft Engine 作为 WAL 的存储引擎。当 使用 Kafka Remote WAL 时,您需要通过配置文件手动指定 Kafka 为 WAL 的存储引擎。
Standalone 模式
我们将一些需要您特别关注的 Kafka Remote WAL 的配置项摘录如下。关于完整的配置项,您可以查看这里。
[wal]
provider = "kafka"
broker_endpoints = ["127.0.0.1:9092"]
replication_factor = 1
max_batch_size = "1MB"
各个配置项的含义为:
provider
: 指定 WAL 存储引擎。应设置为"kafka"
,以指定使用 Kafka Remote WAL。broker_endpoints
: 指定 Kafka 集群所有 brokers 的 advertised listeners。您需要根据 docker compose 脚本中指定的KAFKA_CFG_ADVERTISED_LISTENERS
来配置该项。如您通过其他方式部署 Kafka 集群,您需要根据您在部署时设置的 advertised listeners 来配置该项。如未明确配置,则默认为["127.0.0.1:9092"]
。replication_factor
: 每个 partition 的数据会复制到指定数量的 brokers 上。该配置项的值必须大于 0,且不大于 brokers 的数量。max_batch_size
: 我们会限制一批次传输的 log batch 的总大小不超过该配置项所设定的值。需要注意的是,Kafka 默认会拒绝超过 1MB 的 log,所以我们建议您将该配置项设定为不超过 1MB。如您确实需要调大该配置项,您可以参考这里以了解如何配置 Kafka。
Distributed 模式
对于分布式模式,Kafka Remote WAL 的配置项分布在 metasrv 和 datanode 的配置文件中。与单机模式相比,配置项的名称、含义、默认值均保持一 致。您可以在这里查看 metasrv 的示例配置项,以及在这里查看 datanode 的示例配置项。
Step 3: 启动 GreptimeDB
Standalone 模式
假设您正确设置了 GreptimeDB 二进制文件的路径,您可以在终端中执行如下命令,以启动一个 GreptimeDB 单例,并让其使用您在 Step 2 中所设定的配置项。
./greptime standalone start -c config/standalone.example.toml
如果一切正常,您将在终端中看到包含如下内容的日志(您所看到的内容可能由于 GreptimeDB 的版本变化而略有差异):
...
INFO rskafka::connection: Establishing new connection url="127.0.0.1:9092"
INFO rskafka::connection::topology: New broker broker=1 new=127.0.0.1:9092
INFO rskafka::client::controller: Creating new controller broker connection
INFO rskafka::connection: Establishing new connection broker=1 url="127.0.0.1:9092"
INFO common_meta::wal::kafka::topic_manager: Successfully created topic greptimedb_wal_topic_0
INFO rskafka::client::partition: Creating new partition-specific broker connection topic=greptimedb_wal_topic_0 partition=0
INFO rskafka::client::partition: Detected leader topic=greptimedb_wal_topic_0 partition=0 leader=1 metadata_mode=CachedArbitrary
...
INFO frontend::instance: Starting service: MYSQL_SERVER
INFO servers::server: Starting MYSQL_SERVER at 127.0.0.1:4002
INFO servers::server: MySQL server started at 127.0.0.1:4002
...
注意,如您在 Kafka 集群存续的情况下,多次拉起 GreptimeDB,您看到的关于 Kafka 的日志可能有所不同。
Distributed 模式
我们提供了 gtctl 工具以辅助您快速拉起一个 GreptimeDB 集群。为了便于演示,我们使用 gtctl 启动一个 bare-metal 集群,包含 1 个 metasrv、1 个 frontend、3 个 datanodes。为此,您需要准备好 gtctl 所需的配置文件 cluster.yml
。一个示例配置文件的内容如下:
cluster:
name: mycluster
artifact:
local: "/path/to/greptime"
frontend:
replicas: 1
datanode:
replicas: 3
rpcAddr: 0.0.0.0:14100
mysqlAddr: 0.0.0.0:14200
httpAddr: 0.0.0.0:14300
config: '/path/to/datanode.example.toml'
meta:
replicas: 1
storeAddr: 127.0.0.1:2379
serverAddr: 0.0.0.0:3002
httpAddr: 0.0.0.0:14001
config: '/path/to/metasrv.example.toml'
etcd:
artifact:
local: "/path/to/etcd"
其中, metasrv.example.toml
和 datanode.example.toml
分别表示 metasrv 和 datanode 的配置文件的名称。您需要根据您的实际情况修改示例文件中以 /path/to/
为前缀的所有配置项。
假设您已经正确安装了 gtctl,并且已经正确配置好 cluster.yml