Skip to content

rasheemcodes/redis-c

Repository files navigation

Redis Clone in C

A Redis-compatible server implementation in C, supporting basic RESP protocol commands.

Features

  • PING/PONG - Basic connectivity test
  • SET - Store key-value pairs
  • GET - Retrieve values by key
  • Multi-threaded - Handles multiple concurrent clients
  • RESP Protocol - Full RESP encoding/decoding support
  • Thread-safe - Hash map with mutex protection

Project Structure

redis-c/
├── src/
│   ├── main.c          # Server main loop and command handling
│   ├── decode.c        # RESP protocol decoder
│   ├── encode.c        # RESP protocol encoder
│   ├── hash_map.c      # Thread-safe hash map implementation
│   ├── resp.h          # RESP types and declarations
│   └── hash_map.h      # Hash map declarations
├── CMakeLists.txt      # CMake build configuration
└── run_server.sh       # Helper script to run server

Prerequisites

  • CMake (version 3.13 or higher)
  • GCC or compatible C compiler (C11 standard)
  • redis-cli for testing

Install on Ubuntu/Debian:

sudo apt-get install cmake build-essential redis-tools

Building

# Clone or navigate to project directory
cd redis-c

# Build the project
mkdir -p build
cd build
cmake ..
make
cd ..

The executable will be created at build/redis.

Running the Server

Method 1: Using the helper script

./run_server.sh

Method 2: Direct execution

./build/redis

The server will start and listen on port 6379. You'll see:

Redis server starting...
Server listening on port 6379
Ready to accept connections.

Press Ctrl+C to stop the server.

Testing the Server

Using redis-cli (Interactive Testing)

Use redis-cli to test the server. It's the official Redis command-line interface and handles RESP protocol automatically.

Installation

# Ubuntu/Debian
sudo apt-get install redis-tools

# macOS
brew install redis

Basic Usage

Terminal 1 - Start the server:

./run_server.sh

Terminal 2 - Connect with redis-cli:

redis-cli -p 6379

Commands in redis-cli

Once connected, you can use normal Redis commands:

127.0.0.1:6379> PING
PONG

127.0.0.1:6379> SET mykey "Hello World"
OK

127.0.0.1:6379> GET mykey
"Hello World"

127.0.0.1:6379> GET nonexist
(nil)

127.0.0.1:6379> SET foo bar
OK

127.0.0.1:6379> GET foo
"bar"

127.0.0.1:6379> EXIT

One-line Commands

You can also run commands directly without entering interactive mode:

redis-cli -p 6379 PING
# Output: PONG

redis-cli -p 6379 SET mykey "Hello"
# Output: OK

redis-cli -p 6379 GET mykey
# Output: "Hello"

Performance Benchmarking

Using redis-benchmark (Recommended)

redis-benchmark is the official Redis performance testing tool. It's much faster and more accurate than custom scripts.

Installation

# Ubuntu/Debian
sudo apt-get install redis-tools

# macOS
brew install redis

Quick Benchmark

Terminal 1 - Start the server:

./run_server.sh

Terminal 2 - Run benchmark:

# 1 million SET operations with 50 concurrent clients
redis-benchmark -h localhost -p 6379 -t set -n 1000000 -c 50

# 1 million GET operations
redis-benchmark -h localhost -p 6379 -t get -n 1000000 -c 50

# PING test
redis-benchmark -h localhost -p 6379 -t ping -n 100000 -c 50

Using the Benchmark Script

We provide a convenient wrapper script:

# Default: 1M SET requests with 50 clients
./tests/redis-benchmark.sh

# Custom options
./tests/redis-benchmark.sh -n 1000000 -c 50 -t set
./tests/redis-benchmark.sh -n 100000 -c 10 -t get

# Run all tests (PING, SET, GET)
./tests/redis-benchmark.sh --all

# See all options
./tests/redis-benchmark.sh --help

Benchmark Output Example

====== SET ======
  1000000 requests completed in 45.23 seconds
  50 parallel clients
  3 bytes payload
  keep alive: 1
  host configuration "save": 
  host configuration "appendonly": no
  multi-thread: no

0.00% <= 1 milliseconds
95.50% <= 2 milliseconds
99.90% <= 3 milliseconds
100.00% <= 4 milliseconds

22105.12 requests per second

Common Benchmark Commands

Command Description
redis-benchmark -h localhost -p 6379 -t set -n 1000000 -c 50 1M SET operations, 50 clients
redis-benchmark -h localhost -p 6379 -t get -n 1000000 -c 50 1M GET operations, 50 clients
redis-benchmark -h localhost -p 6379 -t ping -n 100000 -c 50 100K PING operations
redis-benchmark -h localhost -p 6379 -t set,get -n 100000 -c 10 Mixed SET/GET test

RESP Protocol Format

Commands are sent in RESP (Redis Serialization Protocol) format:

  • *N - Array with N elements
  • $N - Bulk string of length N
  • +text - Simple string
  • -text - Error
  • :number - Integer

Example: SET Command

The command SET mykey "Hello World" in RESP format:

*3          ← Array with 3 elements
$3          ← Bulk string of length 3
SET         ← Command name
$5          ← Bulk string of length 5
mykey       ← Key
$11         ← Bulk string of length 11
Hello World ← Value

Note: You don't need to know RESP format when using redis-cli - it handles this automatically!


Implementation Details

Architecture

  • Multi-threaded server using pthread for concurrent client handling
  • Thread-safe hash map with mutex protection for GET/SET operations
  • RESP parser with proper error handling and bounds checking
  • Memory management with proper cleanup of all allocated resources

Commands Supported

Command Description redis-cli Example
PING Returns PONG PING
SET key value Store key-value pair SET foo bar
GET key Retrieve value by key GET foo

Error Handling

  • Invalid commands return error responses
  • Incomplete messages are buffered until complete
  • Protocol errors are handled gracefully

Development

Building for Development

cd build
cmake -DCMAKE_BUILD_TYPE=Debug ..
make

Code Structure

  • main.c - Server socket handling, command processing
  • decode.c - RESP parsing from network bytes
  • encode.c - RESP encoding to network bytes
  • hash_map.c - Dictionary/hash table implementation

Troubleshooting

Port already in use

# Find and kill existing process
lsof -ti:6379 | xargs kill -9
# Or
pkill -f redis

Connection refused

  • Make sure the server is running in another terminal
  • Check that port 6379 is not blocked by firewall
  • Verify server started successfully (check for "Server listening" message)

redis-cli not found

# Install redis-tools
sudo apt-get install redis-tools  # Ubuntu/Debian
brew install redis                # macOS

Commands not working

  • Check server logs for error messages
  • Make sure you're using correct Redis command syntax
  • Verify the server is running and listening on port 6379

Files Reference

Required Files

  • .codecrafters/ - Keep if submitting to CodeCrafters platform, otherwise not needed
  • your_program.sh - Keep if submitting to CodeCrafters platform, otherwise not needed
  • CMakeLists.txt - Required for building
  • src/ - Source code (required)

Optional Files

  • run_server.sh - Helper script (optional, but recommended)
  • tests/redis-benchmark.sh - Benchmark script using redis-benchmark (recommended)
  • tests/stress-test.sh - Custom stress test script (alternative)
  • build/ - Build directory (auto-generated, can be deleted)

Quick Start Summary

  1. Build:

    mkdir -p build && cd build && cmake .. && make && cd ..
  2. Run server:

    ./run_server.sh
  3. Test:

    redis-cli -p 6379

    Then type commands like PING, SET foo bar, GET foo


License

This project is part of the CodeCrafters Redis challenge.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •