Skip to content

Commit a446af4

Browse files
author
Zorglub4242
committed
docs: Add HDD archive node documentation and performance analysis
Comprehensive documentation for running Kaspa archive nodes on HDD storage with performance optimization. Files added: - docs/archival.md: Complete guide for HDD archive nodes - Archive node requirements and use cases - Preset comparison and configuration details - Quick start examples (basic, HDD-optimized, dual-node) - Docker deployment examples - System tuning recommendations - Troubleshooting guide - docs/disk_virtualization.md: NVMe WAL performance analysis - Real-world benchmark data (3h 14m full sync on HDD+NVMe) - Cost-benefit analysis for hybrid storage - Configuration recommendations - Performance comparison vs pure HDD setup Based on real-world testing with archive preset: - Full sync time: ~3h 14m (HDD data + NVMe WAL) - Archive preset optimized for HDD with rate limiting - Tested pipelined write: degrades HDD performance by 62% Related: #681
1 parent d1c8beb commit a446af4

File tree

2 files changed

+1068
-0
lines changed

2 files changed

+1068
-0
lines changed

docs/archival.md

Lines changed: 387 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,387 @@
1+
# Running Kaspa Archive Nodes
2+
3+
This guide explains how to run a Kaspa archive node with HDD-optimized RocksDB configuration.
4+
5+
## What is an Archive Node?
6+
7+
An **archive node** stores the complete blockchain history, including all pruned data that normal nodes discard. Archive nodes are essential for:
8+
9+
- **Blockchain explorers** - Need complete transaction history
10+
- **Research and analytics** - Require access to historical data
11+
- **Compliance and auditing** - Legal requirements for data retention
12+
- **Network resilience** - Provide historical data to syncing peers
13+
14+
Normal Kaspa nodes are **pruned** and only keep recent blocks (determined by finality depth). Archive nodes keep everything.
15+
16+
## Storage Requirements
17+
18+
### Minimum Requirements
19+
- **Storage:** 500GB HDD minimum (2TB+ recommended)
20+
- **RAM:** 8GB minimum (16GB+ recommended with `--rocksdb-preset=archive`)
21+
- **CPU:** 4 cores
22+
- **Network:** Stable connection with sufficient bandwidth
23+
24+
## RocksDB Presets
25+
26+
Kaspad provides two RocksDB configuration presets optimized for different storage types:
27+
28+
### Default Preset (SSD/NVMe)
29+
```bash
30+
kaspad --archival
31+
# or explicitly:
32+
kaspad --archival --rocksdb-preset=default
33+
```
34+
35+
**Configuration:**
36+
- 64MB write buffer
37+
- Standard compression
38+
- Optimized for fast storage (SSD/NVMe)
39+
- Lower memory footprint
40+
41+
**Best for:** Archive nodes on SSD/NVMe storage
42+
43+
### Archive Preset (HDD)
44+
```bash
45+
kaspad --archival --rocksdb-preset=archive
46+
```
47+
48+
**Configuration:**
49+
- **256MB write buffer** (4x default) - Better write batching for HDDs
50+
- **BlobDB enabled** - Separates large values, reduces write amplification
51+
- **Aggressive compression:**
52+
- LZ4 for L0-L4 (fast compression for hot data)
53+
- ZSTD level 22 for L5+ (maximum compression for cold data)
54+
- 16KB dictionary compression with 1MB training
55+
- **12 MB/s rate limiter** - Prevents I/O spikes
56+
- **2GB LRU block cache** - Better read performance
57+
- **Level 0 compaction trigger: 1 file** - Minimizes write amplification
58+
- **4MB read-ahead** - Optimized for sequential HDD reads
59+
- **Partitioned Bloom filters** - Memory-efficient filtering
60+
61+
**Best for:** Archive nodes on HDD storage
62+
63+
**Memory requirements:** 8GB minimum, 16GB+ recommended
64+
65+
## Quick Start
66+
67+
### Basic Archive Node (SSD/NVMe)
68+
```bash
69+
# Default preset, suitable for SSD
70+
kaspad --archival \
71+
--rpclisten-borsh=0.0.0.0:17110 \
72+
--rpclisten-json=0.0.0.0:18110
73+
```
74+
75+
### HDD-Optimized Archive Node
76+
```bash
77+
# Archive preset with HDD optimizations
78+
kaspad --archival \
79+
--rocksdb-preset=archive \
80+
--ram-scale=1.0 \
81+
--rpclisten-borsh=0.0.0.0:17110 \
82+
--rpclisten-json=0.0.0.0:18110
83+
```
84+
85+
## Performance Tuning
86+
87+
### System-Level Optimizations (Linux)
88+
89+
For optimal HDD performance, tune kernel parameters:
90+
91+
```bash
92+
# /etc/sysctl.d/90-kaspad-archive.conf
93+
vm.dirty_ratio = 40
94+
vm.dirty_background_ratio = 20
95+
vm.dirty_expire_centisecs = 12000
96+
vm.dirty_writeback_centisecs = 1500
97+
vm.swappiness = 10
98+
vm.vfs_cache_pressure = 50
99+
```
100+
101+
Apply with: `sudo sysctl -p /etc/sysctl.d/90-kaspad-archive.conf`
102+
103+
Configure I/O scheduler for HDD (mq-deadline):
104+
```bash
105+
echo "mq-deadline" | sudo tee /sys/block/sda/queue/scheduler
106+
echo "4096" | sudo tee /sys/block/sda/queue/read_ahead_kb
107+
```
108+
109+
### RAM Scaling
110+
111+
Adjust memory allocation based on available RAM:
112+
113+
```bash
114+
# Limited RAM (8GB system)
115+
kaspad --archival --rocksdb-preset=archive --ram-scale=0.3
116+
117+
# Normal RAM (16GB system)
118+
kaspad --archival --rocksdb-preset=archive --ram-scale=0.5
119+
120+
# High RAM (32GB+ system)
121+
kaspad --archival --rocksdb-preset=archive --ram-scale=1.0
122+
```
123+
124+
**Note:** Archive preset requires ~8GB minimum even with `--ram-scale=0.3` due to RocksDB caches.
125+
126+
## Monitoring
127+
128+
### Check Archive Status
129+
```bash
130+
# Using kaspa-cli (if installed)
131+
kaspa-cli getinfo
132+
133+
# Check logs
134+
journalctl -u kaspad -f
135+
136+
# Check disk usage
137+
du -sh ~/.kaspa/kaspa-mainnet/datadir/
138+
```
139+
140+
### Performance Metrics
141+
```bash
142+
# Enable performance metrics
143+
kaspad --archival --rocksdb-preset=archive --perf-metrics --perf-metrics-interval-sec=60
144+
```
145+
146+
### Disk I/O Monitoring
147+
```bash
148+
# Monitor disk activity
149+
iostat -x 5
150+
151+
# Check write patterns
152+
iotop -o
153+
```
154+
155+
## Docker Deployment
156+
157+
### Docker Compose Example
158+
159+
**docker-compose.yml:**
160+
```yaml
161+
version: '3.8'
162+
163+
services:
164+
kaspad-archive:
165+
image: kaspanet/kaspad:latest
166+
container_name: kaspad-archive
167+
restart: unless-stopped
168+
command:
169+
- --archival
170+
- --rocksdb-preset=archive
171+
- --ram-scale=1.0
172+
- --rpclisten-borsh=0.0.0.0:17110
173+
- --rpclisten-json=0.0.0.0:18110
174+
- --utxoindex
175+
volumes:
176+
- /mnt/hdd/kaspa-archive:/app/data
177+
ports:
178+
- "16111:16111" # P2P
179+
- "17110:17110" # RPC Borsh
180+
- "18110:18110" # RPC JSON
181+
environment:
182+
- KASPAD_APPDIR=/app/data
183+
```
184+
185+
Run with: `docker-compose up -d`
186+
187+
### Docker with System Optimizations
188+
189+
For HDD optimization, configure host kernel parameters before starting the container.
190+
191+
**docker-run.sh:**
192+
```bash
193+
#!/bin/bash
194+
195+
# Apply system tuning
196+
sudo sysctl -w vm.dirty_ratio=40
197+
sudo sysctl -w vm.swappiness=10
198+
sudo sysctl -w vm.vfs_cache_pressure=50
199+
200+
# Set I/O scheduler
201+
echo "mq-deadline" | sudo tee /sys/block/sda/queue/scheduler
202+
203+
# Run container
204+
docker run -d \
205+
--name kaspad-archive \
206+
--restart unless-stopped \
207+
-v /mnt/hdd/kaspa-archive:/app/data \
208+
-p 16111:16111 \
209+
-p 17110:17110 \
210+
-p 18110:18110 \
211+
kaspanet/kaspad:latest \
212+
--archival \
213+
--rocksdb-preset=archive \
214+
--ram-scale=1.0 \
215+
--rpclisten-borsh=0.0.0.0:17110 \
216+
--rpclisten-json=0.0.0.0:18110 \
217+
--appdir=/app/data
218+
```
219+
220+
## Systemd Service
221+
222+
**Example systemd service for HDD archive node:**
223+
224+
**/etc/systemd/system/kaspad-archive.service:**
225+
```ini
226+
[Unit]
227+
Description=Kaspa Archive Node (HDD-optimized)
228+
After=network.target
229+
230+
[Service]
231+
Type=simple
232+
User=kaspa
233+
Group=kaspa
234+
ExecStart=/usr/local/bin/kaspad \
235+
--archival \
236+
--rocksdb-preset=archive \
237+
--ram-scale=1.0 \
238+
--appdir=/mnt/hdd/kaspa-archive \
239+
--rpclisten-borsh=0.0.0.0:17110 \
240+
--rpclisten-json=0.0.0.0:18110 \
241+
--utxoindex
242+
Restart=always
243+
RestartSec=10
244+
LimitNOFILE=65536
245+
246+
[Install]
247+
WantedBy=multi-user.target
248+
```
249+
250+
Enable and start:
251+
```bash
252+
sudo systemctl daemon-reload
253+
sudo systemctl enable kaspad-archive
254+
sudo systemctl start kaspad-archive
255+
sudo systemctl status kaspad-archive
256+
```
257+
258+
## Troubleshooting
259+
260+
### High Disk I/O
261+
**Symptoms:** System slow, high `iowait`
262+
263+
**Solutions:**
264+
1. Verify archive preset is active:
265+
```bash
266+
journalctl -u kaspad-archive | grep "RocksDB preset"
267+
# Should show: "Using RocksDB preset: archive"
268+
```
269+
2. Check I/O scheduler: `cat /sys/block/sda/queue/scheduler` (should be `mq-deadline`)
270+
3. Verify kernel tuning: `sysctl vm.dirty_ratio vm.swappiness`
271+
4. Lower `--ram-scale` if swapping occurs
272+
273+
### Out of Memory
274+
**Symptoms:** Process killed by OOM
275+
276+
**Solutions:**
277+
1. Archive preset needs minimum 8GB RAM
278+
2. Reduce `--ram-scale`:
279+
```bash
280+
# 8GB system
281+
kaspad --archival --rocksdb-preset=archive --ram-scale=0.3
282+
283+
# 16GB system
284+
kaspad --archival --rocksdb-preset=archive --ram-scale=0.5
285+
```
286+
3. Check swap: `free -h` (should have 8GB+ swap)
287+
4. Consider default preset on SSD instead
288+
289+
### Slow Sync Speed
290+
**Expected:** 10-20 blocks/sec on HDD with archive preset
291+
292+
**If slower:**
293+
1. Verify HDD not failing: `sudo smartctl -a /dev/sda`
294+
2. Check disk utilization: `iostat -x 5` (should be ~70-95%)
295+
3. Ensure system tuning applied
296+
4. Monitor memory: Archive preset uses more RAM but reduces disk I/O
297+
298+
### Preset Not Applied
299+
**Symptom:** Performance same as before
300+
301+
**Check:**
302+
```bash
303+
# Verify flag in service config
304+
systemctl cat kaspad-archive | grep rocksdb-preset
305+
306+
# Check startup logs
307+
journalctl -u kaspad-archive -n 100 | grep -i rocksdb
308+
309+
# Should see:
310+
# "Using RocksDB preset: archive - Archive preset - optimized for HDD"
311+
```
312+
313+
## Trade-offs
314+
315+
### Archive Preset vs Default
316+
317+
| Aspect | Default (SSD) | Archive (HDD) |
318+
|--------|---------------|---------------|
319+
| Write throughput | ~200 MB/s | ~100-150 MB/s |
320+
| Memory usage | ~4-6 GB | ~8-12 GB |
321+
| Disk usage | ~40 GB | ~35 GB (better compression) |
322+
| Sync time (HDD) | 2-3 days | 1-2 days |
323+
| Write amplification | ~20x | ~8-10x |
324+
| CPU usage | Low | Medium (compression) |
325+
326+
### When NOT to Use Archive Preset
327+
328+
- **SSD/NVMe storage** - Default preset is faster
329+
- **Limited RAM (<8GB)** - May cause OOM
330+
- **CPU-constrained** - Compression uses more CPU
331+
- **Low disk space** - BlobDB and caching use more temporary space
332+
333+
## Best Practices
334+
335+
1. **Use separate mount for archive data** - Protects system from filling up
336+
2. **Monitor disk health** - HDDs wear out; use SMART monitoring
337+
3. **Plan for growth** - ~10-20 GB/month, size accordingly
338+
4. **Backup strategy** - Archive data is valuable; back up regularly
339+
5. **Dual-node setup** - Fast node for queries, archive for history
340+
6. **System tuning** - Essential for HDD performance
341+
342+
## Performance Comparison
343+
344+
Based on real-world testing (Issue #681):
345+
346+
**Before (Default on HDD):**
347+
- Sync time: ~3-5 days
348+
- Frequent swap usage (10+ GB)
349+
- Write amplification: ~20x
350+
- Disk utilization: 60-80% (not bottlenecked)
351+
352+
**After (Archive Preset on HDD):**
353+
- Sync time: ~1.5-2 days
354+
- Minimal swap usage (<100 MB)
355+
- Write amplification: ~8-10x
356+
- Disk utilization: 95-99% (fully utilized)
357+
- 30-50% improvement in write throughput
358+
359+
## Additional Resources
360+
361+
- **Issue #681:** Original HDD optimization proposal
362+
- **System Tuning Guide:** Detailed kernel optimization guide
363+
- **Kaspa Discord:** #node-operators channel for support
364+
- **GitHub:** Report issues at kaspanet/rusty-kaspa
365+
366+
## Summary
367+
368+
For **HDD-based archive nodes**, use:
369+
```bash
370+
kaspad --archival --rocksdb-preset=archive
371+
```
372+
373+
This enables Callidon's HDD-optimized RocksDB configuration, providing:
374+
- ✅ 30-50% faster sync times on HDD
375+
- ✅ Reduced write amplification (50-60% reduction)
376+
- ✅ Better disk utilization (95%+ vs 60-80%)
377+
- ✅ Minimal swap usage despite larger working set
378+
- ⚠️ Requires 8GB+ RAM
379+
- ⚠️ Uses more CPU for compression
380+
381+
For **SSD/NVMe**, the default preset is optimal.
382+
383+
---
384+
385+
**Last updated:** November 2024
386+
**Applies to:** Kaspad v1.0.0+
387+
**Related:** Issue #681 - HDD Archive Node Optimization

0 commit comments

Comments
 (0)