CockroachDB权威指南——开始使用

CockroachDB拥有复杂且现代化的架构,旨在支持全球规模的应用。然而,这种复杂性和可扩展性并不意味着陡峭的学习曲线或高门槛。在本章中,我们将帮助你开始使用CockroachDB的安装,并向你介绍与CockroachDB系统工作的一些基础知识。

安装

CockroachDB可以在几分钟内安装在几乎所有主流桌面操作系统上。除此之外,你还可以创建一个免费的CockroachDB Cloud Basic数据库,或者在Docker容器或Kubernetes集群中运行CockroachDB。

安装CockroachDB软件

在大多数情况下,你可能希望将CockroachDB软件安装在桌面计算机上,所以我们从这个步骤开始。你可以在CockroachDB文档中找到完整的二进制文件列表,从中选择适合你操作系统的版本,并下载最新版本或选择之前的版本。

以下说明适用于本文写作时的版本,但安装方法可能会随着每个版本的更新而有所不同,请确保查阅CockroachDB官网获取最新的安装说明。

在macOS上安装

如果你已经安装了Homebrew包管理器,那么它可能是安装CockroachDB的最简便方式。事实上,即使你没有安装Homebrew,安装它并通过Homebrew安装CockroachDB可能比手动安装CockroachDB更为简单。

要安装Homebrew,可以在终端窗口中输入以下命令:

bash 复制代码
/bin/bash -c \
"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

安装完成后,可以使用以下命令安装CockroachDB:

shell 复制代码
% brew install cockroachdb/tap/cockroach

Homebrew会设置CockroachDB作为后台服务,因此你可以通过 brew services start cockroach 来启动CockroachDB的后台实例。如果你不想使用Homebrew,也可以直接下载CockroachDB的二进制文件,并将其复制到路径中。你可以查看发布文档来确定你想要的版本的路径,然后使用curl或wget来复制并解压该版本:

arduino 复制代码
% curl https://binaries.cockroachdb.com/cockroach-v24.2.0.darwin-11.0-arm64.tgz \
    | tar -xJ

然后,你可以将二进制文件复制到你的路径中,这样就可以从任何目录执行Cockroach命令:

bash 复制代码
sudo cp -R cockroach-v24.2.0.darwin-11.0-arm64/* /usr/local/bin

安装完成后,可以运行 cockroach demo 命令来启动一个演示实例并确认其运行状态:

php 复制代码
% cockroach demo
#
# 欢迎使用CockroachDB演示数据库!
#
# 你已连接到一个临时的内存中CockroachDB集群,包含1个节点。
#
# 输入 ? 查看简要介绍。
#
[email protected]:26257/movr> show databases;
  database_name | owner | primary_region | regions | survival_goal
----------------+-------+----------------+---------+----------------
  defaultdb     | root  | NULL           | {}      | NULL
  movr          | demo  | NULL           | {}      | NULL
  postgres      | root  | NULL           | {}      | NULL
  system        | node  | NULL           | {}      | NULL
(4 rows)

在Linux上安装

要在Linux上进行基本安装,首先找到最新的发布版本(或你感兴趣的特定版本),然后下载并解压它。当然,你可以使用curl或wget来获取tar包,下载路径确认后执行:

ruby 复制代码
$ wget https://binaries.cockroachdb.com/cockroach-v24.2.0.linux-arm64.tgz

下载完成后,解压:

ruby 复制代码
$ tar zxvf cockroach-v24.2.0.linux-arm64.tgz

然后,将CockroachDB的二进制文件复制到你的路径中:

shell 复制代码
$ sudo cp -r cockroach-v24.2.0.linux-arm64/* /usr/local/bin

安装完成后,可以运行 cockroach demo 命令来启动CockroachDB的本地临时实例并验证安装是否成功:

perl 复制代码
$ cockroach demo
#
# 欢迎使用CockroachDB演示数据库!
#
# 你已连接到一个临时的内存中CockroachDB集群,包含1个节点。
#
# 输入 ? 查看简要介绍。
#
[email protected]:44913/movr> show databases;
  database_name | owner
----------------+--------
  defaultdb     | root
  movr          | root
  postgres      | root
  system        | node
(4 rows)

对于完全手动的安装,如果你希望使用地理空间特性,可能需要手动安装地理空间库。更多详细信息请参见CockroachDB文档。

在Microsoft Windows上安装

Microsoft Windows不是完全支持运行CockroachDB服务器的操作系统。不过,Windows平台完全支持CockroachDB客户端,且服务器在大多数开发和实验场景中运行良好。

你可以在CockroachDB官方网站上找到适合Windows的发布版本链接。下载后,将解压后的目录添加到你的路径中,或者可以直接从PowerShell提示符中下载文件。有关详细的操作说明,可以参考CockroachDB文档网站。

CockroachDB连接URL

连接CockroachDB集群时,我们需要指定连接位置和凭据。当使用 cockroach democockroach sql 连接到本地服务器时,CockroachDB客户端会默认连接到本地服务器的默认端口。但在更复杂的安装环境中,连接信息会更加复杂。

最常见的连接方式是使用PostgreSQL兼容的URL,格式如下:

ini 复制代码
postgresql://[user[:passwd]]@[host][:port]/[db][?parameters...]

对于本地集群运行且没有认证的最简单URL如下:

ruby 复制代码
$ cockroach sql --url 'postgres://root@localhost:26257?sslmode=disable'
#
# 欢迎使用CockroachDB SQL Shell。
# 所有语句必须以分号结尾。
# 要退出,请输入:\q。
#
# 集群ID: 072189bb-3970-4f37-afe4-55bc37cdf76e
#
# 输入 ? 查看简要介绍。
#
root@localhost:26257/defaultdb>

这等同于运行命令 cockroach sql --insecure

URL的优点是大多数PostgreSQL兼容的程序或驱动程序都可以接受它。例如,如果安装了PostgreSQL客户端,也可以用它来连接到CockroachDB:

python 复制代码
$ psql 'postgres://root@localhost:26257?sslmode=disable'
psql (13.2, server 9.5.0)
Type "help" for help.

root=#

创建CockroachDB Cloud Basic实例

cockroach demo 命令是一个方便的工具,可以用来试玩CockroachDB服务器,但获得一个完全功能且具有持久存储的CockroachDB服务器最简单的方法是利用免费的CockroachDB Cloud Basic数据库服务。该服务为你提供了一个功能齐全的多租户云服务,拥有10 GiB的存储空间。

与桌面部署相比,CockroachDB Cloud Basic有多个优势:

  • 自动配置高可用性和备份。你不必担心在桌面硬盘发生故障时丢失数据。
  • 完全加密保护,包括静态数据和传输中的数据。
  • 随时随地可用,因此非常适合团队开发使用。
  • 适合入门项目和评估CockroachDB

要创建一个CockroachDB Cloud Basic集群,首先访问注册页面并选择基础计划(Basic plan)。在输入详细信息并验证邮箱地址后,你将有机会创建免费的集群。

集群创建完成后,你将收到连接的说明。虽然这些说明适用于所有操作系统用户,但对于Mac用户来说,步骤大致如下图3-1所示。

假设你已经下载了CockroachDB二进制文件,按照说明中的curl命令将必要的证书复制到桌面,然后使用cockroach sql命令连接到数据库:

shell 复制代码
$ curl --create-dirs -o $HOME/.postgresql/root.crt -O \
  https://cockroachlabs.cloud/clusters/614eb05c-0493-4947-962a-b07e3b282ef2/cert
ruby 复制代码
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  2728    0  2728    0     0   5250      0 --:--:-- --:--:-- --:--:--  5317
sql 复制代码
$ cockroach sql \
  --url "postgresql://rob:[email protected]"
#
# 欢迎使用CockroachDB SQL Shell。
# 所有语句必须以分号结尾。
# 要退出,请输入:\q。
#
# 集群ID:614eb05c-0493-4947-962a-b07e3b282ef2
警告:无法显示服务器执行时间:发现了意外的列
#
# 输入 ? 查看简要介绍。
#
rob@cloudy-jackal.../defaultdb> SELECT
                                  database_name,
                                  primary_region,
                                  regions,
                                  survival_goal
                                FROM [SHOW DATABASES];

  database_name | primary_region |     regions     | survival_goal
----------------+----------------+-----------------+----------------
  defaultdb     | NULL           | {}              | NULL
  postgres      | NULL           | {}              | NULL
  system        | aws-eu-west-1  | {aws-eu-west-1} | zone
(3 rows)

Time: 32ms total (execution 7ms / network 26ms)

CockroachDB Cloud Basic密码

请注意,连接字符串中的密码并不是你用来连接CockroachDB Cloud Basic账户的密码。你的CockroachDB Cloud Basic账户可能与多个数据库相关联,每个数据库都有自己的密码。连接对话框中显示的密码只有在你悬停在"REVEAL_PASSWORD"链接上时才会显示,而且只会在数据库创建时显示一次。保存这个密码并确保它的安全是你的责任。如果忘记了密码,你可以通过访问SQL用户页面来重置密码。

启动本地单节点服务器

如前所述,你可以使用 cockroach demo 命令来启动一个临时的演示集群,我们也可以快速创建一个免费的CockroachDB Cloud Basic集群。如果你想在自己的硬件上启动一个具有持久存储的单节点CockroachDB服务器,可以使用 cockroach start-single-node 命令:

markdown 复制代码
$ cockroach start-single-node --insecure --listen-addr=localhost
*
* 警告:所有安全控制已被禁用!
*
* 此模式仅用于非生产环境的测试。
*
* 在此模式下:
* - 你的集群对任何可以访问你IP地址的客户端开放。
* - 入侵者可以观察客户端与服务器之间的通信。
* - 入侵者可以无需密码登录,并读写集群中的任何数据。
* - 入侵者可以消耗你服务器的所有资源,导致无法使用。
*
*
* 信息:要启动一个不强制要求TLS客户端的安全服务器,
* 可以考虑使用 --accept-sql-without-tls。更多选项,请参阅:
*
* - https://go.crdb.dev/issue-v/53404/v24.2
* - https://www.cockroachlabs.com/docs/v24.2/secure-a-cluster.html
*

这将启动一个没有安全设置的单节点CockroachDB集群。要连接到此服务器,我们可以使用 cockroach sql 命令,并使用默认连接字符串:

yaml 复制代码
$ cockroach sql --insecure
#
# 欢迎使用CockroachDB SQL Shell。
# 所有语句必须以分号结尾。
# 要退出,请输入:\q。
#
# 集群ID:848d8b85-4000-484a-b4ad-8f2c76c68221
#
# 输入 ? 查看简要介绍。
#
root@:26257/defaultdb> show databases;
  database_name | owner | primary_region | regions | survival_goal
----------------+-------+----------------+---------+----------------
  defaultdb     | root  | NULL           | {}      | NULL
  postgres      | root  | NULL           | {}      | NULL
  system        | node  | NULL           | {}      | NULL
(3 rows)

Time: 3ms total (execution 3ms / network 0ms)

root@:26257/defaultdb>

不安全模式

使用 --insecure 标志可以方便地快速启动CockroachDB集群,但绝对不适合用于生产系统。请参阅第10章了解如何设置一个正确安全的生产系统。

在Docker容器中启动CockroachDB

如果你安装了Docker,可以在Docker容器中快速启动一个CockroachDB单节点实例。你需要为数据创建一个持久化卷,首先创建该卷:

lua 复制代码
$ docker volume create crdb1

然后,使用 docker run 命令拉取并启动最新的CockroachDB Docker镜像,并以单节点、不安全模式启动服务器:

markdown 复制代码
$ docker run -d \
> --name=crdb1 \
> --hostname=crdb1 \
> -p 26257:26257 -p 8080:8080  \
> -v "crdb1:/cockroach/cockroach-data"  \
> cockroachdb/cockroach:latest start-single-node  \
> --insecure \

如果本地没有找到镜像,输出将类似于:

vbnet 复制代码
Unable to find image 'cockroachdb/cockroach:latest' locally
latest: Pulling from cockroachdb/cockroach
a591faa84ab0: Pull complete
...
6913e7a5719....914b1aafe8

docker run 命令的输出是CockroachDB容器的容器标识符。使用该容器ID,我们可以通过 cockroach sql 命令连接到该容器:

yaml 复制代码
$ docker exec -it 6913e7a5719....914b1aafe8 \
    cockroach sql --insecure
#
# 欢迎使用CockroachDB SQL Shell。
# 所有语句必须以分号结尾。
# 要退出,请输入:\q。
#
# 集群ID:8fcbb9bb-ec7c-40dc-afe0-90306c87f5d7
#
# 输入 ? 查看简要介绍。
#
root@:26257/defaultdb> show databases;
  database_name | owner | primary_region | regions | survival_goal
----------------+-------+----------------+---------+----------------
  defaultdb     | root  | NULL           | {}      | NULL
  postgres      | root  | NULL           | {}      | NULL
  system        | node  | NULL           | {}      | NULL
(3 rows)

Time: 4ms total (execution 3ms / network 1ms)

我们不需要在本地主机上安装CockroachDB软件来使用上述方法连接,因为我们正在使用安装在Docker容器中的CockroachDB客户端。然而,由于我们已经将端口26257从Docker容器转发到本地,我们也可以使用默认连接从桌面连接:

shell 复制代码
$ ~ cockroach sql --insecure
#
# 欢迎使用CockroachDB SQL Shell。
# 所有语句必须以分号结尾。
# 要退出,请输入:\q。
#
# 集群ID:d070609f-58a7-4aea-aa27-92bc4a1e5406
#
# 输入 ? 查看简要介绍。
#
root@:26257/defaultdb>

请注意,只有在端口上没有其他CockroachDB服务器正在监听时,端口转发才会生效。

启动安全服务器

在之前的示例中,我们使用了 --insecure 标志来启动不需要配置安全通信的服务器。这是设置测试服务器的快速方法,但对于任何包含有价值数据的环境来说,这种做法极其危险。

我们将在第13章深入讨论CockroachDB的安全性,但现在,为了设置一个安全服务器,我们需要创建安全证书来加密通信通道,并对客户端和服务器进行身份验证。

以下命令用于创建证书。证书颁发机构(CA)的密钥将存储在 my-safe-directory 中;证书本身将存储在 certs 目录下:

ini 复制代码
$ mkdir certs my-safe-directory

$ # 创建CA证书和密钥对
$ cockroach cert create-ca \
>     --certs-dir=certs \
>     --ca-key=my-safe-directory/ca.key

$ # 为localhost创建证书和密钥对
$ cockroach cert create-node localhost `hostname` --certs-dir=certs \
>     --ca-key=my-safe-directory/ca.key

$ # 为root用户创建证书
$ cockroach cert create-client root \
>     --certs-dir=certs \
>     --ca-key=my-safe-directory/ca.key

现在,我们可以启动服务器并指定包含证书的目录:

ini 复制代码
$ # 启动单节点
$ cockroach start-single-node --certs-dir=certs \
  --listen-addr=localhost

现在,在连接时,我们必须指定证书目录。如果我们从远程主机进行连接,那么我们需要将证书复制到该主机。

ini 复制代码
$ cockroach sql --certs-dir=certs
#
# 欢迎使用CockroachDB SQL Shell。
# 所有语句必须以分号结尾。
# 要退出,请输入:\q。
#
# 集群ID:f908d29e-1fb6-40b8-9e1f-a2a0a3763603
#
# 输入 ? 查看简要介绍。
#
root@:26257/defaultdb>

证书目录

在Linux或macOS系统上,CockroachDB会在 ~/.cockroach-certs 目录中查找证书。如果你的证书放在这个目录下,那么你就不需要指定 --certs-dir 参数。然而,如果你有多个CockroachDB服务器,可能需要为每个服务器维护不同的证书,并将其保存在各自的目录中。

关闭服务器

如果服务器是使用 --background 标志启动的,那么我们可以使用终止信号来关闭服务器。例如,可以使用 killall 来向当前运行的所有 cockroach 命令发送终止命令:

ruby 复制代码
$ killall cockroach

正在启动服务器的优雅关机
服务器已成功关闭

要关闭特定的服务器,首先找到其进程ID,然后使用 kill 命令终止该进程:

shell 复制代码
$ ps -ef | grep cockroach
ubuntu     13911       1 10 10:16 pts/0    00:00:43 cockroach
     start-single-node --insecure --listen-addr=localhost

$ kill 13911
$ 正在启动服务器的优雅关机
服务器已成功关闭

远程连接

在之前的示例中,我们连接的是运行在与客户端相同主机上的服务器。这在现实世界中相对不常见,因为我们通常会连接到另一台机器上的服务器。通常,我们会指定 URL 参数来标识目标服务器。例如,要连接到 mubuntu 服务器上的默认端口,我们可以使用以下命令:

shell 复制代码
$ cockroach sql --certs-dir=certs --url postgresql://root@mubuntu:26257/defaultdb
#
# 欢迎使用CockroachDB SQL Shell。
# 所有语句必须以分号结尾。
# 要退出,请输入:\q。
#
# 集群ID:f908d29e-1fb6-40b8-9e1f-a2a0a3763603
#
# 输入 ? 查看简要介绍。
#
root@mubuntu:26257/defaultdb>

创建Kubernetes集群

在之前的示例中,我们创建了单节点集群并连接到免费的CockroachDB Cloud Basic数据库,这是一个多租户集群的共享区域。如果你想要启动一个专用的多节点集群,最简单的方法是使用CockroachDB Kubernetes操作符在Kubernetes环境中安装CockroachDB集群。

Kubernetes是一个日益普及的框架,用于协调和编排分布式系统的组件管理。CockroachDB Kubernetes操作符包含配置和工具,允许在Kubernetes中部署CockroachDB。

我们将在本书后续章节中回顾Kubernetes的生产部署选项。现在,我们将在Kubernetes的minikube集群中部署CockroachDB,minikube是在桌面系统上实现的本地Kubernetes集群。

在本示例中,我们使用的是在macOS上运行的minikube集群,配置了6个CPU和12GB内存。你可以通过以下命令启动此类集群:

css 复制代码
~ minikube start --memory=12G --cpus=6
😀 minikube v1.18.1 on Darwin 12.1

第一步是部署操作符及其清单:

bash 复制代码
$ kubectl apply -f https://cockroa.ch/crdbclusters_yaml

customresourcedefinition.apiextensions.k8s.io/crdbclusters.crdb.cockroachlabs.com
created

$ kubectl apply -f https://cockroa.ch/operator_yaml

clusterrole.rbac.authorization.k8s.io/cockroach-database-role created
serviceaccount/cockroach-database-sa created
clusterrolebinding.rbac.authorization.k8s.io/cockroach-database-rolebinding
created
role.rbac.authorization.k8s.io/cockroach-operator-role created
clusterrolebinding.rbac.authorization.k8s.io/cockroach-operator-rolebinding
created
clusterrole.rbac.authorization.k8s.io/cockroach-operator-role created
serviceaccount/cockroach-operator-sa created
rolebinding.rbac.authorization.k8s.io/cockroach-operator-default created
deployment.apps/cockroach-operator created

完成后,使用 kubectl get pods 命令检查CockroachDB Kubernetes操作符是否正在集群中运行:

arduino 复制代码
$ kubectl config set-context --current --namespace=cockroach-operator-system
$ kubectl get pods
NAME                                  READY   STATUS              RESTARTS   AGE
cockroach-operator-84bf588dbb-65m8k   0/1     ContainerCreating   0          9s

接下来,获取操作符仓库中包含的示例配置文件:

ruby 复制代码
$ curl -O https://cockroa.ch/example_yaml -o example.yaml

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1098  100  1098    0     0   3399      0 --:--:-- --:--:-- --:--:--  3399

该文件包含要配置的集群定义,例如要创建的节点数量、每个节点所需的内存和CPU。配置文件倾向于生产部署,因此你可能需要根据需要减少要求。例如,以下代码中默认配置文件指定了60 GB的存储需求。对于简单的测试系统,我们可能想将其改为较低的值(或者对于更大的部署,增加该值):

yaml 复制代码
apiVersion: crdb.cockroachlabs.com/v1alpha1
kind: CrdbCluster
metadata:
  name: cockroachdb
spec:
  dataStore:
    pvc:
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: "60Gi"
        volumeMode: Filesystem

你可以编辑配置文件的其他元素,如要创建的节点数或使用的CockroachDB版本。

现在,我们将配置文件应用到操作符,操作符将执行必要的任务来创建集群:

bash 复制代码
$ kubectl apply -f example.yaml
crdbcluster.crdb.cockroachlabs.com/cockroachdb created

集群创建过程可能需要一些时间。当所有节点都处于"Running"状态时,使用 kubectl get pods 命令即可确认:

sql 复制代码
$ kubectl get pods
NAME                                  READY   STATUS    RESTARTS   AGE
cockroach-operator-84bf588dbb-65m8k   1/1     Running   0          6m59s
cockroachdb-0                         1/1     Running   0          87s
cockroachdb-1                         1/1     Running   0          71s
cockroachdb-2                         1/1     Running   0          57s

我们可以通过在任何CockroachDB节点中执行 cockroach sql 命令来连接集群。例如,这里我们连接到 cockroachdb-2 节点并连接到集群:

yaml 复制代码
$ kubectl exec -it cockroachdb-2 -- ./cockroach sql --certs-dir cockroach-certs
#
# 欢迎使用CockroachDB SQL Shell。
# 所有语句必须以分号结尾。
# 要退出,请输入:\q。
#
# 集群ID:cb78255b-befa-4447-9fa8-c06b7a353564
#
# 输入 ? 查看简要介绍。
#
  database_name | owner | primary_region | regions | survival_goal
----------------+-------+----------------+---------+----------------
  defaultdb     | root  | NULL           | {}      | NULL
  postgres      | root  | NULL           | {}      | NULL
  system        | node  | NULL           | {}      | NULL
(3 rows)

Time: 7ms total (execution 6ms / network 1ms)

使用这种方法连接集群需要较高的访问权限。在生产环境中,我们通常会设置负载均衡器来安全地处理进入集群的请求。我们将在第10章中讨论这些配置。

使用Terraform创建集群

CockroachDB Cloud集群可以使用Terraform创建和配置,Terraform是HashiCorp提供的流行的基础设施即代码(IaC)平台。在本节中,我们将使用Terraform创建CockroachDB Cloud Basic、Standard和Advanced集群。

首先,我们初始化CockroachDB的Terraform提供程序:

ini 复制代码
terraform {
  required_providers {
    cockroach = {
      source  = "cockroachdb/cockroach"
      version = "2.0.0"
    }
  }
}

接下来,我们创建一个文件夹。虽然是可选的,但文件夹有助于客户组织他们的CockroachDB Cloud集群,并且最多可以嵌套四级。在账单仪表板上,文件夹允许客户查看其中任何集群的总成本。

ini 复制代码
resource "cockroach_folder" "top" {
  name      = "level_1"
  parent_id = "root"
}

resource "cockroach_folder" "nested" {
  name      = "level_2"
  parent_id = cockroach_folder.top.id
}

接下来,我们创建集群,从AWS上的CockroachDB Cloud Basic集群开始。以下Terraform资源将在三个区域创建一个Basic集群,并指定每月100万个请求单位(RUs)和1 GiB的存储限制。parent_id 引用了我们之前定义的嵌套文件夹的ID:

ini 复制代码
resource "cockroach_cluster" "basic" {
  cloud_provider = "AWS"
  name           = "aws-basic"
  regions = [
    { name : "us-east-1", primary = true },
    { name : "eu-central-1" },
    { name : "ap-southeast-1" }
  ]

  serverless = {
    usage_limits = {
      request_unit_limit = 1000000
      storage_mib_limit  = 1024
    }
  }

  parent_id = cockroach_folder.nested.id
}

接下来,我们将创建一个在GCP中的CockroachDB Cloud Standard集群。与Basic集群一样,Standard集群将跨三个区域运行,但这次我们按vCPUs进行限制,确保集群访问2个vCPUs:

ini 复制代码
resource "cockroach_cluster" "standard" {
  cloud_provider = "GCP"
  name           = "gcp-standard"
  regions = [
    { name : "us-east1", primary = true },
    { name : "europe-west1" },
    { name : "asia-southeast1" }
  ]

  serverless = {
    usage_limits = {
      provisioned_virtual_cpus = 2
    }
  }

  parent_id = cockroach_folder.nested.id
}

最后,我们将创建一个在Azure中的CockroachDB Cloud Advanced集群。与Basic和Standard集群一样,Advanced集群将跨三个区域运行。与Basic和Standard集群不同的是,Advanced集群使用专用硬件运行,因此我们为每个区域指定节点数、磁盘大小(以GiB为单位)和每个节点的vCPU数:

ini 复制代码
resource "cockroach_cluster" "advanced" {
  cloud_provider = "AZURE"
  name           = "azure-advanced"
  regions = [
    {
      name : "eastus",
      node_count = 3
    },
    {
      name : "germanywestcentral",
      node_count = 3
    },
    {
      name : "southeastasia",
      node_count = 3
    }
  ]

  dedicated = {
    storage_gib      = 16
    num_virtual_cpus = 4
  }

  parent_id = cockroach_folder.nested.id
}

对于Standard集群,我们将提供更多资源,以更好地理解可用的选项。以下配置不会涵盖所有内容,完整的可用资源列表可以在CockroachDB Terraform Provider文档中找到。

首先,我们定义一个IP允许列表,授予全球所有IP的访问权限。通常,你会希望通过VPC Peering、AWS PrivateLink和GCP Private Service Connect等技术私密地公开集群,但为了这个示例,我们保持简单:

ini 复制代码
resource "cockroach_allow_list" "standard" {
  name       = "Unrestricted access"
  cidr_ip    = "0.0.0.0"
  cidr_mask  = 0
  sql        = true
  ui         = false
  cluster_id = cockroach_cluster.standard.id
}

接下来,我们将创建一个带有密码的SQL用户。我们将生成密码,因此我们需要使用一个输出块使其在应用后可用:

ini 复制代码
resource "random_password" "standard" {
  special = false
  length  = 50
}

resource "cockroach_sql_user" "standard" {
  cluster_id = cockroach_cluster.standard.id
  name       = "rob"
  password   = random_password.standard.result
}

output "password" {
  value     = cockroach_sql_user.standard.password
  sensitive = true
}

应用后,我们可以通过以下命令访问密码:

lua 复制代码
terraform output -raw password
rk7B6QncmN2jRvU2...

数据库也可以在Terraform中定义。我们将为Standard集群创建一个示例数据库:

ini 复制代码
resource "cockroach_database" "standard" {
  name       = "accounts"
  cluster_id = cockroach_cluster.standard.id
}

最后,我们将创建一个具有最小访问权限的服务账户。此账户可用于访问诸如Metrics Export端点等服务。与用户密码一样,我们需要输出API密钥,以便它可以在Terraform外部使用:

ini 复制代码
resource "cockroach_service_account" "standard_monitor" {
  name        = "standard-cluster-monitor"
  description = "A service account for use in monitoring the standard cluster."
}

resource "cockroach_user_role_grant" "standard_monitor" {
  user_id = cockroach_service_account.standard_monitor.id
  role = {
    role_name     = "CLUSTER_OPERATOR_WRITER",
    resource_type = "CLUSTER",
    resource_id   = cockroach_cluster.standard.id
  }
}

resource "cockroach_api_key" "standard_monitor" {
  name               = "standard-cluster-monitor-key-v1"
  service_account_id = cockroach_service_account.standard_monitor.id
}

output "standard_monitor_api_key" {
  value       = cockroach_api_key.standard_monitor.secret
  description = "The standard-cluster-monitor-key-v1 API key"
  sensitive   = true
}

应用后,我们可以通过以下命令访问API密钥:

lua 复制代码
terraform output -raw standard_monitor_api_key
CCDB1_X363xP8T6Y...

配置可以通过以下命令应用:

复制代码
terraform apply

并通过以下命令销毁:

复制代码
terraform destroy

使用GUI客户端

虽然有些人很高兴仅使用命令行客户端与数据库进行交互,但我们中有些人更喜欢使用GUI。PostgreSQL有许多GUI应用程序,大多数都可以与CockroachDB兼容。然而,DBeaver Community版是一个免费的数据库GUI,具有对CockroachDB的专门支持。

CockroachDB文档中有更多关于使用DBeaver的信息。

探索CockroachDB

现在我们已经可以访问一个CockroachDB集群,并且客户端也准备好连接了,让我们开始探索CockroachDB吧!在以下示例中,我们使用的是本地集群,如果你使用的是Cloud Basic实例,连接字符串可能会有所不同。

添加一些数据

正如澳大利亚人所说的,"没有数据的数据库就像没有啤酒的酒吧!"让我们向数据库中添加一些数据,这样我们就有东西可以查看了。

CockroachDB软件包括多个演示数据库,你可以快速将其添加到你的CockroachDB安装中。在某些情况下,这些数据库已经预填充了数据;在其他情况下,你需要先创建模式,然后再添加数据。

要初始化模式,我们使用 cockroach workload init [schema] 命令。要在该模式上运行负载,我们使用 cockroach workload run [schema] 命令。这些模式包括:

  • bank :模拟一组带有货币余额的账户。初始化模式后,使用 workload run 生成对数据库的负载。
  • intro:一个简单的单表数据库。
  • kv :一个简单的KV模式。初始化模式后,使用 run 来生成均匀分布在集群中的负载。
  • movr :一个虚构的共享出行应用程序的模式。这个模式可以与 workload run 命令一起使用,生成对数据库的负载。
  • startrek:一个Star Trek数据库,包含两个表:episodes和quotes。
  • tpcc :TPC-C标准基准的事务处理模式。这个模式可以与 workload run 命令一起使用,生成对数据库的负载。
  • ycsb :Yahoo Cloud Serving Benchmark模式。这个模式可以与 workload run 命令一起使用,生成对数据库的负载。

对于introstartrek 数据库,我们使用 workload init 命令创建表和数据。例如,在以下示例中,我们创建了 startrek 模式并查看了一些数据:

sql 复制代码
$ cockroach workload init startrek \
     'postgres://root@localhost:26257?sslmode=disable'
I210501 04:29:29.694340 1   imported episodes (0s, 79 rows)
I210501 04:29:29.898945 1   imported quotes (0s, 200 rows)

$ cockroach sql --insecure
#
# 欢迎使用CockroachDB SQL Shell。
# 所有语句必须以分号结尾。
# 要退出,请输入:\q。
#
#
# 输入 ? 查看简要介绍。
#
root@:26257/defaultdb> show databases;

  database_name | owner | primary_region | regions | survival_goal
----------------+-------+----------------+---------+----------------
  defaultdb     | root  | NULL           | {}      | NULL
  postgres      | root  | NULL           | {}      | NULL
  startrek      | root  | NULL           | {}      | NULL
  system        | node  | NULL           | {}      | NULL
(4 rows)

Time: 3ms total (execution 3ms / network 1ms)

root@:26257/defaultdb> use startrek;
SET

Time: 1ms total (execution 0ms / network 0ms)

root@:26257/startrek> show tables;

  schema_name | table_name | type  | owner | estimated_row_count | locality
--------------+------------+-------+-------+---------------------+-----------
  public      | episodes   | table | root  |                   0 | NULL
  public      | quotes     | table | root  |                   0 | NULL
(2 rows)

Time: 24ms total (execution 24ms / network 0ms)

root@:26257/startrek> select * from episodes limit 1;
  id | season | num |    title     | stardate
-----+--------+-----+--------------+-----------
   1 |      1 |   1 | The Man Trap |   1531.1
(1 row)

Time: 1ms total (execution 1ms / network 0ms)

在这个示例中,我们创建了 bank 模式:

shell 复制代码
$ cockroach workload init bank \
     'postgres://root@localhost:26257?sslmode=disable'
I210501 04:31:41.214008 1 imported bank (0s, 1000 rows)
I210501 04:31:41.221478 1 starting 9 splits

然后运行一个60秒的负载仿真:

css 复制代码
$ cockroach workload run bank 'postgres://root@localhost:26257?sslmode=disable' \
    --duration 60s
I210501 04:33:52.340852 1   creating load generator...
I210501 04:33:52.344074 1   creating load generator... done (took 3.220303ms)
_elapsed_ops/sec(inst)___ops/sec(cum)__p50(ms)__p95(ms)_pMax(ms)
    1.0s         187.3          187.9     16.8     48.2    121.6 transfer
    2.0s         295.0          241.5     11.0     31.5     79.7 transfer
    3.0s         260.9          248.0     13.1     37.7     83.9 transfer
    4.0s         203.1          236.7     17.8     39.8     79.7 <snip>

_elapsed____ops(total)___ops/sec(cum)__avg(ms)__p50(ms)__p99(ms)_pMax(ms
   60.0s         14230          237.2     16.9     13.6     65.0    192.9

run 命令主要用于生成负载测试数据,但也可以用来生成查询数据。

数据库和表

如我们所见,CockroachDB部署中的数据是按特定的命名空间(称为数据库)组织的。数据库是一个相当宽泛的术语,在CockroachDB中,数据库集群包含一个或多个数据库。在一个数据库内,可以定义一个或多个模式,尽管通常每个数据库只包含一个模式。

我们可以使用 show databases 命令列出集群中的数据库:

sql 复制代码
root@:26257/defaultdb> show databases;
  database_name | owner | primary_region | regions | survival_goal
----------------+-------+----------------+---------+----------------
  bank          | root  | NULL           | {}      | NULL
  defaultdb     | root  | NULL           | {}      | NULL
  postgres      | root  | NULL           | {}      | NULL
  startrek      | root  | NULL           | {}      | NULL
  system        | node  | NULL           | {}      | NULL
(5 rows)

我们可以使用 use 命令设置当前数据库:

makefile 复制代码
root@:26257/defaultdb> use startrek;
SET

Time: 1ms total (execution 0ms / network 0ms)

我们可以使用 show tables 命令列出数据库中的表:

sql 复制代码
root@:26257/startrek> show tables;
  schema_name | table_name | type  | owner | estimated_row_count | locality
--------------+------------+-------+-------+---------------------+-----------
  public      | episodes   | table | root  |                  79 | NULL
  public      | quotes     | table | root  |                 200 | NULL
(2 rows)

Time: 16ms total (execution 16ms / network 0ms)

我们可以使用 \d 命令描述表:

sql 复制代码
root@:26257/startrek> \d quotes;
  column_name | data_type | is_nullable | column_default |            indices
--------------+-----------+-------------+----------------+----------------------
  quote       | STRING    |    true     | NULL           |  {primary}
  characters  | STRING    |    true     | NULL           |  {primary}
  stardate    | DECIMAL   |    true     | NULL           |  {primary}
  episode     | INT8      |    true     | NULL           |  {primary,quotes_epis
  rowid       | INT8      |    false    | unique_rowid() |  {primary,quotes_epis
(5 rows)

Time: 13ms total (execution 12ms / network 1ms)

执行SQL

通过CockroachDB客户端,我们可以执行任何我们有权限执行的SQL命令。

在这里,我们连接到Star Trek示例数据库,并执行一个查询,找出引用最多的剧集:

sql 复制代码
root@localhost:26257/defaultdb> USE startrek;

SELECT id,
    title,
    count(*) AS quote_count
FROM episodes AS e
    LEFT OUTER JOIN quotes AS q ON (e.id = q.episode)
GROUP BY id,
    title
ORDER BY 3 DESC
LIMIT 10;
SET

Time: 1ms total (execution 0ms / network 1ms)

  id |              title              | quote_count
-----+---------------------------------+--------------
  53 | The Ultimate Computer           |          11
  77 | The Savage Curtain              |           9
  11 | The Menagerie, Part I           |           7
  38 | Metamorphosis                   |           7
  16 | The Galileo Seven               |           7
  28 | The City on the Edge of Forever |           6
  26 | Errand of Mercy                 |           6
  24 | This Side of Paradise           |           5
  23 | A Taste of Armageddon           |           5
  37 | I, Mudd                         |           5
(10 rows)

Time: 5ms total (execution 3ms / network 1ms)

数据库控制台

CockroachDB服务器提供了一个基于Web的客户端,显示集群的状态和有用的性能指标。Web服务器通常暴露在8080端口,但可以在启动服务器时通过 --http-addr 设置更改。

完整的数据库控制台可用于自托管和CockroachDB Cloud Advanced集群。CockroachDB Cloud Basic和Standard集群则使用简化版的控制台。

与编程语言一起工作

使用CockroachDB shell进行实验非常有用,但最终,大多数数据库会与用诸如JavaScript、Java、Go或Python等语言编写的应用代码进行交互。

由于CockroachDB与Postgres兼容,大多数Postgres兼容的驱动程序都可以与CockroachDB一起使用。事实上,市场上并没有特定于CockroachDB的驱动程序,因为Postgres驱动程序表现得非常好。在本节中,我们将带你了解如何在Java、Go、Python和JavaScript中编写"hello world"程序,连接并查询CockroachDB集群。完整的支持语言列表可以在CockroachDB的在线文档中找到。

从Node.js连接到CockroachDB

使用Node.js平台的服务器端JavaScript已成为应用开发中日益流行的选择,因为它允许在前端Web展示代码和服务器端应用逻辑中使用相同的JavaScript语言。

假设你已经安装了Node.js和Node包管理器(npm),我们将使用node-postgres驱动程序连接到CockroachDB。可以使用以下命令安装这个驱动程序:

复制代码
npm install pg

安装pg后,下面的示例应该可以使用连接URI连接到任何CockroachDB数据库:

arduino 复制代码
// 使用Node.js连接CockroachDB的示例

const CrClient = require('pg').Client; //加载pg客户端

async function main() {
    try {
        // 检查参数
        if (process.argv.length != 3) {
            console.log('Usage: node helloWorld.js CONNECTION_URI');
            process.exit(1);
        }
        // 使用命令行URI建立连接
        const connectionString = process.argv[2];
        const crClient = new CrClient(connectionString);
        await crClient.connect();

        // 执行SELECT查询
        const data = await crClient.query(
            `SELECT CONCAT('Hello from CockroachDB at ',
                            CAST (NOW() as STRING)) as hello`
        );
        // 打印出结果
        console.log(data.rows[0].hello);
    } catch (error) {
        console.log(error.stack);
    }
    // 退出
    process.exit(0);
}

main();

此程序期望连接字符串作为程序的第一个参数。process.argv数组包含完整的命令行,包括"node"和"helloWorld.js",因此URI实际上作为数组中的第三个元素。

然后,我们尝试使用该连接字符串建立连接,并执行一个SELECT语句,获取服务器已知的时间。

这里我们连接到一个CockroachDB Cloud Basic集群:

ini 复制代码
$ node helloWorld.js "postgresql://jesse:xxxxxxxxxxxx
aws-us-west-2.cockroachlabs.cloud:26257/defaultdb?
sslmode=verify-full&sslrootcert=$HOME/.postgresql/root.crt&
options=--cluster%3Dalert-dingo-2030"

Hello from CockroachDB at 2024-05-02 00:17:40.835834+00:00

在这里,我们连接到一个本地的CockroachDB,且运行在不安全模式下:

csharp 复制代码
$ node helloWorld.js 'postgres://root@localhost:26257?sslmode=disable'
Hello from CockroachDB at 2024-05-02 00:32:39.125419+00:00

从Java连接到CockroachDB

Java是各行各业和各种环境中数百万应用程序的主力军。在这个示例中,我们将使用官方的PostgreSQL Java数据库连接(JDBC)驱动程序连接到CockroachDB服务器。下载JDBC驱动程序并将其放置在类路径中,或者在你的IDE中将其配置为依赖项。

以下程序接受URL、用户名和密码作为命令行参数,连接到相关的CockroachDB集群,并执行一个SELECT语句:

ini 复制代码
package helloCRDB;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class HelloCRDB {
  public static void main(String[] args) {
      Connection cdb = null;
      try {
            Class.forName("org.postgresql.Driver");
            String connectionURL="jdbc:"+args[0];
            String userName=args[1];
            String passWord=args[2];

            cdb = DriverManager.getConnection(connectionURL,userName,passWord);
            Statement stmt = cdb.createStatement();
            ResultSet rs = stmt
                 .executeQuery("SELECT CONCAT('Hello from CockroachDB at',"
                            + "CAST (NOW() as STRING)) AS hello");
            rs.next();
            System.out.println(rs.getString("hello"));

      } catch (Exception e) {
            e.printStackTrace();
            System.err.println(e.getClass().getName() + ": " + e.getMessage());
            System.exit(0);
      }
  }
}

如果我们想连接到之前创建的CockroachDB Cloud Basic集群,可以执行以下命令:

ruby 复制代码
$ java -m helloCRDB/helloCRDB.HelloCRDB
 postgresql://gcp-asia-southeast1.cockroachlabs.cloud:26257/defaultdb
 ?sslmode=verify-full&sslrootcert=/Users/guyharrison/CockroachDBCockroachDBKeys/
cc-ca.crt&options=--cluster=grumpy-orca-56 \
 guy xxxxxxxxxxxx
csharp 复制代码
Hello from CockroachDB at 2024-05-05 15:39:07.667438+10:00

在这里,我们连接到一个本地的CockroachDB集群,且运行在不安全模式下:

bash 复制代码
$ java  -m helloCRDB/helloCRDB.HelloCRDB postgresql://localhost:26257/
?sslmode=disable root ''

Hello from CockroachDB at 2024-05-05 15:38:56.691009+10:00

从Python连接到CockroachDB

Python是一种广泛使用的脚本语言,也是许多数据科学家和数据处理专家的首选工具。在这个示例中,我们将使用psycopg Python-PostgreSQL包连接到CockroachDB。

要安装psycopg包,请执行以下命令:

ruby 复制代码
$ pip3 install psycopg2

安装过程如下:

yaml 复制代码
Collecting psycopg2
  Using cached psycopg2-2.8.6.tar.gz (383 kB)
Building wheels for collected packages: psycopg2
  Building wheel for psycopg2 (setup.py) ... done
  Created wheel for psycopg2: filename=psycopg2-2.8.6-cp39-...
  Stored in directory: /Users/guyharrison/Li...
Successfully built psycopg2
Installing collected packages: psycopg2
Successfully installed psycopg2-2.8.6

现在,以下简短的程序将使用命令行提供的URL连接到CockroachDB并执行SELECT语句:

python 复制代码
#!/usr/bin/env python3

import psycopg2
import sys

def main():

  if ((len(sys.argv)) !=2):
    sys.exit("Error:No URL provided on command line")
  uri=sys.argv[1]

  conn = psycopg2.connect(uri)
  with conn.cursor() as cur:
    cur.execute("""SELECT CONCAT('Hello from CockroachDB at ',
                   CAST (NOW() as STRING))""")
    data=cur.fetchone()
    print("%s" % data[0])

main()

在这个程序中,我们通过命令行参数提供连接字符串。sys.argv数组包含完整的命令行,包括"python"和"helloCockroachDB.py",因此URI实际上是数组中的第三个元素。

我们尝试使用该连接字符串建立连接,并执行一个SELECT语句,获取服务器已知的时间。

以下是连接到我们之前创建的CockroachDB Cloud Basic集群的示例:

ini 复制代码
$ python helloCockroachDB.py \
 'postgres://guy:xxxxxx@gcp-asia-
southeast1.cockroachlabs.cloud:26257/defaultdb?sslmode=verify-
full&sslrootcert=/Users/guyharrison/CockroachDBCockroachDBKeys/
cc-ca.crt&options=--cluster%3dgrumpy-orca-56'

Hello from CockroachDB at 2024-05-02 02:39:55.859734+00:00

这里我们连接到一个本地的CockroachDB集群,且运行在不安全模式下:

csharp 复制代码
$ python helloCockroachDB.py 'postgres://root@localhost:26257?sslmode=disable'
Hello from CockroachDB at 2024-05-02 02:33:00.755359+00:00

从Go连接到CockroachDB

Go语言是增长最快的编程语言之一,提供了高性能、现代编程范式和较低的资源占用。CockroachDB平台的大部分代码是用Go编写的,因此Go是进行CockroachDB开发的一个绝佳选择。

在这个示例中,我们将使用pgx PostgreSQL驱动程序连接到我们之前创建的CockroachDB Cloud Basic集群。首先,我们需要安装该驱动程序:

shell 复制代码
$ go get github.com/jackc/pgx/v5

以下是一个简单的程序,它使用命令行提供的URL连接到CockroachDB,并执行一个SELECT语句:

go 复制代码
package main

import (
	"context"
	"fmt"
	"os"
	"github.com/jackc/pgx/v5"
)

func main() {
	uri := "postgresql://root@localhost:26257/bank?ssl=disabled"
	conn, err := pgx.Connect(context.Background(), uri)
	if err != nil {
		fmt.Fprintf(os.Stderr,
			"Unable to connect to database: %v\n", err)
		os.Exit(1)
	}
	var text string
	err = conn.QueryRow(context.Background(),
		`SELECT CONCAT('Hello from CockroachDB at ',
		     CAST (NOW() as STRING))`).Scan(&text)
	if err != nil {
		fmt.Fprintf(os.Stderr, "QueryRow failed: %v\n", err)
		os.Exit(1)
	}

	fmt.Println(text)
}

这里,我们连接到一个CockroachDB Cloud Basic集群:

ini 复制代码
$ go run helloCockroachDB.go \
  "postgres://guy:xxxxxxx@gcp-asia-
southeast1.cockroachlabs.cloud:26257/defaultdb?sslmode=verify-
full&sslrootcert=$HOME/CockroachDBCockroachDBKeys/
cc-ca.crt&options=--cluster=grumpy-orca-56"

Hello from CockroachDB at 2024-05-02 02:24:13.930662+00:00

然后,我们运行程序以连接到一个本地的CockroachDB集群,且运行在不安全模式下:

go 复制代码
$ go run helloCockroach.go 'postgres://root@localhost:26257?sslmode=disable'
Hello from CockroachDB at 2024-05-02 02:21:59.179171+00:00

总结

在本章中,我们展示了如何在本地计算机上安装CockroachDB软件,如何在不同配置下创建CockroachDB集群,以及如何通过命令行或编程语言与CockroachDB进行交互。

在桌面上安装CockroachDB软件非常容易,在大多数情况下,如果你想通过命令行与CockroachDB服务器进行交互,这是必要的。你还可以通过Docker或Kubernetes安装CockroachDB软件。

虽然单节点测试服务器对于学习CockroachDB是一个有用的工具,但CockroachDB Cloud Basic计划提供了一个免费的10 GiB服务器,并提供备份和安全功能。你还可以在Kubernetes集群中安装CockroachDB,在本地环境中实验完整的集群。

由于CockroachDB与PostgreSQL兼容,你可以使用任何Postgres兼容的驱动程序连接到CockroachDB。我们还提供了使用Java、Python、Go和Node.js的PostgreSQL驱动程序连接到CockroachDB的简单示例。

在下一章,我们将深入讲解SQL,涵盖你在与CockroachDB交互时最常用的SQL语句。

相关推荐
oydcm16 分钟前
MySQL数据库概述
数据库·mysql
oioihoii26 分钟前
C++23中if consteval / if not consteval (P1938R3) 详解
java·数据库·c++23
带娃的IT创业者30 分钟前
《AI大模型趣味实战》基于RAG向量数据库的知识库AI问答助手设计与实现
数据库·人工智能
Java技术小馆1 小时前
SpringBoot中暗藏的设计模式
java·面试·架构
husterlichf2 小时前
MYSQL 常用数值函数 和 条件函数 详解
数据库·sql·mysql
我的golang之路果然有问题2 小时前
快速了解redis,个人笔记
数据库·经验分享·redis·笔记·学习·缓存·内存
Lei活在当下2 小时前
【现代 Android APP 架构】01. APP 架构综述
android·设计模式·架构
躺不平的理查德2 小时前
General Spark Operations(Spark 基础操作)
大数据·分布式·spark
talle20212 小时前
Zeppelin在spark环境导出dataframe
大数据·分布式·spark
卡皮巴拉爱吃小蛋糕2 小时前
MySQL的MVCC【学习笔记】
数据库·笔记·mysql