Overview of Distributed Computing Systems
Overview of Distributed Computing Systems
Practical 1
Aim: Study any two realtime distributed computing system developed
based on distributed computing system models. (ARPAnet, Sprite System,
Experimental System, Amoeba, Plan 9 and Cambridge Distributed
Computing System).
1) Amoeba:
Amoeba is a distributed operating system designed to provide a transparent and efficient
computing environment across multiple machines. The main goal of Amoeba is to enable the
seamless use of distributed resources as if they were a single coherent system. The working
process of Amoeba can be understood by examining its key components and their
interactions:
Working Process:
• Initialization:
✓ The system starts by initializing the microkernel on each machine.
✓ Servers are started on designated machines to provide various services.
✓ Clients (user applications) are launched on any machine in the network.
• Resource Discovery:
✓ Amoeba uses a directory server to manage and locate resources within the network.
✓ Clients query the directory server to find the services they need.
• Capability-Based Security:
✓ Each object in Amoeba is accessed via a capability, which is a protected reference
containing access rights.
✓ Capabilities ensure that clients can only perform operations for which they have been
granted permission.
✓ Capabilities can be delegated, allowing flexible and secure resource sharing.
• Process Management:
✓ Amoeba allows processes to be distributed across multiple machines.
✓The microkernel manages process creation, scheduling, and communication.
✓Processes can migrate between machines for load balancing or fault tolerance.
• Fault Tolerance:
✓ Amoeba uses replication and checkpointing to ensure reliability.
✓ Critical data and services are replicated across multiple servers.
✓ Checkpointing allows the system to recover processes from saved states in case of failures.
Example Workflow:
• Application Startup:
✓ A user starts a text editing application on their workstation (Client).
✓ The client queries the directory server to locate the file server holding the document.
• File Access:
✓ The client sends a request to the file server to open the document.
• Process Migration:
✓The system detects high load on the current machine running the text editor.
✓The microkernel decides to migrate the text editor process to another machine with more
available resources.
✓The process state is transferred, and the text editor resumes operation on the new machine
seamlessly.
Advantages:
• Transparency:
✓ Unified View: Amoeba provides a seamless and unified view of distributed resources,
✓ making it easier for users and applications to interact with the system without
worrying aboutthe underlying distribution.
✓ Location Transparency: Users and applications can access resources without
needing toknow their physical location.
• Scalability:
✓Horizontal Scaling: Amoeba can scale by adding more machines to the network,
distributing the workload across these machines.
✓Efficient Resource Utilization: The system can dynamically allocate resources based on
demand, optimizing performance and utilization.
• Fault Tolerance:
✓Replication: Critical data and services are replicated across multiple servers to ensure
availability even in the case of failures.
✓Checkpointing: Processes can be checkpointed and recovered, enabling the system to
recover from crashes.
• Flexibility:
✓Microkernel Architecture: The microkernel design allows for minimal and efficient core
operations, with other services provided by user-space servers. This modularity facilitates
easier maintenance and upgrades.
✓Process Migration: Processes can be migrated between machines for load balancing and
resource optimization.
• High Performance:
✓Optimized IPC: The message-passing mechanism for inter-process communication is
designed to be efficient, supporting high-performance distributed applications.
Disadvantages:
• Complexity:
✓System Management: Managing and configuring a distributed operating system like
Amoeba can be complex, requiring specialized knowledge and expertise.
✓Debugging and Monitoring: Debugging distributed applications and monitoring the system
can be more challenging compared to traditional, centralized systems.
• Network Dependency:
✓Latency: The performance of the system can be affected by network latency, especially for
applications requiring frequent communication between distributed components.
✓Bandwidth: High network traffic can lead to bandwidth constraints, potentially impacting
system performance.
• Overhead:
✓ Capability Management: Managing capabilities can introduce overhead, both in
terms ofstorage and computational complexity.
✓ Replication and Checkpointing: While these features provide fault tolerance, they also
addoverhead in terms of storage and processing.
• Resource Contention:
✓Shared Resources: Contention for shared resources can lead to performance bottlenecks,
especially in a heavily loaded system.
✓Load Balancing: Efficiently balancing the load across distributed resources requires
sophisticated algorithms and can be challenging to implement effectively.
Working Process:
• Architecture and Components:
✓Nodes: Individual computers (nodes) connected via a network.
✓Communication Infrastructure: Mechanism for nodes to communicate with each other,
typically through message passing.
✓Distributed Operating System (DOS): Managed the distribution of tasks and resources
UTU/CGPIT/CE/SEM-7/Distributed Computing System
pg. 5
Enroll no - 202103103510490
across the nodes.
• Task Distribution:
✓Task Decomposition: The overall computational task is broken down into smaller subtasks.
✓Task Assignment: Subtasks are assigned to different nodes based on their capabilities and
current load.
• Resource Management:
✓ Resource Allocation: The DOS allocates resources (CPU, memory, storage) to the
subtasks,ensuring efficient utilization.
✓ Load Balancing: Ensures that no single node is overwhelmed by distributing the
• Communication:
✓Message Passing: Nodes communicate via messages to share data and synchronize
processes.
✓Remote Procedure Calls (RPC): Nodes can invoke procedures on other nodes, allowing for
coordinated execution of subtasks.
• Fault Tolerance:
✓Redundancy: Critical tasks or data are replicated across multiple nodes to prevent data loss
in case of node failure.
✓Failure Detection and Recovery: The system continuously monitors node health,
reassigning tasks if a node fails.
• Result Aggregation:
Example Workflow:
✓ Initialization: The system initializes and nodes are connected via the network.
✓ Task Submission: A user submits a computational task to the system.
✓ Decomposition: The DOS decomposes the task into smaller subtasks.
✓ Distribution: Subtasks are distributed to available nodes.
o Execution: Nodes execute their subtasks, communicating and synchronizing as
needed.
Advantages:
• Improved Performance and Scalability:
✓Parallel Processing: By distributing tasks across multiple nodes, the system could perform
computations in parallel, significantly improving performance.
✓Scalability: Adding more nodes to the system increased its computational power and
storage capacity, allowing it to handle larger and more complex tasks.
• Resource Utilization:
✓ Efficient Resource Use: The system ensured that the computational resources (CPU,
✓ memory, storage) of all nodes were utilized effectively, reducing idle times and
increasingoverall efficiency.
✓ Load Balancing: The DOS balanced the workload among nodes, preventing any
singlenode from becoming a bottleneck.
• Cost-Effectiveness:
✓Resource Sharing: Multiple users and applications could share the same set of
computational resources, maximizing their utilization and reducing costs.
✓Scalable Investment: Organizations could start with a smaller setup and gradually expand
their system by adding more nodes as needed, spreading out costs over time.
Disadvantages:
• Complexity:
✓System Management: Managing a distributed system is inherently more complex than a
single machine, requiring sophisticated software to handle task distribution,
synchronization,and fault tolerance.
✓Development Difficulty: Writing software for a distributed system requires a different
approach compared to traditional single-machine programming, often involving
complexalgorithms for communication, coordination, and error handling.
• Communication Overhead:
✓Latency: Communication between nodes introduces latency, which can slow down the
overall system performance, especially for tasks requiring frequent data exchange.
✓Bandwidth: The network bandwidth can become a bottleneck, particularly in data-intensive
applications where large amounts of data need to be transferred between nodes.
• Synchronization Issues:
✓Concurrency Control: Ensuring data consistency across distributed nodes is challenging,
requiring mechanisms like locking, which can introduce additional complexity and
potentialfor deadlocks.
✓Clock Synchronization: Keeping the clocks synchronized across different nodes is difficult,
and discrepancies can lead to issues in coordinating tasks and data.
• Security Concerns:
✓Vulnerability: Distributed systems can be more vulnerable to security threats such as
unauthorized access, data breaches, and distributed denial-of-service (DDoS) attacks.
✓Data Integrity: Ensuring the integrity and security of data as it is transferred across nodes
and networks adds an additional layer of complexity.
Future Scope:
• Integration with Cloud Computing:
✓ Cloud Services: Modern cloud platforms (e.g., AWS, Azure, Google Cloud) inherently
rely on distributed systems. The principles of CDCS can be extended to optimize
resource
✓ allocation, improve fault tolerance, and enhance scalability in cloud environments.
✓ Hybrid Cloud Solutions: CDCS principles can aid in developing hybrid cloud
solutions thatseamlessly integrate on-premises and cloud resources, optimizing
performance and cost- efficiency.
✓ CGPIT/CE/SEM-7/B/DCS 13 | 14
Practical : 2
CGPIT/CE/SEM-7/B/DCS 11 | 40
Enrollment No: 202103103510490
[Link]();
}
}));
}
List<Thread> allThreads = new ArrayList<>();
[Link](senderThreads);
[Link](receiverThreads);
[Link](allThreads);
[Link]("Starting all processes in random order");
for (Thread thread : allThreads) {
[Link]();
}
for (Thread thread : allThreads) {
[Link]();
}
[Link]("All processes have completed.");
}
}
Output :
CGPIT/CE/SEM-7/B/DCS 13 | 40
Enrollment No: 202103103510490
Practical : 3
# Server code
def start_server():
server_socket = [Link](socket.AF_INET,
socket.SOCK_STREAM)host = '[Link]'
port = 5000
server_socket.bind((host,
CGPIT/CE/SEM-7/B/DCS 14 | 40
Enrollment No: 202103103510490
port))server_socket.listen(5)
print(f"Server listening on {host}:{port}")
while True:
client_socket, addr = server_socket.accept()
print(f"Connection from {addr} has been
established.")
data = client_socket.recv(1024).decode('utf-
8')print(f"Received from client: {data}")
# Client code
import socket
import threading
import time
def start_server():
server_socket = [Link](socket.AF_INET, socket.SOCK_STREAM)
host = '[Link]'
port = 12345
server_socket.bind((host, port))
server_socket.listen(1)
print(f"Server listening on {host}:{port}")
conn, addr = server_socket.accept()
print(f"Connection from {addr}")
CGPIT/CE/SEM-7/B/DCS 15 | 40
Enrollment No: 202103103510490
data = [Link](1024).decode('utf-8')
print(f"Received from client: {data}")
def start_client():
client_socket = [Link](socket.AF_INET, socket.SOCK_STREAM)
host = '[Link]'
port = 12345
client_socket.connect((host, port))
message = "Hiii Server!"
client_socket.send([Link]('utf-8'))
response = client_socket.recv(1024).decode('utf-8')
print(f"Received from server: {response}")
client_socket.close()
# Add a small delay to ensure the server is ready before the client tries to connect
[Link](1)
CGPIT/CE/SEM-7/B/DCS 16 | 40
Enrollment No: 202103103510490
# Join the threads to ensure they complete before finishing the notebook cell
server_thread.join()
client_thread.join()
Output:
Practical : 4
try:
message = client_socket.recv(1024).decode()
if not message:
break
print(f"Received message from {client_socket.getpeername()}: {message}")
broadcast(message, clients, client_socket)
except:
break
[Link](client_socket)
client_socket.close()
def start_server():
server_socket = [Link](socket.AF_INET, socket.SOCK_STREAM)
server_host = '[Link]'
server_port = 12345
server_socket.bind((server_host, server_port))
server_socket.listen(10)
print("Server started. Waiting for connections...")
clients = []
while True:
CGPIT/CE/SEM-7/B/DCS 18 | 40
Enrollment No: 202103103510490
if __name__ == "__main__":
start_server()
2) [Link]
import socket
import threading
def receive_messages(client_socket):
while True:
try:
message = client_socket.recv(1024).decode()
print(message)
except Exception as e:
print(f"Error occurred: {e}")
print("Disconnected from the server.")
client_socket.close()
break
def send_message(client_socket):
while True:
message = input("Enter your message: ")
try:
client_socket.sendall([Link]())
CGPIT/CE/SEM-7/B/DCS 19 | 40
Enrollment No: 202103103510490
except Exception as e:
print(f"Error occurred: {e}")
print("Disconnected from the server.")
client_socket.close()
break
def start_client():
client_socket = [Link](socket.AF_INET, socket.SOCK_STREAM)
server_host = '[Link]'
server_port = 12345
try:
client_socket.connect((server_host, server_port))
print("Connected to the server.")
except ConnectionRefusedError:
print("Connection refused. Is the server running?")
return
if __name__ == "__main__":
start_client()
Output:
Client_1 :
CGPIT/CE/SEM-7/B/DCS 20 | 40
Enrollment No: 202103103510490
Client_2 :
Server: -
CGPIT/CE/SEM-7/B/DCS 21 | 40
Enrollment No: 202103103510490
Practical : 5
import [Link];
import [Link];
import [Link];
public class server {
private static final int PORT = 8888;
String message;
while ((message = [Link]()) != null)
{ [Link]("Received: " +
message); String response = "Echo: " +
message; [Link](response);
}
[Link]("Connection closed by " + addr);
} catch (IOException e) {
[Link]();
}
}
}
(2) [Link]
import [Link].*;
import [Link].*;
import [Link];
CGPIT/CE/SEM-7/B/DCS 23 | 40
Enrollment No: 202103103510490
{ try {
while (true) {
[Link]("Enter message to send:
");String message = [Link]();
if ([Link]("exit")) {
break;
}
[Link](message);
[Link]("Closing
connection"); [Link]();
[Link]();
[Link]();
[Link]();
} catch (IOException e) {
[Link]();
}
CGPIT/CE/SEM-7/B/DCS 24 | 40
Enrollment No: 202103103510490
}
}
Output:
CGPIT/CE/SEM-7/B/DCS 25 | 40
Enrollment No: 202103103510490
Practical : 6
• [Link]:
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
CGPIT/CE/SEM-7/B/DCS 27 | 40
Enrollment No: 202103103510490
• [Link]
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
} catch (RemoteException e) {
[Link]();
}
}
}
Output :
CGPIT/CE/SEM-7/B/DCS 29 | 40
Enrollment No: 202103103510490
Practical : 7
def main():
calculator = Calculator()
daemon = [Link]()
uri = [Link](calculator)
ns = [Link]()
[Link]("[Link]", uri)
if __name__ == "__main__":
main()
CGPIT/CE/SEM-7/B/DCS 30 | 40
Enrollment No: 202103103510490
[Link]
import Pyro4
def main():
ns = [Link]()
uri = [Link]("[Link]")
calculator = [Link](uri)
result_add = [Link](10, 5)
result_subtract = [Link](10, 5)
print(f"Addition Result: {result_add}")
print(f"Subtraction Result: {result_subtract}")
if __name__ == "__main__":
main()
Output :
CGPIT/CE/SEM-7/B/DCS 31 | 40
Enrollment No: 202103103510490
CGPIT/CE/SEM-7/B/DCS 32 | 40
Enrollment No: 202103103510490
Practical : 8
Code:
import threading
import time
import random
class Process:
def __init__(self, process_id, total_processes):
self.process_id = process_id
self.total_processes = total_processes
self.replies_received = 0
def request_access(self):
print(f"[Process {self.process_id}] Requesting access...")
[Link](0.1)
def run_process(process):
[Link]([Link](0.1, 1)) # Simulate random delays
process.request_access()
if __name__ == "__main__":
# Create processes
processes = [Process(i, []) for i in range(3)]
print("Simulation finished.")
CGPIT/CE/SEM-7/B/DCS 34 | 40
Enrollment No: 202103103510490
Output:
CGPIT/CE/SEM-7/B/DCS 35 | 40
Enrollment No: 202103103510490
Practical 9
Aim: Implement clock synchronization algorithm using a counter.
Code:
import sys
from datetime import datetime, timedelta
class Process:
def __init__(self, pid, clock):
[Link] = pid # Process ID
[Link] = clock # Initial clock time as a datetime object
def get_time(self):
"""Returns the local clock time."""
return [Link]
class BerkeleyAlgorithm:
def __init__(self, coordinator):
[Link] = coordinator
[Link] = [coordinator] # List of all processes (starting with the coordinator)
def synchronize_clocks(self):
"""Synchronize clocks across all processes."""
print(f"Coordinator (Process {[Link]}) polling other processes for their
times...")
# Step 1: Polling - Gather all the clocks from each process, with request and arrival
timestamps
times = {}
coordinator_time = [Link].get_time() # Coordinator's time when sending the
request
print(f"Coordinator sent requests at time: {coordinator_time.time()}")
CGPIT/CE/SEM-7/B/DCS 37 | 40
Enrollment No: 202103103510490
# Step 3: Adjust times for all processes based on the average difference
for process in [Link]:
if process != [Link]:
adjustment = avg_diff - time_differences[[Link]]
process.adjust_time(adjustment)
print(f"Process {[Link]} clock adjusted by {adjustment} seconds, new time:
{process.get_time().time()}")
def input_time(prompt):
"""Helper function to input time in HH:MM:SS format and return a datetime object."""
while True:
CGPIT/CE/SEM-7/B/DCS 38 | 40
Enrollment No: 202103103510490
try:
time_input = input(prompt)
return [Link](time_input, "%H:%M:%S")
except ValueError:
print("Invalid time format. Please enter in HH:MM:SS format.")
# Simulation of the Berkeley Algorithm with user input for initial clock times
CGPIT/CE/SEM-7/B/DCS 39 | 40
Enrollment No: 202103103510490
Output :
CGPIT/CE/SEM-7/B/DCS 40 | 40