influxdb
influxdb是最新的一個時間序列數據庫,最新一兩年才產生,但已經擁有極高的人氣。influxdb 是用Go寫的,0.9版本的influxdb對於之前會有很大的改變,后端存儲有LevelDB換成了BoltDB,讀寫的API也是有了很大的變化,也將支持集群化,continuous query,支持retention policy,讀寫性能也是哇哇的,可以說是時間序列存儲的完美方案,但是由於還很年輕,可能還會存在諸多的問題,就像現在正在開發的0.9一樣,發布一拖再拖,就是由於還有些技術壁壘沒有攻陷。
對於influxdb我不想多說些什么,之后打算開一個專題,專門詳細來說一說這個玩意,因為我看國內幾乎沒有詳細的文章來講influxdb的。
如果你想讓你的Go應用中的數據持久化,大多數人會使用一些數據庫。最簡單最方便的選擇是嵌入式數據庫,有很多嵌入式數據庫都是C寫的,然而對於Go開發者來說,更希望使用純粹的Golang的解決方案。
Bolt就是這么一個純粹的Go語言版的嵌入式key/value的數據庫,而且在Go的應用中很方便地去用作持久化。Bolt類似於LMDB,這個被認為是在現代kye/value存儲中最好的。但是又不同於LevelDB,BoltDB支持完全可序列化的ACID事務,也不同於SQLlite,BoltDB沒有查詢語句,對於用戶而言,更加易用。
BoltDB將數據保存在一個單獨的內存映射的文件里。它沒有wal、線程壓縮和垃圾回收;它僅僅安全地處理一個文件。
LevelDB和BoltDB的不同
LevelDB是Google開發的,也是一個k/v的存儲數據庫,和BoltDB比起起來有很大的不同。對於使用者而言,最大的不同就是LevelDB沒有事務。在其內部,也有很多的不同:LevelDB實現了一個日志結構化的merge tree。它將有序的key/value存儲在不同文件的之中,並通過“層級”把它們分開,並且周期性地將小的文件merge為更大的文件。這讓其在隨機寫的時候會很快,但是讀的時候卻很慢。這也讓LevelDB的性能不可預知:但數據量很小的時候,它可能性能很好,但是當隨着數據量的增加,性能只會越來越糟糕。而且做merge的線程也會在服務器上出現問題。LevelDB是C++寫的,但是也有些Go的實現方式,如syndtr/goleveldb、leveldb-go。
BoltDB使用一個單獨的內存映射的文件,實現一個寫入時拷貝的B+樹,這能讓讀取更快。而且,BoltDB的載入時間很快,特別是在從crash恢復的時候,因為它不需要去通過讀log(其實它壓根也沒有)去找到上次成功的事務,它僅僅從兩個B+樹的根節點讀取ID。
按照官方說法,boltDB特點:
Comparison with other databases
Postgres, MySQL, & other relational databases
Relational databases structure data into rows and are only accessible through the use of SQL. This approach provides flexibility in how you store and query your data but also incurs overhead in parsing and planning SQL statements. Bolt accesses all data by a byte slice key. This makes Bolt fast to read and write data by key but provides no built-in support for joining values together.
Most relational databases (with the exception of SQLite) are standalone servers that run separately from your application. This gives your systems flexibility to connect multiple application servers to a single database server but also adds overhead in serializing and transporting data over the network. Bolt runs as a library included in your application so all data access has to go through your application's process. This brings data closer to your application but limits multi-process access to the data.
LevelDB, RocksDB
LevelDB and its derivatives (RocksDB, HyperLevelDB) are similar to Bolt in that they are libraries bundled into the application, however, their underlying structure is a log-structured merge-tree (LSM tree). An LSM tree optimizes random writes by using a write ahead log and multi-tiered, sorted files called SSTables. Bolt uses a B+tree internally and only a single file. Both approaches have trade-offs.
If you require a high random write throughput (>10,000 w/sec) or you need to use spinning disks then LevelDB could be a good choice. If your application is read-heavy or does a lot of range scans then Bolt could be a good choice.
One other important consideration is that LevelDB does not have transactions. It supports batch writing of key/values pairs and it supports read snapshots but it will not give you the ability to do a compare-and-swap operation safely. Bolt supports fully serializable ACID transactions.
LMDB
Bolt was originally a port of LMDB so it is architecturally similar. Both use a B+tree, have ACID semantics with fully serializable transactions, and support lock-free MVCC using a single writer and multiple readers.
The two projects have somewhat diverged. LMDB heavily focuses on raw performance while Bolt has focused on simplicity and ease of use. For example, LMDB allows several unsafe actions such as direct writes for the sake of performance. Bolt opts to disallow actions which can leave the database in a corrupted state. The only exception to this in Bolt is DB.NoSync.
There are also a few differences in API. LMDB requires a maximum mmap size when opening an mdb_env whereas Bolt will handle incremental mmap resizing automatically. LMDB overloads the getter and setter functions with multiple flags whereas Bolt splits these specialized cases into their own functions.
參考:
http://www.opscoder.info/boltdb_intro.html
https://github.com/boltdb/bolt
