---
title: Databend 玩转 Local 模式
description: '目前开发者们需要尝鲜 Databend，可以选择使用 Databend Cloud 或者按官方文档部署 Databend 服务。由于 Databend 架构有三层，因此部署 Databend 服务一般需要启动 `databend-query`, `databend-meta` , `minio` 三个进程，同时需要修改端口等配置项，流程上略显复杂。有没有更快的方式可以快速尝鲜 Databend 呢？'
slug: category-product/databend-local-mode
tags: [Product, Engineering, Rust]
category: Product
cover_url: 'databend-local-mode-cover.png'
image: 'databend-local-mode-cover.png'
authors:
  - sundy-li
---

目前开发者们需要尝鲜 Databend，可以选择使用 Databend Cloud 或者按官方文档部署 Databend 服务。由于 Databend 架构有三层，因此部署 Databend 服务一般需要启动 `databend-query`, `databend-meta` , `minio` 三个进程，同时需要修改端口等配置项，流程上略显复杂。有没有更快的方式可以快速尝鲜 Databend 呢？

{/* truncate */}

### Python Binding

一种快速的方式是将 Databend 跑在 python 中，借助 rust 优良的生态，我们基于 pyo3 库发布了 python binding，可以在本地 juypter 或者 colab 等在线服务中使用 Databend：

    # pip install databend
    from databend import SessionContext

    ctx = SessionContext()

    df = ctx.sql("select number, number + 1, number::String as number_p_1 from numbers(8)")

    # convert to pyarrow
    df.to_py_arrow()

    # convert to pandas
    df.to_pandas()

### Databend Local 模式

借鉴于 `clickhouse-local` , `duckdb` 等嵌入型数据库的优点，我们在 Databend 中也可以开启 local 模式。

`local` 模式 是一个 Databend 的简易版本，用户无需部署 Databend 服务即可在命令中 用 SQL 和 Databend 交互。它的好处在于简化了开发安装，同时方便开发者们用 SQL 使用 Databend 支持的功能进行简单的数据处理。如果你需要在生产环境使用 Databend，我们建议按官网推荐部署 Databend 服务 或 Databend Cloud，但如果你是开发人员或测试工程师，你可以使用 `local` 模式 来玩转 Databend。

`local` 模式将启动一个临时的 databend-query 进程，这个进程融合了客户端和服务端，并且他的存储是在临时目录中，生命周期跟随进程，进程离开后资源也将销毁，你可以在一个服务器中启动多个 `local` 进程，他们的资源是相互隔离的。

下面通过例子介绍一下，每个例子都是简短的几行命令，介绍 `local` 模式可以实现什么功能。

在这之前，你需要下载 databend-query 二进制，然后将二进制放到 PATH 环境变量中，植入 `bend-local` 工具别名

```shell

    alias bend-local="databend-query local"

```

- 命令行交互 ( REPL ) 模式

  - 直接在终端输入 bend-local 这一行命令后，我们将进入 REPL 模式，这里融合了客户端和服务端，类似 duckdb cli 工具使用。

    ```shell
        ❯ bend-local
          Welcome to Databend, version v1.2.4-nightly-326cabe38056168dd261f744609ea85319f02686(rust-1.72.0-nightly-2023-09-02T15:18:48.006847567Z).

          databend-local:) select max(a) from range(1,1000) t(a);
          ┌────────────┐
          │   max(a)   │
          │ Int64 NULL │
          ├────────────┤
          │ 999        │
          └────────────┘
          1 row result in 0.036 sec. Processed 999 rows, 999 B (27.89 thousand rows/s, 217.90 KiB/s)

          databend-local:)
    ```

  - 值得注意的是，bend-local 支持配置文件 `~/.config/databend/config.toml` 来做一些个性化客户端配置，配置文件的格式和 [bendsql](https://github.com/databendlabs/bendsql/blob/main/README.md) 是兼容的。

- 一行命令生成一个 parquet 文件

  - 支持 --query, --output-format 参数 传入查询 SQL 和输出格式

    ```shell
       bend-local --query "select number, number + 1 as b from numbers(10)" --output-format parquet > /tmp/a.parquet

    ```

- Shell pipe 模式分析数据，\$STDIN 宏将解析 stdin 流作为一个临时 stage 表

  ```shell
        ❯ echo '3,4' | bend-local -q "select $1 a, $2 b  from $STDIN  (file_format => 'csv') " --output-format table

         SELECT $1 AS a, $2 AS b FROM 'fs:///dev/fd/0' (FILE_FORMAT => 'csv')

         ┌─────────────────┐
         │    a   │    b   │
         │ String │ String │
         ├────────┼────────┤
         │ '3'    │ '4'    │
         └─────────────────┘
  ```

注意上面的 SQL 在 shell 中，使用了 \$ 来对 shell 进行转义

- 读取 stage table（本地文件，外部 s3 等）

  ```shell

        ❯ bend-local --query "select count() from 'fs:///tmp/a.parquet'  (file_format => 'parquet') "
        10

        ❯ bend-local --query "select count() from 'https://datafuse-1253727613.cos.ap-hongkong.myqcloud.com/data/books.parquet'  (file_format => 'parquet') "
        2

        ❯ bend-local --query "select $1, $2 from 'http://www.geoplugin.net/csv.gp?ip=3.3.3.3'  (file_format => 'csv') "
  ```

- 分析系统进程，找出每个用户占用的内存

  ```shell

         ❯ ps aux | tail -n +2 | awk '{ printf("%s\t%s\n", $1, $4) }' | bend-local -q "select  $1 as user,  sum($2::double) as memory  from $STDIN  (file_format => 'tsv')  group by user  "
          sundy   9.100000000000001
          root    1.2
          dbus    0.0

  ```

- 数据清洗，将一个格式转换为其他格式（支持 csv, tsv, parquet, ndjson 等）

  ```shell

        ❯ bend-local -q 'select rand() as a, rand() as b from numbers(100)' > /tmp/a.tsv


        ❯ cat /tmp/a.tsv | bend-local -q "select $1 a, $2 b  from $STDIN  (file_format => 'tsv') " --output-format parquet > /tmp/a.parquet
  ```

- 其他好玩的分析例子，等待你的挖掘
