# Remote Hash Map A distributed node cluster management system using gRPC, implementing a replicated key-value store. ## Table of Contents - [Features](#features) - [Architecture](#architecture) - [Getting Started](#getting-started) - [Prerequisites](#prerequisites) - [Installation](#installation) - [Usage](#usage) - [Running the Node Group](#running-the-node-group) - [Running Individual Nodes](#running-individual-nodes) - [Using the Client](#using-the-client) - [Docker Support](#docker-support) - [Configuration](#configuration) - [Logging](#logging) - [Troubleshooting](#troubleshooting) - [Contributing](#contributing) - [License](#license) ## Features - Distributed key-value storage - Node cluster management - Health checking via regular pinging - Data replication across nodes - Configurable ping intervals - Docker support for easy deployment ## Architecture The system consists of two main components: 1. **Node**: Individual servers capable of storing key-value pairs and responding to ping requests. 2. **NodeGroup**: A manager for the node cluster, handling node addition, retrieval, and health monitoring. ## Getting Started ### Prerequisites - Rust (with Cargo package manager) - protoc (Protocol Buffers compiler) for gRPC - Docker (optional, for containerized deployment) ### Installation 1. Clone the repository: ```bash git clone https://github.com/kwdowicz/remote_hash_map.git cd remote_hash_map ``` 2. Build the project: ```bash cargo build --release ``` ## Usage ### Running the Node Group Start the NodeGroup service: ```bash ./target/release/ng --listen 127.0.0.1:5000 ``` ### Running Individual Nodes Run nodes and connect them to the NodeGroup: ```bash ./target/release/node --listen 127.0.0.1:6001 --ng 127.0.0.1:5000 ./target/release/node --listen 127.0.0.1:6002 --ng 127.0.0.1:5000 ``` ### Using the Client 1. Create a new project: ```bash mkdir rhm_test && cd rhm_test cargo init cargo add remote_hash_map tokio ``` 2. Add the following to `src/main.rs`: ```rust use remote_hash_map::common::client::Client; #[tokio::main] async fn main() -> Result<(), Box> { let mut client = Client::connect("127.0.0.1:5000").await?; client.set("name", "Daria").await?; client.set("name", "Tosia").await?; client.set("name", "Gabi").await?; let result = client.get("name").await?; println!("Name: {}", result); Ok(()) } ``` 3. Run the client: ```bash cargo run ``` ## Using grpcurl example ```bash grpcurl -plaintext -d '{"key": "name", "value": "Tas", "replication": true }' 127.0.0.1:5021 node_rpc.NodeRpc/Set grpcurl -plaintext -d '{}' 127.0.0.1:5000 node_group_rpc.NodeGroupRpc/GetServer ``` ## Docker Support Build and run using Docker: ```bash docker build -t remote_hash_map . docker network create --subnet=192.168.0.0/16 my_network docker run --name ng --network my_network --ip 192.168.0.3 remote_hash_map ng docker run --name node --network my_network --ip 192.168.0.4 -e NG_ADDRESS="192.168.0.3:5000" remote_hash_map node ``` ## Configuration - Ping interval can be configured for the NodeGroup: ```bash ./target/release/ng --listen 127.0.0.1:5000 --ping-sec 4 ``` ## Logging The project uses `env_logger`. Set the `RUST_LOG` environment variable for different log levels: ```bash RUST_LOG=debug ./target/release/node --listen 127.0.0.1:6001 --ng 127.0.0.1:5000 ``` ## Troubleshooting - Ensure all dependencies are installed and properly configured. - Verify that specified ports are not in use or blocked by firewalls. - Check log output for errors or warnings. ## Contributing Contributions are welcome! Please submit a pull request or open an issue to discuss proposed changes or improvements. ## License This project is licensed under the MIT License.