tsalakh ain sus noam Huyah ol guf

勉強会のメモ。その他備忘録。参考にさせて頂いたサイトや資料はリンクさせて頂いていますが不都合があればご連絡ください。

【技術メモ】LevelDB超入門

【技術メモ】LevelDB

LevelDB入門 (基本編)

  • 掲載日:2014/05/05

yosuke-furukawa.hatenablog.com

LevelDBとは?

  • key-value型のデータストアの一つ
  • Googleが開発、2011年に公表。C++で書かれている。
  • Google がIndexedDB実装用に、SQLiteよりもIndexedDBに向くKey-Value型の軽量データストアとして開発
  • ChromeのIndexedDB 実装のためのbackend
  • InfluxDBもRiakもバックエンドはLevelDB

LevelDBの特徴

  • keyとvalueが任意のバイト列
  • データはkeyでソートされて格納
  • 比較関数でソート順序変更
  • シンプルな操作、 Put(key, value), Get(key), Delete(key)
  • 複数の変更をatomicに処理
  • 書き込み中でもread可能
  • データを自動的に圧縮(圧縮ライブラリ:Snappy)
  • OSの操作を抽象化してカスタマイズ可能

LevelDBは何に向くのか

  • LevelDBをバックエンドとした独自のデータストアを作る、という使われ方が多い
  • 例:InfluxDB
    • keyにtimestampを付けて、LevelDB内部で時系列順にソート
    • 順番にReadするsequential readとwriteヘビーに利用
  • 例:Riak
  • 例:ChromeのIndexedDB
    • 構造が非常にシンプルで軽量なので、クライアントサイドのバックエンドとしても使える
    • まさにSQLiteの代替
  • Node.js
    • Node.jsは、ブラウザでもサーバサイドでも動作できる
    • Node.jsでLevelDBが流行っている理由としてはこのポータブルかつモジュラーなところ
    • クライアントサイドでもサーバサイドでも同じインタフェースで永続化できる

アーキテクチャ

  • write時にはLogとSorted Tableに書き込み
  • read時にはcacheを通してLog、Sorted Table、Cacheから値を読み取り

Log file

  • LevelDBへのwrite処理は、Logとインメモリのストア先(memtable)に書込
  • Logに書きだされたデータは、一定サイズを超えるとファイル(SST)に出力
  • read処理は、LogとSSTの2つのデータ構造から読込
    • SSTに入っているデータ:書込から一定時間が経過したデータ
    • Logに入っているデータ:新しいデータ
  • この他に、読み込みを高速化するためにCache領域
  • Cache領域はアプリケーションに依存して大きさ調整が可能

String Sorted Table (SST)

  • SSTは、keyでソートされたエントリを保存
  • SSTは、Level毎にまとまって階層化
    • ここがLevelDBの由来
  • Logが一定量貯まると最も若いストア先(Level-0)にデータを移動
  • Level-0がいっぱいになると、Level-0からLevel-1にデータを移動
  • Levelが増えるほど保存できる容量が増える仕組み
  • 雑に言えば、 Level-1だと大体10MB保存できて、Level-2だと100MB、Level-3だと1GBと10倍ずつ増加

Bloom filter

  • キーがどのLevelに存在するかを教えてくれるフィルター
  • キーからハッシュを使って、そのLevelにデータが存在する可能性をO(1)で計算
  • Bloom filterの特徴はFalse Positive
    • 「存在しない」の応答時は、確実に存在しない
    • 「存在する」の応答時は、実際にLevel内を探索するまで不明
    • 明らかに無駄なLevelを排除することで探索範囲の枝刈りをするしくみ

基本操作 Put

  • key と valueを入れると、一旦その値をLogと memtableに書出
  • memtableに入れた情報は、書込上限に達するとLevel-0のSSTに書出
  • Level-0がいっぱいになったらLevel-1に書出、以下階層的に。

基本操作 Get

  • メモリ、Level-0、Level-1、Level-2、、、と検索してヒットしたらその値を返却
  • 検索する際にBloom filterを使って無駄な検索の枝刈り

基本操作 Delete

  • 基本的に論理削除で、削除フラグを立てるだけ
  • 次のLevelに値を移動する時に物理削除
  • 論理削除にすることで、削除コストとindexの再作成コストを減らす

性能比較

  • Randam readsはTreeDB、SQLiteとそこまで差はありません
  • 順番にReadするSequential ReadとWrite処理に関してはTreeDB、SQLiteと比較して優位