EchoVault: Embeddable Redis Alternative in Go

Kelvin MwinukaKelvin Mwinuka
6 min read

I started working on an open-source project about a year ago to build an embeddable alternative to Redis in Go. That’s when I started building the EchoVault project. Since then, the project has gained some interest and even a few contributors.

This article introduces EchoVault, its features, use cases, and the motivations behind its development.

What is EchoVault?

EchoVault is an embeddable in-memory datastore tailored for Go applications. It provides a RESP-compatible interface over TCP while offering the flexibility to be embedded directly into applications.

By doing so, EchoVault aims to replace traditional in-memory data stores like Redis in some use cases, offering similar functionalities with enhanced integration for Go.

Why EchoVault was Built

My initial motivations for building EchoVault were:

  • Embedded Flexibility: Traditional in-memory data stores like Redis are external services that require separate management and deployment. EchoVault eliminates this overhead by allowing developers to embed the data store directly into their applications, streamlining the deployment process.

  • Go Ecosystem Integration: EchoVault is designed primarily for Go, ensuring seamless integration and optimal performance within Go applications. However, it also maintains RESP compatibility over TCP, making it compatible with existing Redis clients such as redis-cli and Jedis.

  • Redis License Changes: EchoVault is open-source (licensed under Apache 2.0). We’re committed to staying on this fully open-source model and not open-core.

Features Provided by EchoVault

EchoVault is packed with features that make it a robust choice for in-memory data storage:

  • TLS and mTLS Support: Secure communication with support for multiple server and client Root Certificate Authorities (RootCAs). Replication Cluster Support: Utilizes the RAFT algorithm for replication and clustering.

  • Access Control Layer: Provides user authentication and authorization to secure data access.

  • Distributed Pub/Sub Functionality: Supports publish/subscribe to channels and patterns for real-time data processing.

  • Data Structures: We support a variety of data structures, including sets, sorted sets, hashes, lists, and more. We are continuing to add more data structures and commands within them.

  • Persistence Layer: This layer ensures data durability with snapshot and append-only file persistence. The AOF files are RESP compatible but not yet fully Redis compatible.

  • Key Eviction Policies: Implements various strategies for key eviction to manage memory usage. EchoVault has passive and active key eviction. With passive key eviction, expired keys are not evicted until the next time they are accessed. With active eviction, EchoVault will proactively delete keys that are expired.

  • Command Extensions: Allows runtime extension of commands via shared object files and an embedded API.

The feature list continues to expand as we’re in the early stages of development. We have some more cool features lined up for the future, including:

  • Streams.

  • Extensions with Lua modules.

  • Sharding.

Architecture of EchoVault

EchoVault supports both standalone and clustered deployments.

Standalone Mode

In standalone mode, EchoVault operates a single (standalone) instance. This is the easiest way to run EchoVault. You can run a standalone instance from the embedded library or start it as its own process that accepts TCP connections. The embedded instance can also accept TCP connections, allowing you to communicate with your Go process from a TCP client.

RAFT Replication Cluster Mode

For applications requiring strong consistency and fault tolerance, EchoVault supports a RAFT-based replication cluster mode.

RAFT is a consensus algorithm that ensures data consistency across distributed systems. In this mode, multiple EchoVault instances can form a cluster, providing data replication and ensuring that data remains consistent even in the event of node failures.

Key Features of RAFT Cluster Mode:

  • Fault Tolerance: Ensures data availability even if some nodes in the cluster fail.

  • Consistency: Guarantees that all nodes in the cluster have the same data.

  • Scalability: Allows for horizontal scaling by adding more nodes to the cluster.

You can run EchoVault clusters even in embedded modes. This means that your application instances can communicate with each other through the EchoVault layer without having to deploy a third service. This is ideal for use cases such as session management across a cluster of an application’s instances.

Use Cases for EchoVault

EchoVault's versatility makes it suitable for a wide range of applications. Here are some potential use cases:

  • In-Memory Caching Scenario: An e-commerce website needs to cache product details and user session information to improve performance. Solution: Use EchoVault to cache frequently accessed data to speed up response times. Benefits: Faster page loads, improved user experience, and reduced database strain.

  • Service Discovery Scenario: A microservices architecture requires dynamic service discovery for inter-service communication. Solution: Store service endpoints in EchoVault, allowing services to discover and communicate with each other efficiently. Benefits: Simplified service discovery and enhanced communication efficiency.

  • Session Management Scenario: A distributed web application must manage user sessions across multiple instances. Solution: Use EchoVault embedded cluster to store session data, ensuring consistency and accessibility across all application instances. Benefits: Consistent session management across the application’s cluster without deploying a secondary service like Redis.

  • Real-Time Analytics Scenario: A financial trading platform requires real-time analytics and monitoring of trade data. Solution: Store and process real-time trade data in EchoVault, leveraging its sorted sets and pub/sub capabilities for tracking and analysis. Benefits: Real-time data processing and faster analytics.

  • Distributed Task Queue Scenario: A backend system needs to manage and distribute tasks to multiple worker nodes. Solution: Implement a task queue using EchoVault's list data structure, where tasks are pushed onto the list and worker nodes pop tasks for processing. Benefits: Efficient task distribution and scalability.

  • Feature Flags and Configuration Management Scenario: A SaaS application needs to dynamically enable or disable features and manage configuration settings without redeploying the application. Solution: Store feature flags and configuration settings in EchoVault. Benefits: Dynamic configuration management and reduced downtime.

  • Rate Limiting and Throttling Scenario: An API gateway needs to enforce rate limits and throttle requests to prevent abuse and ensure fair usage. Solution: Implement rate limiting using EchoVault's in-memory capabilities to track request counts and enforce limits in real-time. Benefits: Effective rate limiting and improved API reliability.

  • Leader Election Scenario: A cluster of distributed services needs to elect a leader to coordinate tasks. Solution: Rely on EchoVault's embedded distributed cluster’s leader election to ensure that only one application instance is designated as the leader. Benefits: Reliable leader election and improved coordination without implementing it yourself at the application level.

Conclusion

EchoVault is an ambitious project. In these early stages, we expect many kinks to have to be ironed out and many features to be added. However, we welcome this challenge and would love to get the Go community involved in the project.

If this article has triggered your curiosity, or you’re interested in contributing to a project like this, check out our GitHub and drop us a star! We’re always open to more feedback and contributions!

2
Subscribe to my newsletter

Read articles from Kelvin Mwinuka directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Kelvin Mwinuka
Kelvin Mwinuka