- ShortURL is a distributed and highly available URL Shortening service, built on the MERN stack.
- It uses Redis as a cache, and MongoDB as a NoSQL database.
- It uses Nginx that acts as a load balancer, and a reverse proxy for the backend server.
- It uses Apache ZooKeeper to provide tokens for hash generation, and eliminates race conditions between nodes.
- The entire application is containerized by Docker, and orchestrated by k8s.
- This is a demo application of a URL Shortener following the guidelines of efficient System Design.
- This is a project demonstrating the entire development process and is meant to be run in a local environment.
- Install Docker Desktop and enable Kubernetes for a quick setup.
- Clone this repository:
git clone https://github.com/muKaustav/ShortURL.git
- Create a .env file with the following variables:
REACT_APP_MONGODB_URI="<enter your MongoDB URI>"
REACT_APP_REDIS_PORT=1111 (defaults to 6379)
REACT_APP_REDIS_HOST='redis-server' (name it as you like, but change the same in the docker-compose.yml file)
- Open the project folder and start the container with docker compose:
docker compose up --build
# We can also scale instances of an image for higher scalability or distribution.
Example: docker compose up --build --scale node-server=3
- Enjoy the project! 😉
GET:
/url/:identifier : Get the shortened URL from DB
/del : Delete the Zookeeper token
POST:
/url [body : {"OriginalUrl" : "url"}] : Shorten the URL and store in DB
Access the API using the following URLs:
Client: http://localhost:3000/
Load Balanced Server: http://localhost:4000/
- The availability of the application can be improved by using multiple Zookeeper instances, replicas of the DB, and a distributed cache, thus increasing the fault tolerance of the architecture.
- Adding load balancers in between the following improves the performance of the application, and reduces the load on any particular instance:
- client and server
- server and DB
- server and cache
- CAP Theorem:
- We opt for an eventually consistent approach, as in case of a network partition, a URL Shortener should have low latency and high throughput at all times.
- Redirection of the user to the original URL should always have low latency as it directly impacts the business aspect of the application.
- We don't opt for a strongly consistent approach, as we would have to wait for the data to be replicated across the cluster, which decreases the availability and increases the latency of the application, thus impacting the user experience negatively.
- We opt for an eventually consistent approach, as in case of a network partition, a URL Shortener should have low latency and high throughput at all times.
- TinyURL System Design
- System Design : Scalable URL shortener service like TinyURL
- An Illustrated Proof of the CAP Theorem
- What is eventual consistency and why should you care about it?
- Redis Documentation
- Apache Zookeeper Documentation
- Nginx HTTP Load Balancing Documentation
- Docker Documentation
- Kompose Documentation
Contributions, issues and feature requests are welcome.
Feel free to check issues page if you want to contribute.
Kaustav Mukhopadhyay
- Linkedin: @kaustavmukhopadhyay
- Github: @muKaustav
Drop a ⭐️ if this project helped you!
Copyright © 2021 Kaustav Mukhopadhyay.
This project is MIT licensed.