源自于NEO的KeyValue 数据库面世啦
虽然想把标题取得大一点,但终究不是什么太大不了的工作,还是安分守己的开始介绍吧。
项目组成
这个项目叫做LightDB
由三个部分构成
Lightdb.lib 是对rocksdb做了一层封装,主要的修改是追加了保存的数据类型,和表的概念
https://github.com/lightszero/lightdb.lib
Lightdb.server 就是一个远程数据库啦,Lightdb的服务器版本
https://github.com/lightszero/lightdb.server
Lightdb.SDK 是方便客户端接入LightdbServer 提供的,目前只提供了C#版本实现,后续还会提供Typescript版本实现,通讯协议比较简单,任意支持websocket的方案都可以连接。
https://github.com/lightszero/lightdb.sdk
项目特点
要说项目特点的话,
一、追加了数据类型和表概念。
二、有服务器,采用websocket通讯,对js友好
三、数据的存储以taskblock为单位,方便数据库互相验证和同步
其实最重要的特点还有一个关于读的快照snapshot。快照的需求来源是数据处理的事务化,或者说一批操作的原子性要求。
传统数据库一定程度支持事务化,而KeyValue数据库这边支持事务化的程度就更差一些。
而NEO使用的嵌入式数据库,LevelDB因为采用LSM存储方式,提供读取的snapshot 非常容易,代价也小。
这也就造成了在NEO的实现中,存储部分对Snapshot的依赖非常强。
创立这个项目的初衷,有一部分是要改造NEO的存储部分为网络存储,并且可以用轻型节点直接找网络数据库去执行InvokeScript
也就是把Neo的一个节点一个进程的模式,改造为一个节点一个集群。
完成这个目标的基础,就是这个网络数据库需要一个类似的很低成本的读snapshot支持。
所以我选择了rocksdb作为这个基础,rocksdb是facebook 基于leveldb魔改的一个改进版本。
那么为什么要追加数据类型和表的概念?因为leveldb使用中存储的东西都是byte[],而很多时候我们使用neo中得到的byte[] 都不知道是什么东西,要靠相应的约定。
我觉得这个很不方便,所以我们存储的单位不是byte[] 而是一个结构体 DBValue,他可以描述自己是什么数据类型,整数,string,byte[],bigint,小数,等等。
这个结构体里面还预留了给每一个值附加信息的功能,也记录了这个值最终修改的时间戳(存储高度)
至于表就更好理解了,这是使用leveldb的一个自然需求,keyvalue数据库是一个字典,可是我们存进去的东西,从逻辑上是分为几个字典的,交易字典,utxo字典,等等等。
我们只是把这个分字典的自然需求,在数据库层面直接提供了。
然后是网络层,选择了websocket作为通讯方法,完全是基于将来是网页的天下的考虑。因为存储这个功能被独立出来,甚至可以写一条链,他完全是在网页中运行的。
当然目前还没有想那么多,但可以预见到越来越多的业务会在网络中运行,因为这个数据库的出现,nel目前的至少50%的查询需求可以不通过后台服务器,js直接完成。
比如nep5资产的blanceof,比如交易UTXO数据的确认。
其三,数据库的存储模仿了区块链的结构,以taskblock为单位,首尾相接。毕竟一开始这个项目的名字就叫lightchain.
后来一想,这个名字有点烂大街了,数据库还是老老实实的叫DB吧
为什么要以taskblock为单位呢,因为便于同步。数据库读写分离是性能扩展的必然走向,而把每一个操作记录下来,从数据库只要从主数据库取得每一个block,自己执行一遍,就同步完了。
对了还有一点也很像NEO区块链,我们的写入权限控制不是用密码,而是用私钥,而且还是和NEO完全兼容的私钥
最后,还有一个很重要的功能,checkpoint,这也是rocksdb提供的礼物,可以快速的在本地产生一个新的数据库副本。这样我们做链上数据快照的手段就更多了,传统手段是用爬虫爬取要快照的数据,爬到指定高度,停。现在又多了一个手段,约定时间快照,到时间了,啪,一个checkpoint,整个数据库都备份下来了。
不过当数据量达到G的级别,这个checkpoint性能是怎样的,还是需要测试确认的
项目使用方法
一、开服务器
获取lightdb.server,生成
启动之前看一下config

Server_port 服务端口
Server_storage_path 数据库存储路径
Server_type 读写分离用,从机模式还没开发呢,只能Master
Storage_maindb_magic 提供一个魔法字串,好让这个库特立独行
会写入库中,数据库创建之后,改这个值就没意义了
Storage_maindb_firstwriter_address 提供一个NEO地址,他将成为第一个有写入权限的人,实际上还没开发追加写入人的功能,他就是唯一一个。
会写入库中,数据库创建之后,改这个值就没意义了
然后启动server,支持linux windows,在win10,unbutu,centos测试过,linux下需安装依赖库,参考facebook rocksdb项目的说明
https://github.com/facebook/rocksdb/blob/master/INSTALL.md
中的Supported platforms一节


如果路径里没有创建过数据库会新建,否则会打开

控制台目前只有db.state 和 db.block 两个功能

Db.block 会把block解析开,我们可以看到每个block都干了些啥,value都是DBvalue,用DBValue结构体去查看就能看到类型
二、客户端使用
首先引用lightdb.sdk,可以下源码,可以nuget

New一个client对象

注册,断线事件,然后Connect
如果连接成功,就OK
不需要登陆啥的,读随便,写的时候,需要你先签好名
Ping 与dbstate

所有的读操作都是通过snap来进行的

所以先要获取一个snapshot
然后就可以getblock

Getblockhash

Getvalue
client.Post_snapshot_getvalue(snapshotid, tableid, key);
要写数据就比较复杂了

首先创建个writetask对象,所有的写入,都通过writetask对象完成,
然后创建signdata对象,进行签名
然后将这两个东西post给服务器。有对应的私钥才能完成签名,成功写入数据
源自于NEO的KeyValue 数据库面世啦的更多相关文章
- 那么都数据库表,那么多不同记录。是怎样都存储在一个key-value数据库的?
那么都数据库表,那么多不同记录.是怎样都存储在一个key-value数据库的? :设置不同的键值而已!不同的表,选出统一的key规范 jedis.sadd("tom:friend:list& ...
- [转载] 为 Key-Value 数据库实现 MVCC 事务
http://mp.weixin.qq.com/s?__biz=MzA5ODM5MDU3MA==&mid=400086920&idx=1&sn=b8174184059e2886 ...
- key-value数据库
http://blog.csdn.net/byane/article/details/6928519 传统的文件系统中,需要维护目录的层次结构,使用dentry,inode,directory等复杂结 ...
- 浅尝key-value数据库(二)——MongoDB的优与劣
浅尝key-value数据库(二)——MongoDB的优与劣 MongoDB的名字取自英文单词"humongous"的中间五个字母,是一个C++开发的基于分布式文件存储的数据库开源 ...
- 浅尝key-value数据库(三)——MongoDB的分布式
浅尝key-value数据库(三)——MongoDB的分布式 测试了单机MongoDB的随机读和写入性能,这一节来讲一讲MongoDB的分布式. MongoDB的分布式分成两种,一种是Replicat ...
- 浅尝key-value数据库(一)——一览NoSQL
浅尝key-value数据库(一)——一览NoSQL 最近由于一个项目的关系,研究了一下key-value数据库这个最近很火的概念.本系列从项目需求的角度分析并测试了几个key-value数据库的性能 ...
- key-value数据库-Redis
1.简介 Redis是完全开源的ANSI C语言编写.遵守BSD协议,高性能的key-value数据库. 1.1特点 Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载 ...
- Key-value数据库:Redis缓存服务
Redis 是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.其提供了多种主流语言的客户端,方便使用:同时Redis支持主 ...
- Redis教程(REmote DIctionary Server)——一个高性能的key-value数据库
redis(REmote DIctionary Server)是什么? Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言 ...
随机推荐
- Ext.Net的一例Ext Undefined解决办法
在运行的产品里发现了一例Ext Undefined报错.经过仔细排查原因是一个Ext.net按钮控件前端显示部分使用了<% if() <%> 动态控制输出Html脚本(有对应的后端 ...
- ue4 staticMesh属性记录
Light Map Resolution 光照贴图分辨率 Generate Mesh Distancde Field 生成网格距离场(一种不怎么消耗性能的阴影) http://api.unrealen ...
- 论文阅读笔记(二)U-Net
U-Net: Convolutional Networks for Biomedical Image Segmentation U-Net:用于生物医学图像分割的卷积网络 摘要 要想成功地训练一个深度 ...
- Babel学习小记
一.babel配置文件中的plugins和presets是什么? 1.首先说说babel是什么,babel是一个JavaScript转码器,帮助我们把浏览器不兼容的ES6语法转换成ES5语法: 2.接 ...
- PostgreSQL学习笔记(二)-安装pgAdmin
继上篇安装PostgreSQL后,我们需要安装一个PostgreSQL的图形化管理工具. pgadmin管理工具 创建Python的虚拟环境 cd /root/venv python -m venv ...
- IAR 关于C++几个内存的使用及释放的问题
由于之前工作中常常遇到,但是遇到的时候工作总是要求比较紧急,没有那么多时间细细寻找有效的解决办法.现在了解到了一些,记录一些. 1. string vector 都是增量在堆里,所以只要有增量都是在堆 ...
- Input子系统(二)【转】
转自:http://blog.chinaunix.net/uid-25047042-id-4192368.html 上一篇中粗略的分析了下input_dev,input_handle,input_ha ...
- java内部类:成员内部类,静态内部类方法内部类,匿名内部类(A)
package cn.kecheng; /** * 在java中,一个文件可以定义多个类,文件名必须和public 类型的类的类名保持一致.这两个类是平行关系. * 在java中,一个类也可以定义在一 ...
- MQTT控制---connect
连接服务端 客户端到服务端的第一个报文必须是CONNECT,且只能发送一次,发送的第二个connect报文当作违规处理并断开连接. 有效载荷包含一个或者多个编码的字段.包括客户端的唯一标识符,Will ...
- 常见jquery面试题
jQuery 面试问题和答案 JavaScript 是客户端脚本的标准语言,而 jQuery 使得编写 JavaScript 更加简单.你可以只用写几行的jQuery 代码就能实现更多的东西. 它是最 ...