Derek解讀Bytom源碼-持久化儲存LevelDB

來源:互聯網
上載者:User

作者:Derek

簡介

Github地址:https://github.com/Bytom/bytom

Gitee地址:https://gitee.com/BytomBlockc...

本章介紹Derek解讀-Bytom源碼分析-持久化儲存LevelDB

作者使用MacOS作業系統,其他平台也大同小異

Golang Version: 1.8

LevelDB介紹

比原鏈預設使用leveldb資料庫。Leveldb是一個google實現的非常高效的kv資料庫。LevelDB是單進程的服務,效能非常之高,在一台4核Q6600的CPU機器上,每秒鐘寫資料超過40w,而隨機讀的效能每秒鐘超過10w。

由於Leveldb是單進程服務,不能同時有多個進程進行對一個資料庫進行讀寫。同一時間只能有一個進程,或一個進程多並發的方式進行讀寫。

比原鏈在資料存放區層上儲存所有鏈上地址、資產交易等資訊。

LevelDB的增刪改查操作

LevelDB是google開發的一個高效能K/V儲存,本節我們介紹下LevelDB如何對LevelDB增刪改查。

package mainimport (    "fmt"    dbm "github.com/tendermint/tmlibs/db")var (    Key        = "TESTKEY"    LevelDBDir = "/tmp/data")func main() {    db := dbm.NewDB("test", "leveldb", LevelDBDir)    defer db.Close()    db.Set([]byte(Key), []byte("This is a test."))    value := db.Get([]byte(Key))    if value == nil {        return    }    fmt.Printf("key:%v, value:%v\n", Key, string(value))    db.Delete([]byte(Key))}// Output// key:TESTKEY, value:This is a test.

以上Output是執行該程式得到的輸出結果。

該程式對leveld進行了增刪改查操作。dbm.NewDB得到db對象,在/tmp/data目錄下會產生一個叫test.db的目錄。該目錄存放該資料庫的所有資料。
db.Set 設定key的value值,key不存在則建立,key存在則修改。
db.Get 得到key中value資料。
db.Delete 刪除key及value的資料。

比原鏈的資料庫

預設情況下,資料存放區目錄在--home參數下的data目錄。以Darwin平台為例,預設資料庫儲存在 $HOME/Library/Bytom/data。

  • accesstoken.db token資訊(錢包存取控制許可權)
    core.db 核心資料庫,儲存主鏈相關資料。包括塊資訊、交易資訊、資產資訊等
    discover.db 分布式網路中端到端的節點資訊
  • trusthistory.db
    txdb.db 儲存體交易相關資訊
    txfeeds.db 目前比原鏈代碼版本未使用該功能,暫不介紹
    wallet.db 本地錢包資料庫。儲存使用者、資產、交易、utox等資訊

以上所有資料庫都由database模組管理

比原資料庫介面

在比原鏈中資料持久化儲存由database模組管理,但是持久化相關介面在protocol/store.go中

type Store interface {    BlockExist(*bc.Hash) bool    GetBlock(*bc.Hash) (*types.Block, error)    GetStoreStatus() *BlockStoreState    GetTransactionStatus(*bc.Hash) (*bc.TransactionStatus, error)    GetTransactionsUtxo(*state.UtxoViewpoint, []*bc.Tx) error    GetUtxo(*bc.Hash) (*storage.UtxoEntry, error)    LoadBlockIndex() (*state.BlockIndex, error)    SaveBlock(*types.Block, *bc.TransactionStatus) error    SaveChainStatus(*state.BlockNode, *state.UtxoViewpoint) error}
  • BlockExist 根據hash判斷區塊是否存在
  • GetBlock 根據hash擷取該區塊
  • GetStoreStatus 擷取store的儲存狀態
  • GetTransactionStatus 根據hash擷取該塊中所有交易的狀態
  • GetTransactionsUtxo 緩衝與輸入txs相關的所有utxo
  • GetUtxo(*bc.Hash) 根據hash擷取該塊內的所有utxo
  • LoadBlockIndex 載入塊索引,從db中讀取所有block header資訊並緩衝在記憶體中
  • SaveBlock 儲存塊和交易狀態
  • SaveChainStatus 設定主鏈的狀態,當節點第一次啟動時,節點會根據key為blockStore的內容判斷是否初始化主鏈。

比原鏈資料庫key首碼

database/leveldb/store.go

var (    blockStoreKey     = []byte("blockStore")    blockPrefix       = []byte("B:")    blockHeaderPrefix = []byte("BH:")    txStatusPrefix    = []byte("BTS:"))
  • blockStoreKey 主鏈狀態首碼
  • blockPrefix 塊資訊首碼
  • blockHeaderPrefix 塊頭資訊首碼
  • txStatusPrefix 交易狀態首碼

GetBlock查詢塊過程分析

database/leveldb/store.go

func (s *Store) GetBlock(hash *bc.Hash) (*types.Block, error) {    return s.cache.lookup(hash)}

database/leveldb/cache.go

func (c *blockCache) lookup(hash *bc.Hash) (*types.Block, error) {    if b, ok := c.get(hash); ok {        return b, nil    }    block, err := c.single.Do(hash.String(), func() (interface{}, error) {        b := c.fillFn(hash)        if b == nil {            return nil, fmt.Errorf("There are no block with given hash %s", hash.String())        }        c.add(b)        return b, nil    })    if err != nil {        return nil, err    }    return block.(*types.Block), nil}

GetBlock函數最終會執行lookup函數。lookup函數總共操作有兩步:

  • 從緩衝中查詢hash值,如果查到則返回
  • 如果為從緩衝中查詢到則回調fillFn回呼函數。fillFn回呼函數會將從磁碟上獲得到塊資訊儲存到緩衝中並返回該塊的資訊。

fillFn回呼函數實際上調取的是database/leveldb/store.go下的GetBlock,它會從磁碟中擷取block資訊並返回。

相關關鍵詞:
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.