首页 > 数据库 > 国内数据库 > KWDB数据库高可用方案验证与测试
作者:wangzongyu
原文链接:https://blog.csdn.net/wangzongyu/article/details/147168082
KWDB作为面向AIoT场景的新一代分布式多模数据库,提供了丰富的功能。 支持同一实例同时建立时序库和关系库并融合处理多模数据。
默认情况下,KWDB多副本集群支持高可用,能够实现故障转移和数据强一致性。集群中的各节点通过定期的心跳机制来维护连接和状态,以便及时发现故障并采取相应措施。本文将详细测试KWDB多副本集群的高可用方案。
root@
kwdb1:~
/kwdb_install# kwbase sql --host=10.1.248.95:26257 --certs-dir=/etc/kaiwudb/certs/ --user=wangzy
#
#
Welcome to the
KWDB
SQL shell.
#
All statements must be terminated by a semicolon.
#
To exit,
type: \q.
#
Enter
password:
#
Server
version:
KaiwuDB
2.2
.0 (x86_64-linux-gnu, built
2025/
03/
31
07:
20:
47, go1
.16
.15, gcc
9.4
.0) (same version
as client)
#
Cluster
ID: 65071f3e-f4a4-
48e4-9a4e-953f772bf661
#
#
Enter \?
for a brief introduction.
#
wangzy@
10.1
.248
.95:
26257/defaultdb> show users;
username | options | member_of
-----------+------------+------------
admin |
CREATEROLE | {}
root |
CREATEROLE | {admin}
wangzy | | {admin}
(
3 rows)
Time:
14.638175ms
wangzy@
10.1
.248
.95:
26257/defaultdb>
CREATE
TS
DATABASE ts_db
RETENTIONS 10d
PARTITION
INTERVAL 2d;
wangzy@
10.1
.248
.95:
26257/defaultdb>
SHOW
CREATE
DATABASE ts_db;
database_name | create_statement
----------------+------------------------------
ts_db |
CREATE
TS
DATABASE ts_db
| retentions 864000s
| partition interval 2d
(
1 row)
wangzy@
10.1
.248
.95:
26257/defaultdb> use ts_db;
创建t1时序表并写入数据:
use ts_db;
CREATE
TABLE ts_db.
t1(ts timestamp not
null,a int, b int)
tags(tag1 int not
null, tag2 int) primary
tags(tag1);
向表中写入数据,并查看表中的数据:
INSERT
INTO ts_db.
t1
VALUES(
now(),
11,
11,
33,
44);
INSERT
INTO ts_db.
t1
VALUES(
now(),
22,
22,
33,
44);
INSERT
INTO ts_db.
t1
VALUES(
now(),
11,
33,
33,
44);
INSERT
INTO ts_db.
t1
VALUES(
now(),
22,
44,
33,
44);
INSERT
INTO ts_db.
t1
VALUES(
now(),
33,
55,
44,
44);
INSERT
INTO ts_db.
t1
VALUES(
now(),
22,
44,
44,
44);
INSERT
INTO ts_db.
t1
VALUES(
now(),
33,
44,
55,
44);
INSERT
INTO ts_db.
t1
VALUES(
now(),
null,
null,
66,
66);
INSERT
INTO ts_db.
t1
VALUES(
now(),
null,
null,
66,
77);
SELECT *
FROM t1;
ts | a | b | tag1 | tag2
--------------------------------+------+------+------+-------
2025-
04-
14
02:
39:
40.34+
00:
00 |
NULL |
NULL |
66 |
66
2025-
04-
14
02:
39:
42.398+
00:
00 |
NULL |
NULL |
66 |
66
2025-
04-
14
02:
39:
40.336+
00:
00 |
33 |
44 |
55 |
44
2025-
04-
14
02:
39:
40.327+
00:
00 |
33 |
55 |
44 |
44
2025-
04-
14
02:
39:
40.332+
00:
00 |
22 |
44 |
44 |
44
2025-
04-
14
02:
39:
40.304+
00:
00 |
11 |
11 |
33 |
44
2025-
04-
14
02:
39:
40.314+
00:
00 |
22 |
22 |
33 |
44
2025-
04-
14
02:
39:
40.319+
00:
00 |
11 |
33 |
33 |
44
2025-
04-
14
02:
39:
40.323+
00:
00 |
22 |
44 |
33 |
44
(
9 rows)
wangzy@
10.1
.248
.95:
26257/ts_db>
CREATE
DATABASE reldb1
WITH
ENCODING =
'UTF8';
wangzy@
10.1
.248
.95:
26257/ts_db> use reldb1;
创建accounts表:
CREATE TABLE reldb1.accounts(id INT8 DEFAULT unique_rowid() PRIMARY KEY, name STRING, balance DECIMAL, enabled BOOL);
写入数据:
INSERT INTO accounts VALUES (1, 'lily', 10000.5, true), (2, 'ruarc', 20000.75, true), (3, 'tullia', 30000, false), (4, 'arturo', 45000, false);
SELECT *
FROM accounts;
id | name | balance | enabled
-----+--------+----------+----------
1 | lily |
10000.5 |
true
2 | ruarc |
20000.75 |
true
3 | tullia |
30000 |
false
4 | arturo |
45000 |
false
(
4 rows)
提前备份数据,防止后续的验证中造成数据丢失,生产环境中也要定期进行数据备份
KWDB支持通过数据导入、导出的方式进行数据库库级别和表级别的数据备份。KWDB支持一次性导出指定数据库中所有表的元数据、用户数据和权限信息。当然也可以导出指定的表,因为我的目的是对数据库进行下备份,防止后面测试过程中数据丢失。便于恢复,本次我就导出库的全部表数据。在生产环境也要定时对数据库进行备份。
■ 将时序数据库的用户数据和元数据导出到本地节点,当然也可以导出到指定的服务器:
wangzy@
10.1
.248
.95:
26257/reldb1>
EXPORT
INTO
CSV
"nodelocal://1/ts_db"
FROM
DATABASE ts_db;
result
-----------
succeed
(
1 row)
Time:
573.496633ms
导出的时序表位于public 模式下。每张表是一个单独的目录,用于存放该表的用户数据(.csv 文件)。导出的时序数据库数据组织形式如下所示:
root@
kwdb1:
/data/kaiwudb/extern# pwd
/data/kaiwudb/extern/ts_db
root@
kwdb1:
/data/kaiwudb/extern/ts_db# tree
.
├── meta.
sql
└── public
└── t1
└── n2
.0.
csv
2 directories,
2 files
■ 将关系数据库的用户数据和元数据导出到本地节点,当然也可以导出到指定的服务器:
wangzy@
10.1
.248
.95:
26257/reldb1>
EXPORT
INTO
CSV
"nodelocal://1/rdb"
FROM
DATABASE reldb1;
filename | rows | node_id | file_num
-------------------------------+------+---------+-----------
TABLE reldb1.
public.
accounts |
4 |
2 |
1
meta.
sql |
1 |
1 |
1
(
2 rows)
Time:
588.889273ms
导出的关系表按其所在模式进行组织。每张表是一个单独的目录,用于存放该表的元数据信息(meta.sql)和用户数据(.csv 文件)。导出的关系库数据组织形式如下所示:
root@
kwdb1:
/data/kaiwudb/extern/rdb# pwd
/data/kaiwudb/extern/rdb
root@
kwdb1:
/data/kaiwudb/extern/rdb# tree
.
├── meta.
sql
└── public
└── accounts
├── meta.
sql
└── n2
.0.
csv
2 directories,
3 files
KWDB多副本集群默认采用3副本机制。为了确保系统在节点发生故障后仍能够提供服务,集群通过多数投票机制保证数据一致性和可用性,因此至少需要2个副本保持可用状态。
前面已经搭建了一个3节点的集群,接下来以3节点集群为例,说明KWDB多副本集群如何实现高可用性。
● 正常运行的情况:KWDB集群启动后,副本和leaseholder均匀分布在所有节点上,确保数据的高可用性和平衡性
看一下目前集群的状态情况:
● 单节点异常情况(非故障):如果单个节点因网络断开、延迟、操作系统故障、磁盘故障等原因导致节点状态变为异常(is_available 和is_live均为 false),系统会开始迁移该节点的leaseholder,迁移期间数据查询和 DML 操作可能受影响,DDL 操作可能会报错,生命周期会顺延至下一执行周期执行。待节点恢复为可用状态后恢复正常。
将NODE3(kwdb3)节点的kaiwudb服务关停,模拟节点出现异常:
root@kwdb3:~# systemctl stop kaiwudb
查看集群状态NODE3(kwdb3)的is_available变为false,is_live状态变为false:
验证服务写入和查询无影响:
wangzy@
10.1
.248
.95:
26257/reldb1>
INSERT
INTO accounts
VALUES (
5,
'wangzy',
90000.9,
true);
INSERT
1
Time:
2.979627ms
wangzy@
10.1
.248
.95:
26257/reldb1>
SELECT *
FROM accounts;
id | name | balance | enabled
-----+--------+----------+----------
1 | lily |
10000.5 |
true
2 | ruarc |
20000.75 |
true
3 | tullia |
30000 |
false
4 | arturo |
45000 |
false
5 | wangzy |
90000.9 |
true
(
5 rows)
Time:
2.782496ms
● 单节点故障情况:节点离线时间达到设定值后,系统会将该节点标记为不可用。如果剩余节点数量仍大于副本数,系统自动补足缺失的副本,确保数据的高可用性、副本补足期间,数据查询不受影响,DML操作不受影响,DDL操作可能会报错,副本补足后,DDL操作恢复正常。
先将NODE3(kwdb3)节点的kaiwudb服务启动,恢复集群状态为正常:
接下来模拟将NODE3(kwdb3)节点直接关机:
root@kwdb3:~# shutdown -h now
查看集群状态,由于系统检测到故障节点后会开始迁移该节点的leaseholder,迁移期间数据查询和 DML 操作可能受影响,所以会卡顿一下。
但是查询依然没有受到影响:
wangzy@
10.1
.248
.95:
26257/reldb1>
INSERT
INTO accounts
VALUES (
6,
'wangzongyu',
8800,
true);
wangzy@
10.1
.248
.95:
26257/reldb1>
SELECT *
FROM accounts;
id | name | balance | enabled
-----+------------+----------+----------
1 | lily |
10000.5 |
true
2 | ruarc |
20000.75 |
true
3 | tullia |
30000 |
false
4 | arturo |
45000 |
false
5 | wangzy |
90000.9 |
true
6 | wangzongyu |
8800 |
true
(
6 rows)
Time:
3.737195ms
● 节点恢复情况:不可用节点恢复后,系统会将副本和leaseholder 回迁到该节点,迁移期间数据查询和DML操作可能受影响,DDL操作可能会报错,生命周期会顺延至下一执行周期执行。待节点恢复为可用状态后恢复正常。
集群恢复到正常状态:
● 多节点故障情况:如果两个或更多节点出现故障,由于剩余节点数小于或等于副本数,系统无法补足缺失的副本,可能导致部分数据无法访问,甚至出现集群无法使用的情况。
root@
kwdb2:~# shutdown -h now
root@
kwdb3:~# shutdown -h now
root@
kwdb1:~
/kwdb_install# ./deploy.
sh cluster --status
ERROR: cannot dial server.
Is the server running?
If the server is running, check --host client-side and --advertise server-side.
read tcp
127.0
.0
.1:
1730->
127.0
.0
.1:
26257: i/o timeout
Failed running
"node status"
当两个节点故障后,KWDB集群将无法再使用。
集群节点多次发生故障后重新加入,可能会导致数据写入缓慢。而且集群节点故障或故障节点恢复后的 leaseholder 迁移可能导致读写短暂不可用或卡顿。
故障节点标记:
默认情况下,如果一个节点在集群中离线时间超过30分钟,系统会将其标记为不可用,并将该节点上的数据副本重新分配到其他节点,以确保数据的可用性和一致性。(比如5个节点至少2副本的情况,当一台节点故障,这个节点上的副本会重新分配到其他节点)
用户也可以通过以下SQL命令设置节点死亡时间:
SET CLUSTER SETTING server.time_until_store_dead = <value>; // 设置时间建议不小于75s
延长节点死亡判定时间,可以减少节点故障对集群性能的长时间影响,但可能会影响集群的高可用性功能和DDL相关操作。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70027415/viewspace-3090022/ ,如需转载,请注明出处,否则将追究法律责任。