Fără Descriere

Danilo Fragoso c5220654ca harden durable PKBFI scans 2 zile în urmă
bin 3920048461 fix memory leak 7 luni în urmă
.gitignore c5220654ca harden durable PKBFI scans 2 zile în urmă
README.md 4608009b97 implement durable pkvdb engine 1 săptămână în urmă
benchmark.zig 4608009b97 implement durable pkvdb engine 1 săptămână în urmă
benchmark_heavy.sh a5a4da609d add benchmark results 9 luni în urmă
benchmark_heavy_redis.sh a5a4da609d add benchmark results 9 luni în urmă
benchmark_no_pipeline.sh a5a4da609d add benchmark results 9 luni în urmă
benchmark_no_pipeline_redis.sh a5a4da609d add benchmark results 9 luni în urmă
command.zig 4608009b97 implement durable pkvdb engine 1 săptămână în urmă
engine.zig c5220654ca harden durable PKBFI scans 2 zile în urmă
keydir.zig 4608009b97 implement durable pkvdb engine 1 săptămână în urmă
main.zig 4608009b97 implement durable pkvdb engine 1 săptămână în urmă
makefile 4608009b97 implement durable pkvdb engine 1 săptămână în urmă
migration.zig 4608009b97 implement durable pkvdb engine 1 săptămână în urmă
ordered_index.zig 4608009b97 implement durable pkvdb engine 1 săptămână în urmă
pkbfi.zig c5220654ca harden durable PKBFI scans 2 zile în urmă
pkvdb.zig 4608009b97 implement durable pkvdb engine 1 săptămână în urmă
redis.zig 4608009b97 implement durable pkvdb engine 1 săptămână în urmă
requirements.md b26ab44fd7 first commit 10 luni în urmă
socket.zig 4608009b97 implement durable pkvdb engine 1 săptămână în urmă

README.md

🍕 PizzaKV

An in-memory key-value store written in Zig with Redis protocol compatibility and persistent storage.

Overview

PizzaKV is a concurrent key-value database that implements a subset of the Redis RESP (REdis Serialization Protocol), allowing it to work with Redis clients for supported commands. It also supports a simpler custom protocol (Pizzaria Protocol) using \r delimiters. Built from scratch in Zig.

Features

  • Dual Protocol Support:
    • RESP (Redis Serialization Protocol) - subset implementation compatible with Redis clients
    • Pizzaria Protocol - simple \r-delimited custom protocol
  • Persistent Storage: Append-only file (AOF) persistence with buffered writes
  • Prefix Search: Built-in radix tree index for efficient prefix-based queries
  • Thread-Safe: Concurrent operations using sharded hash tables and RwLocks
  • Zero Dependencies: Pure Zig implementation with no external dependencies

Supported Commands

RESP Protocol (Redis-compatible)

  • SET key value - Store a key-value pair
  • GET key - Retrieve a value by key
  • DEL key - Delete a key

Pizzaria Protocol (\r-delimited)

  • write key|value - Write a key-value pair (key and value separated by |)
  • read key - Read a value by key
  • delete key - Delete a key
  • keys - Get all keys (using radix tree)
  • reads prefix - Get all values for keys matching a prefix
  • status - Server status check

Architecture

Core Components

  • Sharded Hash Table: 64 shards with 1,048,576 total buckets for parallel access
  • Radix Tree Index: Fast prefix search and key enumeration
  • Persistence Layer: 8MB write buffer with automatic flushing
  • TCP Server: Async I/O with connection pooling

Concurrency Model

  • Per-shard RwLocks: Allow concurrent reads within each shard
  • Global tree mutex: Protects radix tree modifications
  • Atomic connection tracking: For graceful shutdown

Building

# Build optimized binary
make build

# Clean build artifacts
make clean

Running

# Start server in Redis mode (RESP protocol, port 8085)
./pizzakv -redis

# Start server in Pizzaria mode (\r-delimited protocol, port 8085)
./pizzakv

# Custom port
./pizzakv -port=9000

# Unix socket mode (creates .pizzakv.sock in current directory)
./pizzakv -unix
./pizzakv -unix -redis

# The server will create a .db file for persistence.
# In unix mode, a .pizzakv.sock file is also created and removed on shutdown.

Benchmarking

PizzaKV includes comprehensive benchmark suites comparing against Redis:

# Heavy workload benchmarks (with pipelining)
./benchmark_heavy.sh              # PizzaKV
./benchmark_heavy_redis.sh        # Redis comparison

# No-pipeline benchmarks (raw latency)
./benchmark_no_pipeline.sh        # PizzaKV
./benchmark_no_pipeline_redis.sh  # Redis comparison

Performance Comparison

Heavy Workload (With Pipelining, P=32)

Both systems tested with AOF persistence enabled.

Test PizzaKV Redis (AOF) Winner
Write Load (1M × 256B) 363K ops/sec
7.88ms p50
571K ops/sec
4.87ms p50
Redis 1.57×
Read Load (1M reads) 1.29M ops/sec
1.06ms p50
1.33M ops/sec
2.18ms p50
PizzaKV (latency)
Large Values (100k × 10KB) 133K ops/sec
3.98ms p50
80K ops/sec
3.34ms p50
PizzaKV 1.67×
Extreme Concurrency (200 clients) 333K writes
965K reads
500K writes
998K reads
Redis

No-Pipeline Performance (P=1, Raw Latency)

Single-request latency comparison - the true test of performance.

Test PizzaKV p50 Redis p50 Improvement
Small Writes (256B) 0.159ms 0.295ms 46% faster
Small Reads 0.175ms 0.207ms 15% faster
Medium Writes (1KB) 0.175ms 0.255ms 31% faster
Medium Reads (1KB) 0.159ms 0.175ms 9% faster
Large Writes (10KB) 0.111ms 0.199ms 44% faster ⚡⚡⚡
Large Reads (10KB) 0.095ms 0.103ms 8% faster
High Concurrency (100 clients) 0.303ms 0.327ms 7% faster

Summary

  • Single-request latency (P=1): 0.095ms - 0.303ms across all tests
  • Lower latency than Redis on most single-request operations
  • Higher throughput than Redis on 10KB payloads with pipelining
  • Read throughput reaches 1.3M+ ops/sec with pipelining
  • No crashes observed during benchmark runs
  • Handles 1.2GB persistence file without degradation

Technical Details

Memory Management

  • Arena allocators for hash table entries (per-shard)
  • Arena allocator for radix tree nodes
  • C allocator for temporary operations

Hash Function

  • FNV-1a hash with bit mixing for uniform distribution
  • Minimizes collisions across 1M buckets

Persistence Format

Simple append-only format:

OPCODE|key|value\r
  • W|key|value\r - Write operation
  • D|key|\r - Delete operation

Thread Safety

  • Shard-level RwLocks for concurrent hash table access
  • Global mutex for radix tree operations
  • Atomic counters for connection tracking

Project Structure

pizzakv/
├── main.zig           # Server, connection handling
├── storage.zig        # Sharded hash table
├── index.zig          # Radix tree for prefix search
├── persistence.zig    # AOF persistence layer
├── hashing.zig        # Hash function
├── redis.zig          # RESP protocol parser
├── command.zig        # Command execution
├── socket.zig         # TCP and Unix socket operations
└── benchmark_*.sh     # Benchmark scripts

Notes

  • This implements a subset of RESP, not the full Redis protocol
  • RESP commands are limited to SET, GET, and DEL
  • The Pizzaria protocol provides additional commands (prefix search)
  • Built with Zig 0.15.1 using -O ReleaseFast optimization