Skip to content

Commit aad85cf

Browse files
author
test
committed
Snapshoting
1 parent 1d81160 commit aad85cf

19 files changed

Lines changed: 567 additions & 14 deletions

Cargo.lock

Lines changed: 33 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ edition = "2024"
55

66
[dependencies]
77
actix-web = { version = "4", features = ["openssl"] }
8-
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
8+
tokio = { version = "1", features = ["rt-multi-thread", "macros", "fs"] }
99
reqwest = { version = "0.12.15", features = ["json"] }
1010
futures-util = "0.3.31"
1111
serde_json = "1.0.140"
@@ -20,6 +20,7 @@ openssl = { version = "0.10", features = ["vendored"] }
2020
chrono = "0.4.40"
2121
jsonwebtoken = "9.3.1"
2222
log = "0.4.27"
23+
bincode = { version = "2.0", features = ["derive"] }
2324

2425
[dev-dependencies]
2526
actix-test = { version = "0.1.0-beta.13" }

README.md

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
<h1 align="center">🦀 DynaRust: Distributed Key-Value Store</h1>
1+
# 🦀 DynaRust: Distributed Key-Value Store
22

3-
DynaRust is a distributed key‑value store built in Rust. It's designed to be reliable and easy to manage, allowing you to add or remove nodes (servers) dynamically without interrupting service 🔄.
3+
DynaRust is a distributed key‑value store built in Rust 🦀. It's designed to be reliable 💪 and easy to manage, allowing you to add or remove nodes (servers) dynamically without interrupting service 🔄.
44

5-
Think of it as a shared dictionary spread across multiple computers 💻↔️💻. You can store data (key‑value pairs), retrieve it, and delete it using a simple web API 🔌. DynaRust automatically copies your data across available nodes for high availability and synchronizes changes over time (eventual consistency). It stores data in memory for speed ⚡️ and persists it to disk (`storage.db`) so your data remains safe even if a node restarts.
5+
Think of it as a shared dictionary 📚 spread across multiple computers 💻↔️💻. You can store data (key‑value pairs), retrieve it, and delete it using a simple web API 🔌. DynaRust automatically copies your data across available nodes for high availability and synchronizes changes over time (eventual consistency). It stores data in memory for speed ⚡️ and persists it to disk (`storage.db`) 💾 so your data remains safe even if a node restarts.
66

7-
With its advanced real‑time update capabilities, DynaRust pushes live changes with latencies below 5 ms 🚀. In fact, on a typical VPS (1 GB RAM, 100 Mbps bandwidth), a single node can comfortably sustain peak traffic of up to **5000 live connections**—and you can increase capacity even further simply by adding more nodes to your cluster!
7+
With its advanced real‑time update capabilities, DynaRust pushes live changes with latencies below 5 ms 🚀. In fact, on a typical VPS (1 GB RAM, 100 Mbps bandwidth), a single node can comfortably sustain peak traffic of up to **5000 live connections** 🔥—and you can increase capacity even further simply by adding more nodes to your cluster!
88

99
---
1010
## Performance
@@ -38,6 +38,10 @@ With its advanced real‑time update capabilities, DynaRust pushes live changes
3838

3939
* **Use Case Example:** Imagine a web UI needing push notifications. Store device IDs as keys in a `devices` table. Use a separate `status` key in the same table. The frontend listens to `devices/subscribe/status`. The backend iterates through device keys, performs actions, and updates the `status` key, instantly notifying all listening frontends. Simple and blazing fast! ⚡️
4040

41+
* **🔒 Security:**
42+
Certainly! Here’s a more polished and highlighted version of the **Security** section, emphasizing clarity and best practices:
43+
44+
---
4145

4246
### 🔒 **Security**
4347

@@ -50,10 +54,10 @@ With its advanced real‑time update capabilities, DynaRust pushes live changes
5054
- Each node must present a **secret token** (set via the `CLUSTER_SECRET` environment variable) to join the cluster, ensuring only trusted nodes participate.
5155

5256
- **Transport Security (HTTPS):**
53-
- All communication is secured with HTTPS (if enabled).
57+
- All communication is secured with HTTPS by default.
5458
- **Easy Certificate Generation:**
5559
- Run `bash cert.sh`, provide a password, and a `.p12` certificate will be generated under the `cert/` directory.
56-
- **How to enable HTTPS Mode:**
60+
- **Testing Mode:**
5761
- Set `DYNA_MODE=https` to enable HTTPS
5862

5963
---
@@ -62,6 +66,11 @@ With its advanced real‑time update capabilities, DynaRust pushes live changes
6266
* **🌐 Distributed Storage:**
6367
Data is automatically partitioned and spread across all nodes in the cluster.
6468

69+
* **🗄️ Automatic Snapshots:**
70+
Every 60 minutes DynaRust writes a JSON snapshot of the entire in‑memory store to `./snapshots/snapshot_<ts>.json`.
71+
By default only the last 100 snapshots are kept; older files are pruned automatically.
72+
You can override the retention limit with the `SNAP_LIMIT` environment variable (e.g. `SNAP_LIMIT=200`).
73+
6574
* **✅ High Availability:**
6675
If one node fails, the remaining nodes continue to serve requests for the available data.
6776

@@ -176,12 +185,12 @@ All operations except **GET** require a valid JWT in the `Authorization: Bearer
176185
- `404 Not Found` if table missing
177186
178187
6. **🔑 List or Batch‑Fetch Keys**
179-
6.1 **GET** `/{table}/keys`
188+
6.1 **GET** `/default/keys`
180189
`200 OK`
181190
```json
182191
["key1","key2",…]
183192
```
184-
6.2 **POST** `/{table}/keys`
193+
6.2 **POST** `/default/keys`
185194
- Body:
186195
```json
187196
["key1","key2","key3"]
@@ -197,7 +206,7 @@ All operations except **GET** require a valid JWT in the `Authorization: Bearer
197206
198207
7. **🔔 Subscribe to Real‑Time Updates (SSE)**
199208
Instant updates on a single key.
200-
- URL: `/{table}/subscribe/mykey`
209+
- URL: `/default/subscribe/mykey`
201210
- Usage:
202211
```bash
203212
curl -N http://localhost:6660/default/subscribe/mykey
@@ -306,11 +315,11 @@ DynaRust uses eventual consistency via state synchronization:
306315
+------------------------------------+
307316
308317
│ periodic
309-
│ snapshot
318+
│ snapshot & WAL
310319
311320
+-----------------------+
312321
| Disk Persistence |
313-
| (cold_save) |
322+
| (cold_save, WAL) |
314323
| 💾 |
315324
+-----------------------+
316325
@@ -328,7 +337,7 @@ Legend:
328337
• In‐Memory Store: local hashmaps of VersionedValue {value,version,timestamp,owner}.
329338
• Replication Module: fan‑out writes to peers using `X-Internal-Request`.
330339
• Other Nodes: receive internal requests, update memstore (no auth, no events).
331-
• Disk Persistence: periodic snapshots
340+
• Disk Persistence: periodic snapshots + WAL for durability.
332341
• Cluster Membership: heartbeat sync via broadcaster tasks for node discovery.
333342
• SSE Subscriptions: real‐time `EventSource` streams on `/subscribe/{key}`.
334343

cert.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
CERT_DIR="./cert"
6+
mkdir -p "$CERT_DIR"
7+
8+
# 1. Generate CA key and certificate
9+
openssl genrsa -out "$CERT_DIR/ca.key" 4096
10+
openssl req -x509 -new -nodes -key "$CERT_DIR/ca.key" -sha256 -days 3650 \
11+
-out "$CERT_DIR/ca.crt" \
12+
-subj "/C=US/ST=State/L=City/O=MyOrg/OU=OrgUnit/CN=MyRootCA"
13+
14+
# 2. Generate server key and CSR
15+
openssl genrsa -out "$CERT_DIR/server.key" 4096
16+
openssl req -new -key "$CERT_DIR/server.key" -out "$CERT_DIR/server.csr" \
17+
-subj "/C=US/ST=State/L=City/O=MyOrg/OU=OrgUnit/CN=localhost"
18+
19+
# 3. Sign server certificate with CA
20+
openssl x509 -req -in "$CERT_DIR/server.csr" -CA "$CERT_DIR/ca.crt" -CAkey "$CERT_DIR/ca.key" \
21+
-CAcreateserial -out "$CERT_DIR/server.crt" -days 365 -sha256
22+
23+
# 4. Generate client key and CSR
24+
openssl genrsa -out "$CERT_DIR/client.key" 4096
25+
openssl req -new -key "$CERT_DIR/client.key" -out "$CERT_DIR/client.csr" \
26+
-subj "/C=US/ST=State/L=City/O=MyOrg/OU=OrgUnit/CN=client"
27+
28+
# 5. Sign client certificate with CA
29+
openssl x509 -req -in "$CERT_DIR/client.csr" -CA "$CERT_DIR/ca.crt" -CAkey "$CERT_DIR/ca.key" \
30+
-CAcreateserial -out "$CERT_DIR/client.crt" -days 365 -sha256
31+
32+
33+
# 6. Combine client cert and key for clients that need a single PEM
34+
cat "$CERT_DIR/client.crt" "$CERT_DIR/client.key" > "$CERT_DIR/client-combined.pem"
35+
cd $CERT_DIR
36+
openssl pkcs12 -export -out client.p12 -inkey client.key -in client.crt -certfile ca.crt
37+
38+
echo "All certificates and keys have been generated in $CERT_DIR"
39+

cert/ca.crt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
-----BEGIN CERTIFICATE-----
2+
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
32+
qNHjcM746Q==
33+
-----END CERTIFICATE-----

cert/ca.key

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
-----BEGIN PRIVATE KEY-----
2+
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
51+
MkTSeDBqmjeqz/jomyKVDL48dF885Hw=
52+
-----END PRIVATE KEY-----

cert/ca.srl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
5A8DC566AB8E09C799D1B38373CA3C19676BD551

0 commit comments

Comments
 (0)