persistent_kv/config.rs
1#[derive(Copy, Clone, PartialEq, Debug)]
2pub enum SyncMode {
3 /// Execute a full sync operation(s) after every single key write. This is
4 /// _very_ slow (~milliseconds) but minimizes risk of data loss. If the local
5 /// process fails, data loss is not possible. In the event of a OS level failure
6 /// or power event, data loss is unlikely but still technically possible e.g.
7 /// if the hardware further delays writes without the OS knowing.
8 /// Note: The implementation uses File::sync_all(), so all caveats from there apply.
9 BlockAndSync,
10
11 /// Blocks on but does not explicitly sync file system operation(s). This is
12 /// reasonably fast (~microseconds). In this mode, calling
13 /// [`super::PersistentKeyValueStore::set`] or
14 /// [`super::PersistentKeyValueStore::unset`] on a key still blocks on the
15 /// syscall to append to the write log. This means that local process failures
16 /// should not lead to data loss. OS level failures or power events are possible
17 /// data loss concerning writes that occured in the seconds prior.
18 BlockNoExplicitSync,
19
20 /// Allows for in-memory buffering of writes before writing to disk. There
21 /// is no limit on the size of frequency of the buffer, so at worst a disk
22 /// write may not occur until the store instance is dropped.
23 Buffered,
24}
25
26#[derive(Clone, PartialEq, Debug)]
27pub struct Config {
28 /// If true, we will not write any snapshot / restore events to stdout.
29 /// By default this is on as such events are rare and will be helpful to spot
30 /// unexpected config or runtime issues.
31 pub silent: bool,
32
33 /// The interval at which full snapshots should be created. The unit counted is the
34 /// number of key-value pairs modified (created, updated or deleted) meaning if
35 /// `snapshot_interval` is 10,000, then a snapshot will be created every 10,000
36 /// key-value pairs modified.
37 ///
38 /// Notes:
39 /// - Snapshots may be skipped if we cannot keep up with the number of changes.
40 /// - Snapshots are created asynchronously and do not block reads or writes to
41 /// the main store (except for a brief lock to create a memory data copy).
42 /// - Snapshots are not required for the store to have basic persistence
43 /// guarantees as all modifications are written to a write-ahead log first.
44 /// However, regular snapshotting compacts the write-ahead log and helps
45 /// keep disk usage and startup time to be bounded by
46 /// O(number of keys)
47 /// rather than
48 /// O(number of modifications)
49 pub snapshot_interval: u64,
50
51 /// The number of buckets to use for the memory store, each responsible for a part
52 /// of the keyspace. This is a trade-off between memory overhead and contention
53 /// avoidance in multithreaded operation. Each bucket has its own dictionary,
54 /// supporting data structure and mutex.
55 pub memory_bucket_count: usize,
56
57 /// File system synchronization model.
58 pub sync_mode: SyncMode,
59
60 /// The number of threads to use for IO operations. This includes reading and writing
61 /// of snapshots and influences (but not fully determines) number of shards used.
62 pub target_io_parallelism_snapshots: u64,
63
64 /// The number of shards to use for the write log (this is directly the file count used)
65 pub target_io_parallelism_writelog: u64,
66
67 /// The targeted size for a snapshot shard. This is not a hard limit. This number influences
68 /// (but not fully determines) number of shards used for snapshots.
69 pub target_snapshot_shard_size_bytes: usize,
70
71 /// Whether to make use of positioned writes e.g. write_at() instead of seek() + write().
72 /// This uses OS specific extensions and enables higher effective concurrency for writes.
73 pub use_positioned_writes: bool,
74}
75
76impl Default for Config {
77 fn default() -> Config {
78 Self {
79 snapshot_interval: 10000,
80 memory_bucket_count: 32,
81 sync_mode: SyncMode::BlockNoExplicitSync,
82 silent: false,
83 target_io_parallelism_snapshots: 8,
84 target_io_parallelism_writelog: 1,
85 target_snapshot_shard_size_bytes: 1024 * 1024 * 1024, // 1 GB
86
87 #[cfg(target_os = "windows")]
88 use_positioned_writes: false,
89 #[cfg(not(target_os = "windows"))]
90 use_positioned_writes: true,
91 }
92 }
93}