github.com/rosedblabs/rosedb/v2@v2.3.7-0.20240423093736-a89ea823e5b9/README.md (about)

     1  <div align="center">
     2  <strong>
     3  <samp>
     4  
     5  [English](https://github.com/rosedblabs/rosedb/blob/main/README.md) · [简体中文](https://github.com/rosedblabs/rosedb/blob/main/README-CN.md)
     6  
     7  </samp>
     8  </strong>
     9  </div>
    10  
    11  ## What is ROSEDB
    12  
    13  rosedb is a lightweight, fast and reliable key/value storage engine based on [Bitcask](https://riak.com/assets/bitcask-intro.pdf) storage model.
    14  
    15  The design of Bitcask was inspired, in part, by log-structured filesystems and log file merging.
    16  
    17  ## Status
    18  rosedb is well tested and ready for production use. There are serveral projects using rosedb in production as a storage engine.
    19  
    20  **Didn't find the feature you want? Feel free to open an issue or PR, we are in active development.**
    21  
    22  ## Design overview
    23  
    24  ![](https://github.com/rosedblabs/rosedb/blob/main/docs/imgs/design-overview-rosedb.png)
    25  
    26  RoseDB log files are using the WAL(Write Ahead Log) as backend, which are append-only files with block cache.
    27  
    28  > wal: https://github.com/rosedblabs/wal
    29  
    30  ## Key features
    31  
    32  ### Strengths
    33  
    34  <details>
    35      <summary><b>Low latency per item read or written</b></summary>
    36      This is due to the write-once, append-only nature of Bitcask database files.
    37  </details>
    38  
    39  <details>
    40      <summary><b>High throughput, especially when writing an incoming stream of random items</b></summary>
    41      Write operations to RoseDB generally saturate I/O and disk bandwidth, which is a good thing from a performance perspective. This saturation occurs for two reasons: because (1) data that is written to RoseDB doesn't need to be ordered on disk, and (2) the log-structured design of Bitcask allows for minimal disk head movement during writes.
    42  </details>    
    43  
    44  <details>
    45      <summary><b>Ability to handle datasets larger than RAM without degradation</b></summary>
    46      Access to data in RoseDB involves direct lookup from an in-memory index data structure. This makes finding data very efficient, even when datasets are very large.
    47  </details>
    48  
    49  <details>
    50      <summary><b>Single seek to retrieve any value</b></summary>
    51      RoseDB's in-memory index data structure of keys points directly to locations on disk where the data lives. RoseDB never uses more than one disk seek to read a value and sometimes even that isn't necessary due to filesystem caching done by the operating system.
    52  </details>
    53  
    54  <details>
    55      <summary><b>Predictable lookup and insert performance</b></summary>
    56      For the reasons listed above, read operations from RoseDB have fixed, predictable behavior. This is also true of writes to RoseDB because write operations require, at most, one seek to the end of the current open file followed by and append to that file.
    57  </details>
    58  
    59  <details>
    60      <summary><b>Fast, bounded crash recovery</b></summary>
    61      Crash recovery is easy and fast with RoseDB because RoseDB files are append only and write once. The only items that may be lost are partially written records at the tail of the last file that was opened for writes. Recovery operations need to review the record and verify CRC data to ensure that the data is consistent.
    62  </details>
    63  
    64  <details>
    65      <summary><b>Easy Backup</b></summary>
    66      In most systems, backup can be very complicated. RoseDB simplifies this process due to its append-only, write-once disk format. Any utility that archives or copies files in disk-block order will properly back up or copy a RoseDB database.
    67  </details>
    68  
    69  <details>
    70      <summary><b>Batch options which guarantee atomicity, consistency, and durability</b></summary>
    71  	RoseDB supports batch operations which are atomic, consistent, and durable. The new writes in batch are cached in memory before committing. If the batch is committed successfully, all the writes in the batch will be persisted to disk. If the batch fails, all the writes in the batch will be discarded.
    72  </details>
    73  
    74  <details>
    75      <summary><b>Support iterator for forward and backward</b></summary>
    76  	RoseDB supports iterator for forward and backward. The iterator is based on the in-memory index data structure of keys, which points directly to locations on disk where the data lives. The iterator is very efficient, even when datasets are very large.
    77  </details>
    78  
    79  <details>
    80      <summary><b>Support key watch</b></summary>
    81  	RoseDB supports key watch, you can get the notification if keys changed in db.
    82  </details>
    83  
    84  <details>
    85      <summary><b>Support key expire</b></summary>
    86  	RoseDB supports key expire, you can set the expire time for keys.
    87  </details>
    88  
    89  ### Weaknesses
    90  
    91  <details>
    92      <summary><b>Keys must fit in memory</b></summary>
    93      RoseDB keeps all keys in memory at all times, which means that your system must have enough memory to contain your entire keyspace, plus additional space for other operational components and operating- system-resident filesystem buffer space.
    94  </details>
    95  
    96  ## Gettings Started
    97  
    98  ### Basic operations
    99  
   100  ```go
   101  package main
   102  
   103  import "github.com/rosedblabs/rosedb/v2"
   104  
   105  func main() {
   106  	// specify the options
   107  	options := rosedb.DefaultOptions
   108  	options.DirPath = "/tmp/rosedb_basic"
   109  
   110  	// open a database
   111  	db, err := rosedb.Open(options)
   112  	if err != nil {
   113  		panic(err)
   114  	}
   115  	defer func() {
   116  		_ = db.Close()
   117  	}()
   118  
   119  	// set a key
   120  	err = db.Put([]byte("name"), []byte("rosedb"))
   121  	if err != nil {
   122  		panic(err)
   123  	}
   124  
   125  	// get a key
   126  	val, err := db.Get([]byte("name"))
   127  	if err != nil {
   128  		panic(err)
   129  	}
   130  	println(string(val))
   131  
   132  	// delete a key
   133  	err = db.Delete([]byte("name"))
   134  	if err != nil {
   135  		panic(err)
   136  	}
   137  }
   138  ```
   139  
   140  ### Batch operations
   141  
   142  ```go
   143  	// create a batch
   144  	batch := db.NewBatch(rosedb.DefaultBatchOptions)
   145  
   146  	// set a key
   147  	_ = batch.Put([]byte("name"), []byte("rosedb"))
   148  
   149  	// get a key
   150  	val, _ := batch.Get([]byte("name"))
   151  	println(string(val))
   152  
   153  	// delete a key
   154  	_ = batch.Delete([]byte("name"))
   155  
   156  	// commit the batch
   157  	_ = batch.Commit()
   158  ```
   159  
   160  see the [examples](https://github.com/rosedblabs/rosedb/tree/main/examples) for more details.
   161  
   162  ## Community
   163  Welcome to join the [Slack](https://join.slack.com/t/rosedblabs/shared_invite/zt-19oj8ecqb-V02ycMV0BH1~Tn6tfeTz6A) channel and [Discussions](https://github.com/orgs/rosedblabs/discussions) to connect with RoseDB team developers and other users.
   164  
   165  ## Contributors
   166  [![](https://opencollective.com/rosedb/contributors.svg?width=890&button=false)](https://github.com/rosedblabs/rosedb/graphs/contributors)