Skip to content

快速开始

什么是 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 可以帮助我们创建用于连接多个容器的桥接网络:

docker network create greptimedb-remote-wal
docker network create greptimedb-remote-wal

Step 2: 启动 Kafka 服务

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

docker run \
  --name kafka --rm \
  --network greptimedb-remote-wal \
  -p 9092:9092 \
  -e KAFKA_CFG_NODE_ID="1" \
  -e KAFKA_CFG_PROCESS_ROLES="broker,controller" \
  -e KAFKA_CFG_CONTROLLER_QUORUM_VOTERS="1@kafka:9093" \
  -e KAFKA_CFG_ADVERTISED_LISTENERS="PLAINTEXT://kafka:9092" \
  -e KAFKA_CFG_CONTROLLER_LISTENER_NAMES="CONTROLLER" \
  -e KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP="CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT" \
  -e KAFKA_CFG_LISTENERS="PLAINTEXT://:9092,CONTROLLER://:9093" \
  -e ALLOW_PLAINTEXT_LISTENER="yes" \
  -e KAFKA_BROKER_ID="1" \
  -e KAFKA_CFG_LOG_DIRS="/bitnami/kafka/data" \
  -v $(pwd)/kafka-data:/bitnami/kafka/data \
  bitnami/kafka:3.6.0
docker run \
  --name kafka --rm \
  --network greptimedb-remote-wal \
  -p 9092:9092 \
  -e KAFKA_CFG_NODE_ID="1" \
  -e KAFKA_CFG_PROCESS_ROLES="broker,controller" \
  -e KAFKA_CFG_CONTROLLER_QUORUM_VOTERS="1@kafka:9093" \
  -e KAFKA_CFG_ADVERTISED_LISTENERS="PLAINTEXT://kafka:9092" \
  -e KAFKA_CFG_CONTROLLER_LISTENER_NAMES="CONTROLLER" \
  -e KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP="CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT" \
  -e KAFKA_CFG_LISTENERS="PLAINTEXT://:9092,CONTROLLER://:9093" \
  -e ALLOW_PLAINTEXT_LISTENER="yes" \
  -e KAFKA_BROKER_ID="1" \
  -e KAFKA_CFG_LOG_DIRS="/bitnami/kafka/data" \
  -v $(pwd)/kafka-data:/bitnami/kafka/data \
  bitnami/kafka:3.6.0

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

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

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

docker run \
  --network greptimedb-remote-wal \
  -p 4000-4003:4000-4003 -p 4242:4242 \
  -v "$(pwd)/greptimedb:/tmp/greptimedb" \
  --name greptimedb --rm \
  -e GREPTIMEDB_STANDALONE__WAL__PROVIDER="kafka" \
  -e GREPTIMEDB_STANDALONE__WAL__BROKER_ENDPOINTS="kafka:9092" \
  greptime/greptimedb standalone start \
  --http-addr 0.0.0.0:4000 \
  --rpc-addr 0.0.0.0:4001 \
  --mysql-addr 0.0.0.0:4002 \
  --postgres-addr 0.0.0.0:4003 \
  --opentsdb-addr 0.0.0.0:4242
docker run \
  --network greptimedb-remote-wal \
  -p 4000-4003:4000-4003 -p 4242:4242 \
  -v "$(pwd)/greptimedb:/tmp/greptimedb" \
  --name greptimedb --rm \
  -e GREPTIMEDB_STANDALONE__WAL__PROVIDER="kafka" \
  -e GREPTIMEDB_STANDALONE__WAL__BROKER_ENDPOINTS="kafka:9092" \
  greptime/greptimedb standalone start \
  --http-addr 0.0.0.0:4000 \
  --rpc-addr 0.0.0.0:4001 \
  --mysql-addr 0.0.0.0:4002 \
  --postgres-addr 0.0.0.0:4003 \
  --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

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

    • 创建 system_metrics

      sql
      CREATE TABLE IF NOT EXISTS system_metrics (
          host STRING,
          idc STRING,
          cpu_util DOUBLE,
          memory_util DOUBLE,
          disk_util DOUBLE,
          ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
          PRIMARY KEY(host, idc),
          TIME INDEX(ts)
      );
      CREATE TABLE IF NOT EXISTS system_metrics (
          host STRING,
          idc STRING,
          cpu_util DOUBLE,
          memory_util DOUBLE,
          disk_util DOUBLE,
          ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
          PRIMARY KEY(host, idc),
          TIME INDEX(ts)
      );
    • 写入测试数据

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

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

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

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

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

Step 5: 清理

  • 停止 GreptimeDB 和 Kafka

    docker stop greptimedb
    docker stop kafka
    docker stop greptimedb
    docker stop kafka
  • 移除 Docker bridge

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

    rm -r <working-dir>/greptimedb
    rm -r <working-dir>/kafka-data
    rm -r <working-dir>/greptimedb
    rm -r <working-dir>/kafka-data