/short-url

Experiment web service that shortens URLs

Primary LanguagePython

Short-URL

This is a job application coding challenge project.

Create a web service that shortens URLs for 1000s of concurrent users. Users should be able to submit a long URL, then receive a unique shortened URL that redirects to the long URL.

Demo

This application will be available for a short time under http://shorts.gq

For eg. this http://shorts.gq/0 should redirect you to my GitHub profile.

Performance and scalability considerations

We need to generate unique values and make them short. Generating random UUIDs would be against "make them short" requirement. So in order to generate short values we need a shared counter like value that will be assigned used as key for url mapping.

I chose redis for atomic INCR command and persistent storage. It would be a bottleneck, but it should do fine until we'll need to service more than 50K mapping requests per second.

Deployment on k8s cluster with autoscaling would take care of rest of scalability issues.

Metrics and monitoring

I focused on the getting the app running on live k8s cluster and did not implement metrics. But ATM I think we could get away with the ones available out of the box with Prometheus k8s support:

  • Metrics for ingress/load balancer to monitor HTTP traffic
    • the usual stuff related to usage, latencies and errors
  • Redis metrics
    • Storage capacity and latencies
    • The "counter" value with limit as 64 bit signed integer, we should be pretty safe, but let's monitor how quicly we're depleting the rest of the results.

Future

  • Re-use mappings for previously seen destination
  • Multiple redis instances and dispatching with consistent hashing
  • Expiration on time on url mappings.
  • Rolling forward with new redis instances for new mappings and decommissioning instances that expired all the previous values.

User interface

I was asked to not waste time on UI, so I decided to stick with whatever is available out of the box.

Testing

The project was tested locally on minikube with ingress and repository addons enabled. Please see Makefile commands with minikube-prefix.

To create deployment on minikue please override REGISTRY env variable with whatever minikube will show as prefix for shorts image uploaded to the local minikube images store:

env REGISTRY=docker.io/library make minikube-create-deployment

Please beware that minikube deployment uses imagePullPolicy: Never for prohibit image downloads from non-existent external source.

A docker-compose is provided for simplified environment setup and to provide redis for integration tests.

Other job application code challenges

Please take a look at other code challenge projects I have prepared in the past.

And other notable projects — please beware that they are legacy at this point