CockroachDB提供了一系列的功能,旨在让你的应用程序在多个地区都能轻松支持。在CockroachDB 20.1中,我们引入了一个新的功能--在线主键变更,允许你在零停机的情况下将你的应用从单区域升级到多区域。我们最近写了一些关于构建在线主键变化的技术挑战,在这篇博文中,我们将介绍一些使用案例和该功能带来的好处。
一个快速的例子
首先,使用你喜欢的方法下载CockroachDB 20.1,包括Linux、Mac或Windows的二进制文件、Docker镜像,或者直接从源码构建。
这个例子将集中在虚构的共享汽车公司MovR上,我们之前在介绍横向连接的时候已经写过。MovR是一家在全球多个城市运营的共享汽车公司。我们已经在这篇多地区的博文中详细探讨了它的模式。你也可以使用我们最近在博客中提到的新的CockroachDB演示功能,在不到5分钟的时间内尝试一下。
要使用CockroachDB演示(以及带有预填充数据的更复杂的Rides表),请输入以下命令。
./cockroach demo
这个命令将自动加载MovR表和数据。
show tables;
table_name
+----------------------------+
promo_codes
rides
user_promo_codes
users
vehicle_location_histories
vehicles
(6 rows)
你可以看到这个骑行表已经为多区域做了很好的设置,因为它有一个复合主键,把区域放在id前面。
show create table rides;
table_name | create_statement
-------------+----------------------------------------------------------------------------------------------------------------------------------
rides | CREATE TABLE rides (
| id UUID NOT NULL,
| city VARCHAR NOT NULL,
| vehicle_city VARCHAR NULL,
| rider_id UUID NULL,
| vehicle_id UUID NULL,
| start_address VARCHAR NULL,
| end_address VARCHAR NULL,
| start_time TIMESTAMP NULL,
| end_time TIMESTAMP NULL,
| revenue DECIMAL(10,2) NULL,
| CONSTRAINT "primary" PRIMARY KEY (city ASC, id ASC),
| CONSTRAINT fk_city_ref_users FOREIGN KEY (city, rider_id) REFERENCES users(city, id),
| CONSTRAINT fk_vehicle_city_ref_vehicles FOREIGN KEY (vehicle_city, vehicle_id) REFERENCES vehicles(city, id),
| INDEX rides_auto_index_fk_city_ref_users (city ASC, rider_id ASC),
| INDEX rides_auto_index_fk_vehicle_city_ref_vehicles (vehicle_city ASC, vehicle_id ASC),
| FAMILY "primary" (id, city, vehicle_city, rider_id, vehicle_id, start_address, end_address, start_time, end_time, revenue),
| CONSTRAINT check_vehicle_city_city CHECK (vehicle_city = city)
| )
(1 row)
由于我们想展示从单地区到多地区的历程,我已经修改了骑行表,将城市从主键中删除(注意:如果你想使用现有的MovR骑行表,你也可以用ALTER TABLE rides ALTER PRIMARY KEY USING COLUMNS (id ASC); )。为了在家里跟上,我们将创建并使用一个新的数据库,然后创建一个新的骑行表,如下所示。
CREATE DATABASE movr_blog;
USE movr_blog;
CREATE TABLE rides (
id
UUID NOT NULL,
city
VARCHAR NOT NULL,
vehicle_city
VARCHAR NULL,
rider_id
UUID NULL,
vehicle_id
UUID NULL,
start_address
VARCHAR NULL,
end_address
VARCHAR NULL,
start_time
TIMESTAMP NULL,
end_time
TIMESTAMP NULL,
revenue
DECIMAL(10,2) NULL
);
现在,我们想改变这个主键,所以我们需要使用下面的 alter table 语句。
ALTER TABLE rides ALTER PRIMARY KEY USING COLUMNS (city ASC, id ASC);
NOTICE: primary key changes are finalized asynchronously; further schema changes on this table may be restricted until the job completes
ALTER TABLE
Time: 189.061ms
现在在这个例子中,我们没有指向集群的负载,也没有大量的数据需要改变,所以这是一个相对快速的操作。正如我们将在下面看到的,在线模式的改变被设计为对前台活动的影响最小,因为它不会锁定表供你的客户使用。
一个比较复杂的MovR例子
让我们展示一个更复杂的例子,考虑到整个MovR数据库。我们在这个GitHub 仓库中提供了整个 MovR 工作负载。
要设置这个例子,请确保你已经安装并运行了docker。
brew install docker
你还需要安装CockroachDB 20.1。
brew install cockroachdb
然后,在你的笔记本电脑上启动一个 cockroachdb 节点。
./cockroach start-single-node --insecure --host localhost --background
接下来,创建MovR数据库。
cockroach sql --insecure --host localhost -e "create database movr;"
现在,让我们为MovR数据库生成一些假数据。
docker run -it --rm cockroachdb/movr:movr-20.1-beta.20.4.1 --url "postgres://root@docker.for.mac.localhost:26257/movr?sslmode=disable" load --num-users 100 --num-rides 100 --num-vehicles 10
我们可以打开webui,在浏览器中直接访问localhost,看看发生了什么事。
http://localhost:8080/#/overview/list
我们甚至可以看到现有的表是什么样子的,比如说,骑手表。
http://localhost:8080/#/database/movr/table/rides
现在让我们把负载指向它。
docker run -it --rm cockroachdb/movr:movr-20.1-beta.20.4.2 --app-name "movr-loadgen" --url "postgres://root@docker.for.mac.localhost:26257/movr?sslmode=disable" run --multi-region
我们还可以在webui的metrics标签中看到这个负载。
http://localhost:8080/#/metrics/overview/cluster
现在,让我们把它升级为一个多区域集群。通常情况下,如果你是手工操作,你需要通过Docker运行以下命令。
docker run -it --rm cockroachdb/movr:movr-20.1-beta.20.4.1 --app-name "movr-loadgen" --url "postgres://root@docker.for.mac.localhost:26257/movr?sslmode=disable" configure-multi-region --preview-queries
[INFO] (MainThread) connected to movr database @ postgres://root@docker.for.mac.localhost:26257/movr?sslmode=disable
DDL to convert a single region database to multi-region
===primary key alters===
ALTER TABLE users ALTER PRIMARY KEY USING COLUMNS (city, id);
ALTER TABLE rides ALTER PRIMARY KEY USING COLUMNS (city, id);
ALTER TABLE vehicle_location_histories ALTER PRIMARY KEY USING COLUMNS (city, ride_id, timestamp);
ALTER TABLE vehicles ALTER PRIMARY KEY USING COLUMNS (city, id);
ALTER TABLE user_promo_codes ALTER PRIMARY KEY USING COLUMNS (city, user_id, code);
===foreign key alters===
DROP INDEX users_city_idx;
ALTER TABLE vehicles DROP CONSTRAINT fk_owner_id_ref_users;
CREATE INDEX ON vehicles (city, owner_id);
DROP INDEX vehicles_auto_index_fk_owner_id_ref_users;
DROP INDEX vehicles_city_idx;
ALTER TABLE vehicles ADD CONSTRAINT fk_owner_id_ref_users_mr FOREIGN KEY (city, owner_id) REFERENCES users (city,id);
ALTER TABLE rides DROP CONSTRAINT fk_rider_id_ref_users;
CREATE INDEX ON rides (city, rider_id);
ALTER TABLE rides ADD CONSTRAINT fk_rider_id_ref_users_mr FOREIGN KEY (city, rider_id) REFERENCES users (city,id);
ALTER TABLE rides DROP CONSTRAINT fk_vehicle_id_ref_vehicles;
CREATE INDEX ON rides (city, vehicle_id);
ALTER TABLE rides ADD CONSTRAINT fk_vehicle_id_ref_vehicles_mr FOREIGN KEY (city, vehicle_id) REFERENCES vehicles (city,id);
DROP INDEX rides_auto_index_fk_rider_id_ref_users;
DROP INDEX rides_auto_index_fk_vehicle_id_ref_vehicles;
ALTER TABLE user_promo_codes DROP CONSTRAINT fk_user_id_ref_users;
ALTER TABLE user_promo_codes ADD CONSTRAINT fk_user_id_ref_users_mr FOREIGN KEY (city, user_id) REFERENCES users (city,id);
我们已经编写了脚本,为你完成这些命令,所以你可以去掉--预览--查询来看到这个执行。
docker run -it --rm cockroachdb/movr:movr-20.1-beta.20.4.1 --app-name "movr-loadgen" --url "postgres://root@docker.for.mac.localhost:26257/movr?sslmode=disable" configure-multi-region
你可以在webui的job部分看到这些运行,或者通过运行show jobs
我们也可以在webui中或通过运行show create table rides 来验证这一点的发生。
这对集群有什么影响?
回到指标表中,我们可以看到,当模式变化生效时,p99的延迟只稍微上升了一点,但我们的吞吐量没有下降。
你可以增加集群的规模,增加工作负载,并在其他方面使用MovR来尝试CockroachDB!
为你的应用程序提供未来保障
你还在寻找CockroachDB使多区域部署变得简单的其他方法吗?我们之前报道了如何利用地理分区,通过跟随者读取减少多区域延迟,以及最近的《如何在CockroachDB上构建多区域应用》。
CockroachDB为开发者提供了强大的工具来创建多区域应用。但是你的应用不需要从一开始就为多区域而设计,我们也为你提供了工具,让你的应用从单区域发展到多区域。免费试用CockroachCloud 30天。