快速开始

什么是 Remote WAL

WAL(Write-Ahead Logging) 是 GreptimeDB 中的一个关键组件,它持久记录每一次数据修改,以确保不会丢失缓存在内存中的数据。我们在 Datanode 服务中用持久的嵌入式存储引擎 raft-engine 将 WAL 实现为一个模块。在公共云中部署 GreptimeDB 时,我们可以在云存储(AWS EBS、GCP 持久盘等)中持久存储 WAL 数据,以实现 0 RPO。然而,由于 WAL 与 Datanode 紧密耦合,导致部署过程中的 RTO(Recovery Time Objective)较长。此外,由于 raft-engine 无法支持多日志订阅,这使得实现 region 热备份和 region 迁移变得困难。

为了解决上述问题,我们决定设计并实现一个远程 WAL。远程 WAL 将 WAL 从 Datanode 分离到远程服务,我们选择了 Apache Kafka 作为远程服务。Apache Kafka 在流处理中被广泛采用,展现出卓越的分布式容错能力和基于主题的订阅机制。在发布 v0.5.0 版本时,我们引入了 Apache Kafka 作为 WAL 的可选存储引擎。

运行带有 Remote WAL 的 Standalone GreptimeDB

通过以下步骤使用 Docker 体验远程 WAL 非常简单。在这个快速开始中,我们将创建一个采用 KRaft 模式的 Kafka 集群,并将其作为独立 GreptimeDB 的远程 WAL。

Step 1: 创建一个自定义的 Docker bridge

自定义的 Docker bridge 可以帮助我们创建用于连接多个容器的桥接网络:

  1. docker network create greptimedb-remote-wal

Step 2: 启动 Kafka 服务

使用 KRaft 模式来启动单节点 Kafka:

  1. docker run \
  2. --name kafka --rm \
  3. --network greptimedb-remote-wal \
  4. -p 9092:9092 \
  5. -e KAFKA_CFG_NODE_ID="1" \
  6. -e KAFKA_CFG_PROCESS_ROLES="broker,controller" \
  7. -e KAFKA_CFG_CONTROLLER_QUORUM_VOTERS="1@kafka:9093" \
  8. -e KAFKA_CFG_ADVERTISED_LISTENERS="PLAINTEXT://kafka:9092" \
  9. -e KAFKA_CFG_CONTROLLER_LISTENER_NAMES="CONTROLLER" \
  10. -e KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP="CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT" \
  11. -e KAFKA_CFG_LISTENERS="PLAINTEXT://:9092,CONTROLLER://:9093" \
  12. -e ALLOW_PLAINTEXT_LISTENER="yes" \
  13. -e KAFKA_BROKER_ID="1" \
  14. -e KAFKA_CFG_LOG_DIRS="/bitnami/kafka/data" \
  15. -v $(pwd)/kafka-data:/bitnami/kafka/data \
  16. bitnami/kafka:3.6.0

数据将保存在 $(pwd)/kafka-data.

Step 3: 用 Remote WAL 模式启动 standalone 模式 GreptimeDB

使用 Kafka wal provider 来启动 standalone 模式的 GreptimeDB:

  1. docker run \
  2. --network greptimedb-remote-wal \
  3. -p 4000-4003:4000-4003 -p 4242:4242 \
  4. -v "$(pwd)/greptimedb:/tmp/greptimedb" \
  5. --name greptimedb --rm \
  6. -e GREPTIMEDB_STANDALONE__WAL__PROVIDER="kafka" \
  7. -e GREPTIMEDB_STANDALONE__WAL__BROKER_ENDPOINTS="kafka:9092" \
  8. greptime/greptimedb standalone start \
  9. --http-addr 0.0.0.0:4000 \
  10. --rpc-addr 0.0.0.0:4001 \
  11. --mysql-addr 0.0.0.0:4002 \
  12. --postgres-addr 0.0.0.0:4003 \
  13. --opentsdb-addr 0.0.0.0:4242

我们使用环境变量来指定 provider:

  • GREPTIMEDB_STANDALONE__WAL__PROVIDER: 设置为 kafka 以此来使用 kafka remote wal;
  • GREPTIMEDB_STANDALONE__WAL__BROKER_ENDPOINTS: 指定 Kafka 集群中所有 brokers 的地址。在此示例中,我们将使用 Kafka 容器的名称,桥接网络将其解析为 IPv4 地址;

Step 4: 写入和查询数据

有很多方式来连接 GreptimeDB,这里我们选择使用 mysql 命令行工具。

  1. 用 MySQL 协议连接 GrepimeDB

    1. mysql -h 127.0.0.1 -P 4002
  2. 写入测试数据

    • 创建 system_metrics

      1. CREATE TABLE IF NOT EXISTS system_metrics (
      2. host STRING,
      3. idc STRING,
      4. cpu_util DOUBLE,
      5. memory_util DOUBLE,
      6. disk_util DOUBLE,
      7. ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
      8. PRIMARY KEY(host, idc),
      9. TIME INDEX(ts)
      10. );
    • 写入测试数据

      1. INSERT INTO system_metrics
      2. VALUES
      3. ("host1", "idc_a", 11.8, 10.3, 10.3, 1667446797450),
      4. ("host1", "idc_a", 80.1, 70.3, 90.0, 1667446797550),
      5. ("host1", "idc_b", 50.0, 66.7, 40.6, 1667446797650),
      6. ("host1", "idc_b", 51.0, 66.5, 39.6, 1667446797750),
      7. ("host1", "idc_b", 52.0, 66.9, 70.6, 1667446797850),
      8. ("host1", "idc_b", 53.0, 63.0, 50.6, 1667446797950),
      9. ("host1", "idc_b", 78.0, 66.7, 20.6, 1667446798050),
      10. ("host1", "idc_b", 68.0, 63.9, 50.6, 1667446798150),
      11. ("host1", "idc_b", 90.0, 39.9, 60.6, 1667446798250);
  3. 查询数据

    1. SELECT * FROM system_metrics;
  4. 查询 Kafka Topics

    1. # List the Kafka topics.
    2. docker exec kafka /opt/bitnami/kafka/bin/kafka-topics.sh --list --bootstrap-server localhost:9092

    默认所有 topic 都以 greptimedb_wal_topic 开头,例如:

    1. docker exec kafka /opt/bitnami/kafka/bin/kafka-topics.sh --list --bootstrap-server localhost:9092
    2. greptimedb_wal_topic_0
    3. greptimedb_wal_topic_1
    4. greptimedb_wal_topic_10
    5. ...

Step 5: 清理

  • 停止 GreptimeDB 和 Kafka

    1. docker stop greptimedb
    2. docker stop kafka
  • 移除 Docker bridge

    1. docker network rm greptimedb-remote-wal
  • 删除数据

    1. rm -r <working-dir>/greptimedb
    2. rm -r <working-dir>/kafka-data