- 键值写入/读取/范围查找
- 名称空间隔离数据
- 支持设置键值过期时间
- 节点间数据保持强一致性
- 直接通过HTTP接口操作数据
- WS订阅监听某个/某批前缀相同的键值更新事件
- 数据读取:直接访问指定名称空间的LevelDB
- 数据写入:先将数据写入到Raft集群的日志中,再通过日志消费将数据同步进LevelDB中
- 订阅发布服务-事件广播:节点从Raft日志中同步数据时,会顺带将数据投放到通道中,然后广播推送给目前连接到该节点的特定订阅者客户端
- 过期键值清理:对过期键值有两种处理方式,第一种是在查询时检测并删除,第二种是后台任务定时批量扫描删除
- 数据读取:可在任意节点进行
- 数据写入:只能在领导者节点进行,如果在非领导者节点执行写入操作,会自动将该请求转发至当前集群的领导者节点执行
1
启动集群中的第一个节点时(或者单节点部署时),配置文件config.yaml中的node.first设为true,第一个节点默认为领导者节点2
启动集群中的第二、第三...乃至后续节点时,配置文件config.yaml中的node.first设为false3
在主节点(第一个启动的节点)上调用新建节点
接口,将后续启动的节点依此加入到第一个节点所在的集群中
go build main.go
POST
http://127.0.0.1:8000/v2/node 新建节点(必须在领导者节点上执行)
Body
{
"addr": "127.0.0.1",
"httpPort": 7000,
"tcpPort": 6999
}
httpPort:节点的http端口号,集群外部对节点的操作都通过http接口进行;tcpPort:节点的tcp端口号,供内部Raft集群调度使用
{
"code": 1000,
"data": "127.0.0.1:7000"
}
data:节点的外部操作地址(http地址)
DELETE
http://127.0.0.1:8000/v2/node/{endpoint} 删除节点(必须在领导者节点上执行)
URI
endpoint = 127.0.0.1:7000
endpoint:节点的外部操作地址(http地址)
{
"code": 1000
}
GET
http://127.0.0.1:8000/v2/nodes 获取节点列表
{
"code": 1000,
"data": [
{
"endpoint": "127.0.0.1:8000",
"health": true,
"leader": true
},
{
"endpoint": "127.0.0.1:7000",
"health": true,
"leader": false
}
]
}
health:是否健康;leader:是否是领导者节点
GET
http://127.0.0.1:8000/v2/leader 获取领导者节点
{
"code": 1000,
"data": "127.0.0.1:8000"
}
GET
http://127.0.0.1:8000/v2/config 获取当前节点配置(内部调用)
{
"node": {
"first": true,
"addr": "127.0.0.1",
"tcpPort": 7999,
"httpPort": 8000
},
"store": {
"data": "./data",
"log": "./log"
}
}
GET
http://127.0.0.1:8000/v2/health 获取当前节点健康状态(内部调用)
1
POST
http://127.0.0.1:8000/v2/namespace/{namespace} 新建名称空间
URI
namespace = dev
{
"code": 1000
}
namespace:名称空间
DELETE
http://127.0.0.1:8000/v2/namespace/{namespace} 删除名称空间
URI
namespace = dev
{
"code": 1000
}
GET
http://127.0.0.1:8000/v2/namespaces 获取名称空间列表
{
"code": 1000,
"data": [
"default",
"dev"
]
}
data:名称空间列表
URI
namespace = dev
key = test
Body
{
"value": "hello world",
"ttl": 300
}
key:键;value:值;ttl:有效时间(秒)(当ttl=0时,键值不会过期)
{
"code": 1000,
"data": 1690475805
}
data:键值的过期日期(秒级时间戳)
DELETE
http://127.0.0.1:8000/v2/kv/{namespace}/{key} 删除键值
URI
namespace = dev
key = test
{
"code": 1000
}
GET
http://127.0.0.1:8000/v2/kv/{namespace}/{key} 根据键获取键值
URI
namespace = dev
key = test
{
"code": 1000,
"data": {
"key": "test",
"value": "hello world",
"ddl": 1690475805
}
}
ddl:键值的过期日期(秒级时间戳)(ddl=0时表示该键值不会过期)
GET
http://127.0.0.1:8000/v2/kvs/{namespace}/{key_prefix}?offset=0&count=10 根据键前缀获取键值列表
URI
namespace = dev
key_prefix = te
Query
offset = 0
count = 10
{
"code": 1000,
"data": [
{
"key": "test",
"value": "hello world",
"ddl": 1690475805
},
{
"key": "test1",
"value": "hi world",
"ddl": 0
}
]
}
key_prefix:键的前缀;offset:分页游标;count:分页大小(count=0时返回当前游标后的所有数据)
WS
ws://127.0.0.1:8000/subscribe/{namespace}/{key_prefix}/{client_id} 订阅监听某个/某批前缀相同的键值更新事件
URI
namespace = dev
key_prefix = te
clientId = 12he6fj48dhe36fu398rhf3hf392423g
{
"method": 1,
"key": "test",
"value": "hello world",
"ddl": 1690475805
}
client_id:客户端id(自定义传入,必须唯一);method:0-键值删除事件;1-键值写入事件
{
"code": 1002,
"error": "len(namespace) == 0"
}
失败响应码
- 1001 接口入参异常响应码
- 1002 服务处理异常响应码
- 1003 集群调用异常响应码