Git Product home page Git Product logo

url-shortener's Introduction

URL Shortener

A high throughput, horizontally scalable URL shortener solution using Go, Redis, MongoDB, Terraform, and Kubernetes on EKS.

drawing

Tech Stack

  • Golang ✔️
  • MongoDB ✔️
  • Redis ✔️
  • Terraform ✔️
  • Kubernetes on EKS ✔️

System Design

This section aims to go through the technical decisions behind the solution architecture.

First of all, an URL Shortener should handle a lot of URL redirections concurrently, avoiding downtime as much as possible, in order to keep those short URLs working. It's a read-heavy system and has a specific room for optimization: hot URLs. Some URLs will be fetched much more frequently than others, so it makes sense to keep them in some kind of cache.

To achieve the requirements, the system stores hot URLs in an in-memory database: a Redis instance. When an URL is created, it is cached with an expiration lifespan. If the URL is fetched before this span ends, the expiration span is refreshed, so that a commonly used URL keeps having a fast response time. When the expiration span is reached, the URL will be only available at the main data storage, in this case, a MongoDB instance. Because there's no need for strong consistency or relational dependency, a NoSQL database is a good choice to store users' and URLs' information. Golang is a very good language to handle concurrency, so it's great for building fast servers.

To handle millions of users, the application needs to scale horizontally. By running everything as containers inside a kubernetes cluster, we can easily start up new instances for the application backend API or MongoDB. Although in this example we don't use shards, MongoDB supports sharding, which is a strong solution if our data grows really large.

Production environment

The production infrastructure was built as code using terraform. To reproduce this environment yourself, there are a few requirements needed:

  • An AWS account, with programatic access.
  • Terraform CLI installed (For this project I've used version 0.12.24).
  • Kubernetes CLI installed.

After everything is set up properly, go through the following steps:

Enter the terraform source code directory

cd terraform

Initialize the working directory and download all dependecies with

terraform init

Generate an execution plan

terraform plan -out=plan.apply

Apply

terraform apply plan.apply

Generally, EKS cluster takes about 15 minutes to create. When is done, a new file named kubeconfig_url-shortener-production-cluster should be seen in the current directory. This file will be used to access the brand-new Kubernetes cluster.

To get access to the EKS cluster

export KUBECONFIG="${PWD}/kubeconfig_url-shortener-production-cluster"

Now let's start up our pods and get everything running

kubectl apply -f ./kubernetes 

When it's complete, three newly created pods should be running: A Redis instance for cashing hot URLs, a MongoDB as the main data storage and the URL Shortener API

kubectl get pods 

On the EKS interface, you can also see if everything went correctly by entering the url shortener cluster

drawing

In order to test it out, get the load balance endpoint by

kubectl describe service url-shortener

That's it! Now you can start generating short URLs by calling the API endpoints. 🚀

Local environment

Run with docker-compose

For local development, you can start everything up using docker-compose by running

make all

Minikube

You can also run the application locally with kubernetes using minikube.

First of all, start the minikube cluster

minikube start

Apply everything by running

kubectl apply -f kubernetes

You can watch all pods coming alive with

kubectl get pods -w

To find the application URL exposed in our cluster by the service, type

minikube service url-shortener

When you're done, delete the application with

kubectl delete -f kubernetes

And also delete the minikube cluster

minikube delete --all

Endpoints

POST /users

Request

curl -XPOST http://localhost:3000/v1/users --header "Content-Type: application/json"  --data '{
    "name": "Jack",
    "email": "[email protected]"
}'

Response

{
  "id": "5fd6ac5c6884b412d6ec1475",
  "name": "Jack",
  "email": "[email protected]",
  "updated_at": 1607904348,
  "created_at": 1607904348
}

GET /users/:id

Request

curl http://localhost:3000/v1/users/1

Response

{
  "id": "5fd6ac5c6884b412d6ec1475",
  "name": "Jack",
  "email": "[email protected]",
  "updated_at": 1607904348,
  "created_at": 1607904348
}

POST /short_urls

Request

curl -XPOST http://localhost:3000/v1/short_urls --header "Content-Type: application/json"  --data '{
    "original_url": "https://really-long-website-url.com",
    "user_id": "5fd6ac5c6884b412d6ec1475",
    "expires_at": 100
}'

Response

{
  "hash": "DWv53EaGg",
  "original_url": "https://really-long-website-url.com",
  "user_id": "5fd6ac5c6884b412d6ec1475",
  "expires_at": 100,
  "created_at": 1607904409
}

GET /short_urls/:hash

Request

curl http://localhost:3000/v1/short_urls/DWv53EaGg

Response

{ "original_url": "https://really-long-website-url.com" }

GET /short_urls/:hash/redirect

Request

curl http://localhost:3000/v1/short_urls/DWv53EaGg/redirect

Response

It redirects to the original URL

url-shortener's People

Contributors

0xkalvin avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.