Fabric 1.0原始碼分析(23)LevelDB(KV資料庫)
# Fabric 1.0原始碼筆記 之 LevelDB(KV資料庫)
## 1、LevelDB概述
LevelDB是Google開源的持久化KV單機資料庫,具有很高的隨機寫,順序讀/寫效能,但是隨機讀的效能很一般,也就是說,LevelDB很適合應用在查詢較少,而寫很多的場景。
LevelDB的特點:
* key和value都是任意長度的位元組陣列;
* entry(即一條K-V記錄)預設是按照key的字典順序儲存的,當然開發者也可以過載這個排序函式;
* 提供的基本操作介面:Put()、Delete()、Get()、Batch();
* 支援批量操作以原子操作進行;
* 可以建立資料全景的snapshot(快照),並允許在快照中查詢資料;
* 可以通過前向(或後向)迭代器遍歷資料(迭代器會隱含的建立一個snapshot);
* 自動使用Snappy壓縮資料;
* 可移植性;
Fabric中使用了goleveldb包,即https://github.com/syndtr/goleveldb/。
goleveldb的基本操作:
* 開啟資料庫,db, err:=leveldb.OpenFile("./db", nil)。作用就是在當前目錄下建立一個db資料夾作為資料庫的目錄。
* 儲存鍵值,db.Put([]byte("key1"),[]byte("value1"),nil)。作用就是在資料庫中儲存鍵值對 key1-value1。leveldb資料庫中對鍵值的操作都是byte格式化的資料。
* 獲取鍵值對,data,_ := db.Get([]byte("key1"),nil),獲取key1對應的值。
* 遍歷資料庫,iter := db.NewIterator(nil, nil),for iter.Next(){ fmt.Printf("key=%s,value=%s\n",iter.Key(),iter.Value()) },iter.Release()。作用就是建立迭代器iter,然後依次遍歷資料庫中所有的資料並列印鍵和值,最後釋放迭代器iter。
* 關閉資料庫,db.Close()。
Fabric中LevelDB程式碼,分佈在common/ledger/util/leveldbhelper目錄,目錄結構如下:
* leveldb_provider.go,定義了結構體Provider、Provider、UpdateBatch、Iterator及其方法。
* leveldb_helper.go,定義了DB結構體及方法。
## 2、DB結構體及方法
DB結構體定義:對實際資料儲存的包裝。
```go
type Conf struct {
DBPath string //路徑
}
type DB struct {
conf *Conf //配置
db *leveldb.DB //leveldb.DB物件
dbState dbState //type dbState int32
mux sync.Mutex //鎖
readOpts *opt.ReadOptions
writeOptsNoSync *opt.WriteOptions
writeOptsSync *opt.WriteOptions
}
//程式碼在common/ledger/util/leveldbhelper/leveldb_helper.go
```
涉及如下方法:對goleveldb包做了封裝。
```go
func CreateDB(conf *Conf) *DB //建立DB例項
func (dbInst *DB) Open() //leveldb.OpenFile,建立並開啟leveldb資料庫(如目錄不存在則建立)
func (dbInst *DB) Close() //db.Close()
func (dbInst *DB) Get(key []byte) ([]byte, error) //db.Get
func (dbInst *DB) Put(key []byte, value []byte, sync bool) error //db.Put
func (dbInst *DB) Delete(key []byte, sync bool) error //db.Delete
func (dbInst *DB) GetIterator(startKey []byte, endKey []byte) iterator.Iterator //db.NewIterator,建立迭代器
func (dbInst *DB) WriteBatch(batch *leveldb.Batch, sync bool) error //db.Write,批量寫入
//程式碼在common/ledger/util/leveldbhelper/leveldb_helper.go
```
## 3、DBHandle結構體及方法
DBHandle結構體定義:封裝DB,目的為給key新增dbName字首,新增和拆除字首通過constructLevelKey(h.dbName, key)和retrieveAppKey()實現。
```go
type DBHandle struct {
dbName string //DB名稱
db *DB //type DB struct
}
//程式碼在common/ledger/util/leveldbhelper/leveldb_provider.go
```
涉及如下方法:
```go
func (h *DBHandle) Get(key []byte) ([]byte, error) //h.db.Get
func (h *DBHandle) Put(key []byte, value []byte, sync bool) error //h.db.Put
func (h *DBHandle) Delete(key []byte, sync bool) error //h.db.Delete
func (h *DBHandle) WriteBatch(batch *UpdateBatch, sync bool) error //h.db.WriteBatch
func (h *DBHandle) GetIterator(startKey []byte, endKey []byte) *Iterator //h.db.GetIterator
//程式碼在common/ledger/util/leveldbhelper/leveldb_provider.go
```
補充UpdateBatch結構體及方法:
```go
type UpdateBatch struct {
KVs map[string][]byte
}
func NewUpdateBatch() *UpdateBatch //構造UpdateBatch
func (batch *UpdateBatch) Put(key []byte, value []byte) //batch.KVs[string(key)] = value
func (batch *UpdateBatch) Delete(key []byte) //batch.KVs[string(key)] = nil
//程式碼在common/ledger/util/leveldbhelper/leveldb_provider.go
```
補充Iterator結構體及方法:封裝github.com/syndtr/goleveldb/leveldb/iterator。
```go
type Iterator struct {
iterator.Iterator
}
func (itr *Iterator) Key() []byte //itr.Iterator.Key()拆除dbName
func constructLevelKey(dbName string, key []byte) []byte //為key新增dbName
func retrieveAppKey(levelKey []byte) []byte //為key拆除dbName
//程式碼在common/ledger/util/leveldbhelper/leveldb_provider.go
```
## 4、Provider結構體及方法
Provider結構體定義:將單個物理LevelDB,虛擬為多個邏輯LevelDB
```go
type Provider struct {
db *DB
dbHandles map[string]*DBHandle
mux sync.Mutex
}
//程式碼在common/ledger/util/leveldbhelper/leveldb_provider.go
```
涉及方法如下:
```go
func NewProvider(conf *Conf) *Provider {//建立並開啟db,構造Provider
db := CreateDB(conf)
db.Open()
return &Provider{db, make(map[string]*DBHandle), sync.Mutex{}}
}
//獲取名稱為dbName的leveldb控制程式碼
func (p *Provider) GetDBHandle(dbName string) *DBHandle {
p.mux.Lock()
defer p.mux.Unlock()
dbHandle := p.dbHandles[dbName]
if dbHandle == nil {
dbHandle = &DBHandle{dbName, p.db}
p.dbHandles[dbName] = dbHandle
}
return dbHandle
}
//關閉leveldb
func (p *Provider) Close() {
p.db.Close()
}
//程式碼在common/ledger/util/leveldbhelper/leveldb_provider.go
```
網址:http://www.qukuailianxueyuan.io/
欲領取造幣技術與全套虛擬機器資料
區塊鏈技術交流QQ群:756146052 備註:CSDN
尹成學院微信:備註:CSDN
網址:http://www.qukuailianxueyuan.io/
欲領取造幣技術與全套虛擬機器資料
區塊鏈技術交流QQ群:756146052 備註:CSDN
尹成學院微信:備註:CSDN
相關文章
- Fabric 1.0原始碼分析(20) Ledger #idStore(ledgerID資料庫)原始碼資料庫
- Fabric 1.0原始碼分析(19) Ledger #statedb(狀態資料庫)原始碼資料庫
- Fabric 1.0原始碼分析(21)Ledger #historydb(歷史資料庫)原始碼資料庫
- Fabric 1.0原始碼分析(25) Orderer原始碼
- Fabric 1.0原始碼分析(31) Peer原始碼
- Fabric 1.0原始碼分析(3)Chaincode(鏈碼)原始碼AI
- Fabric 1.0原始碼分析(40) Proposal(提案)原始碼
- Fabric 1.0原始碼分析(14) flogging(Fabric日誌系統)原始碼
- Fabric 1.0原始碼分析(18) Ledger(賬本)原始碼
- Fabric 1.0原始碼分析(43) Tx(Transaction 交易)原始碼
- Fabric 1.0原始碼分析(47)Fabric 1.0.4 go程式碼量統計原始碼Go
- Fabric 1.0原始碼分析(42)scc(系統鏈碼)原始碼
- Fabric 1.0原始碼分析(13)events(事件服務)原始碼事件
- Fabric 1.0原始碼分析(26)Orderer #ledger(Orderer Ledger)原始碼
- Fabric 1.0原始碼分析(39) policy(背書策略)原始碼
- Fabric 1.0原始碼分析(45)gRPC(Fabric中註冊的gRPC Service)原始碼RPC
- Fabric 1.0原始碼分析(10)consenter(共識外掛)原始碼
- Fabric 1.0原始碼分析(15)gossip(流言演算法)原始碼Go演算法
- Fabric 1.0原始碼分析(44)Tx #RWSet(讀寫集)原始碼
- Fabric 1.0原始碼分析(5)Chaincode(鏈碼)體系總結原始碼AI
- Fabric 1.0原始碼分析(6)configtx(配置交易) #ChannelConfig(通道配置)原始碼
- Fabric 1.0原始碼分析(29) Orderer #multichain(多鏈支援包)原始碼AI
- Fabric 1.0原始碼分析(30) Orderer #BroadcastServer(Broadcast服務端)原始碼ASTServer服務端
- Fabric 1.0原始碼分析(35)Peer #EndorserServer(Endorser服務端)原始碼Server服務端
- Fabric 1.0原始碼分析(36) Peer #EndorserClient(Endorser客戶端)原始碼client客戶端
- Fabric 1.0原始碼分析(37) Peer #DeliverClient(Deliver客戶端)原始碼client客戶端
- Fabric 1.0原始碼分析(38) Peer #BroadcastClient(Broadcast客戶端)原始碼ASTclient客戶端
- Fabric 1.0原始碼分析(41)putils(protos/utils工具包)原始碼
- Fabric 1.0原始碼分析(2) blockfile(區塊檔案儲存)原始碼BloC
- Fabric 1.0原始碼分析(7)configtx(配置交易) #configtxgen(生成通道配置)原始碼
- Fabric 1.0原始碼分析(9)configtx(配置交易)體系介紹原始碼
- Fabric 1.0原始碼分析(22)Ledger #blkstorage(block檔案儲存)原始碼BloC
- Fabric 1.0原始碼分析(27) Orderer #configupdate(處理通道配置更新)原始碼
- Fabric 1.0原始碼分析(32) Peer #peer node start命令實現原始碼
- Fabric 1.0原始碼分析(42)scc(系統鏈碼) #cscc(通道相關)原始碼
- Fabric 1.0原始碼分析(4)Chaincode(鏈碼)#platforms(鏈碼語言平臺)原始碼AIPlatform
- leveldb原始碼分析(2)-bloom filter原始碼OOMFilter
- Fabric 1.0原始碼分析(28) Orderer #localconfig(Orderer配置檔案定義)原始碼