NEL发布NEO Key-Value数据库LightDB
不明白不知道
发表于 2022-12-5 17:52:44
165
0
0
也就是把Neo的一个节点一个进程的模式,改造为一个节点一个集群。
完成这个目标的基础,就是这个网络数据库需要一个类似的很低成本的读snapshot支持。
所以我选择了rocksdb作为这个基础,rocksdb是facebook 基于leveldb魔改的一个改进版本。
那么为什么要追加数据类型和表的概念?& n% M5 J- q# W- z7 q3 q
因为leveldb使用中存储的东西都是byte[],而很多时候我们使用neo中得到的byte[] 都不知道是什么东西,要靠相应的约定。
我觉得这个很不方便,所以我们存储的单位不是byte[] 而是一个结构体 DBValue,他可以描述自己是什么数据类型,整数,string,byte[],bigint,小数,等等。
这个结构体里面还预留了给每一个值附加信息的功能,也记录了这个值最终修改的时间戳(存储高度)
至于表就更好理解了,这是使用leveldb的一个自然需求,keyvalue数据库是一个字典,可是我们存进去的东西,从逻辑上是分为几个字典的,交易字典,utxo字典,等等等。
我们只是把这个分字典的自然需求,在数据库层面直接提供了。5 j& c; w) A Z+ v& [, `. U
然后是网络层,选择了websocket作为通讯方法,完全是基于将来是网页的天下的考虑。因为存储这个功能被独立出来,甚至可以写一条链,他完全是在网页中运行的。( ?0 f1 ?* q8 G- S
当然目前还没有想那么多,但可以预见到越来越多的业务会在网络中运行,因为这个数据库的出现,nel目前的至少50%的查询需求可以不通过后台服务器,js直接完成。; w" J1 k3 @) i$ w5 L- v; V
比如nep5资产的blanceof,比如交易UTXO数据的确认。- y* n: P# f: F2 @' o' }# c! ]1 p
其三,数据库的存储模仿了区块链的结构,以taskblock为单位,首尾相接。毕竟一开始这个项目的名字就叫lightchain.
后来一想,这个名字有点烂大街了,数据库还是老老实实的叫DB吧: o. {( R* [' y0 }# J' w2 `+ Q H
为什么要以taskblock为单位呢,因为便于同步。数据库读写分离是性能扩展的必然走向,而把每一个操作记录下来,从数据库只要从主数据库取得每一个block,自己执行一遍,就同步完了。1 l# ^: P$ {/ z: x3 d% u
对了还有一点也很像NEO区块链,我们的写入权限控制不是用密码,而是用私钥,而且还是和NEO完全兼容的私钥8 `+ G/ N/ A( O8 [
最后,还有一个很重要的功能,checkpoint,这也是rocksdb提供的礼物,可以快速的在本地产生一个新的数据库副本。这样我们做链上数据快照的手段就更多了,传统手段是用爬虫爬取要快照的数据,爬到指定高度,停。现在又多了一个手段,约定时间快照,到时间了,啪,一个checkpoint,整个数据库都备份下来了。- V+ }7 s& _% h2 d2 z7 n
不过当数据量达到G的级别,这个checkpoint性能是怎样的,还是需要测试确认的1 p3 J$ O. C4 ` }. P
项目使用方法
一、开服务器
获取lightdb.server,生成, A0 p+ a1 r; m: }/ T7 S, n
启动之前看一下config
Server_port 服务端口
Server_storage_path 数据库存储路径! [: _, {4 W: p T$ a
Server_type 读写分离用,从机模式还没开发呢,只能Master; ?1 \5 O: o2 i* g, c/ M, Y: W
Storage_maindb_magic 提供一个魔法字串,好让这个库特立独行4 K0 e/ D/ u1 z4 D
会写入库中,数据库创建之后,改这个值就没意义了% l# L( U( Y* m# H
Storage_maindb_firstwriter_address 提供一个NEO地址,他将成为第一个有写入权限的人,实际上还没开发追加写入人的功能,他就是唯一一个。1 v; B& w' r) e* N( z
会写入库中,数据库创建之后,改这个值就没意义了
然后启动server,支持linux windows,在win10,unbutu,centos测试过,linux下需安装依赖库,参考facebook rocksdb项目的说明
https://github.com/facebook/rocksdb/blob/master/INSTALL.md
中的Supported platforms一节, j# [5 M B- ~/ a" M
如果路径里没有创建过数据库会新建,否则会打开
控制台目前只有db.state 和 db.block 两个功能
Db.block 会把block解析开,我们可以看到每个block都干了些啥,value都是DBvalue,用DBValue结构体去查看就能看到类型" Z R9 [. O7 S
二、客户端使用6 m. A. E2 Z, ~) ^6 b
首先引用lightdb.sdk,可以下源码,可以nuget
% x+ a( A2 q; j+ B+ G
New一个client对象6 T _5 z; n2 q( f, G
注册,断线事件,然后Connect
如果连接成功,就OK, e( t0 |, ~" p. K* [& @
不需要登陆啥的,读随便,写的时候,需要你先签好名
Ping 与dbstate
y" ]0 p' V. f7 P7 e
所有的读操作都是通过snap来进行的, W7 [9 I* g$ ^/ S" `( y
' t! u( n! f8 h* h) E& {+ v: G
所以先要获取一个snapshot& N- B6 O( g% Q! i2 ]
然后就可以getblock8 {- {" Y3 J5 o8 J! Z
9 o1 m; j. `8 ~1 p5 Y0 P) b* f0 U
Getblockhash& U, `- N: a( }7 Z, u O
Getvalue
client.Post_snapshot_getvalue(snapshotid, tableid, key);" [2 X9 L, o c/ {+ H
要写数据就比较复杂了" Q+ v% ^) [4 g$ F, A( v# n* ~' e' g
首先创建个writetask对象,所有的写入,都通过writetask对象完成,6 p: V- k H& H2 g. V* A8 g
然后创建signdata对象,进行签名" B5 F; [+ g% l7 I; f. _2 Z3 E; a+ e
然后将这两个东西post给服务器。有对应的私钥才能完成签名,成功写入数据。
成为第一个吐槽的人