MatrixKV初体验
前言
周末抽空参与了MatrixKV的体验活动,最近也想了解状态复制机相关的知识和实践。通过体验MatrixKV的功能,加深了自己对相关知识的理解。下述是个人整理的整个体验流程的小白实践。
MatrixKV是一个简单的分布式强一致KV存储系统,采用Pebble作为底层的存储引擎,MatrixCube作为分布式组件,以及自定义了最简单的读写请求接口。用户可以非常简单的在任意一个节点发起读写数据的请求,也可以从任意一个节点读到需要的数据。
本次体验以Docker模拟一个小型MatrixKV集群的形式,来进一步体验MatrixCube的功能与运作机制。
Step 1: 环境准备
机器准备
机器数量: 1台
OS: centos7.6
free memory: 12G
docker: Docker version 20.10.14
docker-compose: docker-compose version 1.29.2
go : 1.18.3
语言环境
该实验需要依赖GO 的语言环境,因此我们需要在对应机器上提前安装好GO的环境。
下载GO安装包
-
在线下载
## 安装wget 已有可以忽略 [root@hadp01 data]# yum install -y wget ## 获取安装包 [root@hadp01 data]# wget https://studygolang.com/dl/golang/go1.18.3.linux-amd64.tar.gz
-
离线下载
下载网址: https://studygolang.com/dl (go语言中文网)
下载对应版本即可
上传至服务器
安装并配置GO语言环境
-
解压安装包
[root@hadp01 data]# tar -C /usr/local -zxf ./go1.18.3.linux-amd64.tar.gz
-
配置环境变量
## 编辑配置文件 [root@hadp01 data]# vi /etc/profile ## 增加以下内容至文件末尾 export GOROOT=/usr/local/go export PATH=$PATH:$GOROOT/bin ## source 配置文件 [root@hadp01 data]# source /etc/profile
-
验证go环境
[root@hadp01 data]# go version ## 出现以下版本信息即可 go version go1.18.3 linux/amd64
网络环境
增加go中国源站
[root@hadp01 data]# go env -w GOPROXY=https://goproxy.cn,direct
Step 2: 集群配置准备
前置条件
下载代码
[root@hadp01 data]# git clone https://github.com/matrixorigin/matrixkv
编译环境准备
[root@hadp01 data]# go mod vendor
集群配置
端口配置
端口配置是docker将服务暴露的端口默认是8080,如果机器部署有其他服务,会因为该端口被占用导致集群启动失败,因此,在端口被占用的情况下,需要调整端口,以便集群部署成功。如不确定端口是否被占用,可以修改一个不常见的端口,作为服务的暴露端口。如下,我选择的是修改为8079
## 进入到代码目录
[root@hadp01 data]# cd matrixkv
## 修改配置文件
[root@hadp01 data]# vi docker-compose.yml
version: '2.1'
services:
node0:
image: matrixkv
ports:
## 将此处原本的端口映射修改。如原本是将容器的8080映射到物理机的8080,我此处修改为8079到8079。
- "8079:8079"
volumes:
- ./cfg/node0.toml:/etc/cube.toml
- /data/node0:/data/matrixkv
command:
## 此处也要修改为8079
- --addr=node0:8079
- --cfg=/etc/cube.toml
# shard will split after 1024 bytes
- --shard-capacity=1024
node1:
image: matrixkv
ports:
## 此处也要修改为8079
- "8081:8079"
volumes:
- ./cfg/node1.toml:/etc/cube.toml
- /data/node1:/data/matrixkv
command:
## 此处也要修改为8079
- --addr=node1:8079
- --cfg=/etc/cube.toml
# shard will split after 1024 bytes
- --shard-capacity=1024
depends_on:
- node0
node2:
image: matrixkv
ports:
## 此处也要修改为8079
- "8082:8079"
volumes:
- ./cfg/node2.toml:/etc/cube.toml
- /data/node2:/data/matrixkv
command:
## 此处也要修改为8079
- --addr=node2:8079
- --cfg=/etc/cube.toml
# shard will split after 1024 bytes
- --shard-capacity=1024
depends_on:
- node1
node3:
image: matrixkv
ports:
## 此处也要修改为8079
- "8083:8079"
volumes:
- ./cfg/node3.toml:/etc/cube.toml
- /data/node3:/data/matrixkv
command:
## 此处也要修改为8079
- --addr=node3:8079
- --cfg=/etc/cube.toml
# shard will split after 1024 bytes
- --shard-capacity=1024
depends_on:
- node0
- node1
- node2
节点配置
在/cfg文件夹中有node0-node3的配置文件,其中Node0-Node2均为Prophet节点,Node3为数据节点。Prophet节点的配置以Node0举例如下如下:
#raft-group的RPC通信地址,节点之间通过这个地址来发送raft message和snapshot。
addr-raft = "node0:8081"
#对客户端开放的地址,客户通过这个端口和cube来交互自定义的业务请求。
addr-client = "node0:8082"
#Cube的数据存放目录,每个节点会根据这个目录所在的磁盘统计存储的使用情况,上报给调度节点。
dir-data = "/tmp/matrixkv"
[raft]
#Cube会对Raft的写请求做batch,会把多个写请求合并到一个Raft-Log,只做一次Raft的Proposal,这个配置指定一个Proposal的大小,这个 #配置取决于应用的具体情况
max-entry-bytes = "200MB"
[replication]
# 1. 一个raft-group的副本最大的down time,当一个副本的down time超过这个值,调度节点就会认为这个副本用久的故障了,
# 然后会在集群中选择一个合适的节点来重新创建这个副本。如果后面这个节点又重新启动了,那么调度节点会通知这个副本
# 销毁自己。
# 2. 这里的默认设置一般是30分钟,这个时间我们认为是设备一般出现故障可以在30分钟内完成故障处理恢复,如果超过这个时间说明已经无法 # 恢复。在这里我们为了做实验的方便,设置成15秒。
max-peer-down-time = "15s"
[prophet]
#该Prophet调度节点的名称
name = "node0"
#该Prophet调度节点对外的RPC地址
rpc-addr = "node0:8083"
#指定该节点为Prophet节点
prophet-node = true
[prophet.schedule]
# Cube集群中的所有节点都会定期发送心跳到调度的Leader节点,当一个节点超过一定的时间都没有发送心跳,
# 那么调度节点会把这个节点的状态修改为Down,并且会把这个节点上,所有的Shard在集群其他节点来重建,
# 当这个节点恢复后,这个节点上的所有Shard都会收到销毁的调度消息。
# 这里也是为了实验方便设置成10秒,默认也是30分钟。
max-container-down-time = "10s"
#Prophet中内嵌一个ETCD作为存储元数据的组件
[prophet.embed-etcd]
#Cube的Prophet调度节点会先后启动, 假设我们有node0, node1, node2三个调度节点, 第一个启动的是node0节点, 那么node0节点就会
#组成一个只有一个副本的etcd, 对于node0而言, `join`参数不需要填写, 后面的node1, node1启动的时候, `join`设置为node1
#的Etcd的Peer address
join = ""
#内嵌Etcd的client address
client-urls = "http://0.0.0.0:8084"
#内嵌Etcd的advertise client address, 不填写, 默认和`client-urls`一致
advertise-client-urls = "http://node0:8084"
#内嵌Etcd的peer address
peer-urls = "http://0.0.0.0:8085"
#内嵌Etcd的advertise peer address, 不填写, 默认和`peer-urls`一致
advertise-peer-urls = "http://node0:8085"
[prophet.replication]
#每个Shard最多多少个副本,当Cube的调度节点周期性巡检的时候,发现Shard的副本个数和这个值不匹配的时候,会执行创建副本或者删除副本的调#度操作。
max-replicas = 3
Step 3: 集群部署启动
镜像打包
执行打包命令
[root@hadp01 data]# make docker
打包成功后执行 docker images 命令会发现有 matrixkv 相关的镜像
创建节点数据目录
需要根据配置文件数据目录配置创建,如无特殊要求,可以使用此默认配置
[root@hadp01 data]# mkdir -p /data/node0
[root@hadp01 data]# mkdir -p /data/node1
[root@hadp01 data]# mkdir -p /data/node2
[root@hadp01 data]# mkdir -p /data/node3
服务启动
[root@hadp01 data]# docker-compose up
出现以下日志服务启动成功
Starting matrixkv_node0_1 ... done
Starting matrixkv_node1_1 ... done
Starting matrixkv_node2_1 ... done
Starting matrixkv_node3_1 ... done
同时我们去到对应的目录能发现数据目录已经创建完成
[root@hadp01 data]# cd /data
[root@hadp01 data]# ll
drwxr-xr-x. 6 root root 66 7月 9 14:08 node0
drwxr-xr-x. 6 root root 66 7月 9 14:08 node1
drwxr-xr-x. 5 root root 49 7月 9 14:08 node2
drwxr-xr-x. 5 root root 51 7月 9 14:08 node3
[root@hadp01 data]# cd node0
[root@hadp01 data]# ll
drwxr-xr-x. 2 root root 114 7月 9 14:49 kv-data
drwxr-xr-x. 2 root root 114 7月 9 14:49 logdb
drwx------. 3 root root 20 7月 9 14:49 prophet
drwxr-x---. 3 root root 31 7月 9 14:08 snapshots
Step 4: 测试集群功能
读写请求
-
数据写入SET
[root@hadp01 data]# curl -X POST -H 'Content-Type: application/json' -d '{"key":"k1","value":"v1"}' http://127.0.0.1:8079/set
返回示例
{"key":"k1","error":""}
-
数据读取SET
[root@hadp01 data]# curl http://127.0.0.1:8079/get?key=k1
返回示例,能够正确获取到 k1 的值 v1
{"key":"k1","value":"v1","error":""}
-
数据删除SET
[root@hadp01 data]# curl -X POST -H 'Content-Type: application/json' -d '{"key":"k1"}' http://127.0.0.1:8079/delete
返回示例
{"key":"k1","error":""}
此时,再获取 k1的值,已经无法获取到对应的 v1
{"key":"k1","value":"","error":""}
{"key":"k1","value":"","error":""}
同时,我们使用其他节点进行数据的增删查都是可以的
## 使用8081 (node1) 插入数据 [root@hadp01 data]# curl -X POST -H 'Content-Type: application/json' -d '{"key":"name1","value":"tom"}' http://127.0.0.1:8081/set {"key":"name1","error":""} ## 使用8082 (node2) 读取数据 [root@hadp01 data]# curl http://127.0.0.1:8082/get?key=name1 {"key":"name1","value":"tom","error":""} ## 使用8083 (node3) 删除数据 [root@hadp01 data]# curl -X POST -H 'Content-Type: application/json' -d '{"key":"name1"}' http://127.0.0.1:8083/delete {"key":"name1","error":""} ## 此时使用8079 (node0) 读取数据 {"key":"name1","value":"","error":""}
数据分片查询与分裂
MatrixCube会在写入的数据量达到一定级别的时候产生Shard分裂,在MatrixKV中,我们将Shard的大小设置成了1024Byte。因此写入数据超过这个尺寸的数据会产生分裂。MatrixKV提供了一个简单的查询当前集群或者当前节点中有多少个Shard的接口。
-
分片查询
#当前集群中的Shard情况 [root@hadp01 data]# curl http://127.0.0.1:8079/shards [{"id":2,"epoch":{"configVer":5,"generation":1},"replicas":[{"id":3,"storeID":1,"initialMember":true},{"id":7,"storeID":6},{"id":8,"storeID":5}],"labels":null}]
此时能看见有 id为 3,7,8三个Shard
-
分裂
写入一个超过1024Byte的数据之后
[root@hadp01 data]# curl -X POST -H 'Content-Type: application/json' -d@test.json http://127.0.0.1:8083/set
查询分片
[root@hadp01 data]# curl http://127.0.0.1:8079/shards
节点变化与副本生成
-
节点变化
查看节点
[root@hadp01 matrixkv]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7805963d7296 matrixkv "/usr/local/bin/matr…" About an hour ago Up 39 minutes 0.0.0.0:8083->8079/tcp, :::8083->8079/tcp matrixkv_node3_1 2ed005fb0dfa matrixkv "/usr/local/bin/matr…" About an hour ago Up 39 minutes 0.0.0.0:8082->8079/tcp, :::8082->8079/tcp matrixkv_node2_1 8c2ffd817aa4 matrixkv "/usr/local/bin/matr…" About an hour ago Up 39 minutes 0.0.0.0:8081->8079/tcp, :::8081->8079/tcp matrixkv_node1_1 c05960e6f746 matrixkv "/usr/local/bin/matr…" About an hour ago Up 39 minutes 0.0.0.0:8079->8079/tcp, :::8079->8079/tcp matrixkv_node0_1
关闭node3
[root@hadp01 matrixkv]# docker stop matrixkv_node3_1 matrixkv_node3_1
查询数据
[root@hadp01 matrixkv]# curl http://127.0.0.1:8083/get?key=name1 curl: (7) Failed connect to 127.0.0.1:8083; 拒绝连接 [root@hadp01 matrixkv]# curl http://127.0.0.1:8079/get?key=name1 {"key":"name1","value":"","error":""}
体验感受
接触MatrixOne是通过DataFun了解到的,通过了解官网及相关技术文档之后,觉得这个用Go编写的htap数据引擎很有意思,紧接着就体验了matrixKV,体验下来觉得很有丝滑感,同时MO社区文化很好。希望未来MO相关的产品会越来越完善,越来越好。