This repository contains the code for the Assignment-1 of Distributed Systems(CS60002) course of Spring, 2024.
sudo apt-get update
sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
sudo curl -SL https://github.com/docker/compose/releases/download/v2.15.1/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
To create the necessary Docker images for the load balancer and servers, execute the following command:
make install
To initiate the deployment of load balancer containers, execute the following command:
make deploy
This command will launch the load balancer container, which, in turn, will spawn the initial N server Docker containers along with their heartbeat probing threads. Ensure that the necessary configurations are in place for a seamless deployment. The command also clears any existing containers using server or load balancer image (i.e. execute make clean).
Note: The deployment command launches Docker in the background mode. Therefore, users are advised to check the docker-compose logs to view load-balancer logs.
To interact with the load balancer and send GET/POST requests, launch the interactive terminal using the following command:
bash client.sh
To stop and remove all containers using the server image and load balancer, run the following command:
make clean
Executing this command is recommended before running the main code to ensure there are no conflicting container instances already running. This helps prevent potential errors and ensures a clean environment for the code execution.
To remove previously created server and load balancer images, execute the following command:
make deepclean
It is advisable to run this command before executing the main code to eliminate any pre-existing images with the same name. This ensures a clean slate and avoids potential conflicts during the code execution.
- When executing the /add endpoint, users may provide existing server hostnames as part of the request. In such cases, the load balancer takes a proactive approach to ensure that the specified num_add parameter is honored. Even if the user supplies hostnames that already exist in the system, the load balancer will ignore already existing hostnames and generate new hostnames for additional servers to fulfill the exact count specified by num_add.
- When executing the /rm endpoint, users may provide hostnames for removal. To ensure the specified number of servers to be removed is consistently achieved, the load balancer employs a strategy wherein, if the user-provided hostname doesn't exist in the system, it randomly selects and removes a server hostname from the existing set.
- Every server is equipped with a heartbeat thread that sends a heartbeat message every 0.2 seconds. If no heartbeat is detected for two consecutive attempts, the server is declared dead, triggering the spawning of a new server. This mechanism prevents premature declarations of server death due to network fluctuations, ensuring stability in the system.
Code 137 indicated RAM memory related issue. Stop and remove already runining container to free up space.
Particular container: docker stop container_id
Stop all runing container: docker stop $(docker ps -a -q)
Particular container: docker rm container_id
Stop all runing container: docker rm $(docker ps -a -q)
To analyze the distribution load of 10,000 asynchronous requests on N=3 servers, follow these commands:
cd analysis
python analysis.py
The analysis.py script sends 10,000 asynchronous requests (/home requests) to the load balancer. Based on the responses received, it plots a frequency map illustrating how many responses come from each server.
Ensure that the necessary dependencies are installed and the system is properly configured before executing the analysis script.
Modify the NUM_INITIAL_SERVERS = 3 line number 9 of load_balancer/client_handler.py
with 2 to 6 and run analysis.py to get average load and standard distribution of load distribution.
Follow folder analysis/old_hash/
for exact distribution bar plots.
To analyze the server failure scenario execute the following:
cd analysis
python kill_server.py
The kill_server.py script is designed to simulate the process of killing a server, validating the functionality of all endpoints in the event of server failure, and assessing the prompt respawn of the server. The effectiveness of server respawn is verified through the analysis of load distribution and the count of dropped requests(failed) during the time it takes for the heartbeat mechanism to detect and respawn the server.
After testing all the 9 combinations of SHA-256, SHA-1, and MD5 hashing functions for request and server hashings, we found that the most effective combination is:
- Server Hashing: SHA-1
- Request Hashing: MD5
To implement this new hash function configuration, follow these steps:
-
Open the file
load_balancer/consistent_hashing.py
and locate theserver_hash_func
andrequest_hash_func
definition. -
Comment the alternative hash function provided.
-
Save the changes.
-
Re-run the analysis script after deploying the load balancer again.
-
Ensure that you have cleared previous containers and images, and rebuild the project before executing the analysis script. This ensures that the new hash function is applied to the load balancer and the analysis is based on the updated configuration.
The evaluation results of new hash function on variable number of servers are present in analysis/md5_hash
- Pranav Mehrotra (20CS10085)
- Saransh Sharma (20CS30065)
- Pranav Nyati (20CS30037)
- Shreyas Jena (20CS30049)