System Design of URL Shortening Service

Ott 2, 2021
admin

Quando abbiamo bisogno di una nuova chiave, possiamo prendere uno degli ID già generati. Questo approccio può rendere le cose più veloci perché quando arriva una nuova richiesta, non abbiamo bisogno di creare un ID, assicurare la sua unicità, ecc. UGS assicurerà che tutti gli ID siano unici, e possono essere memorizzati in un database in modo che gli ID non debbano essere generati ogni volta.

Poiché abbiamo bisogno di un byte per memorizzare un carattere, possiamo memorizzare tutte queste chiavi in:

6 (caratteri) * 68.7B (chiavi uniche) ~= 412 GB.

★Disponibilità & Affidabilità:

Se teniamo una copia di UGS, è un singolo punto di fallimento. Quindi, dobbiamo fare una replica di UGS. Se il server primario muore, quello secondario può gestire le richieste degli utenti.

Ogni server UGS può mettere in cache alcune chiavi dal Key-DB. Questo può accelerare le cose. Ma, dobbiamo stare attenti; se un server muore prima di consumare tutte le chiavi, perderemo quelle chiavi. Ma, possiamo supporre, questo è accettabile dato che abbiamo quasi 68B chiavi uniche di sei lettere.

Per assicurare la disponibilità, dobbiamo assicurarci di rimuovere un singolo punto di fallimento nel sistema. La replica per i dati rimuoverà un singolo punto di fallimento e fornirà il backup. Possiamo mantenere più repliche per garantire l’affidabilità del server di database. E inoltre, per un servizio ininterrotto, anche gli altri server hanno bisogno di copie.

★DataStorage:

In questo sistema, dobbiamo memorizzare miliardi di record. Ogni oggetto che conserviamo è forse meno di 1 KB. Un dato URL non è correlato ad un altro. Quindi, possiamo usare un database NoSQL come Cassandra, DynamoDB, ecc. Una scelta NoSQL sarebbe più facile da scalare, che è uno dei nostri requisiti.

★ Scalabilità:

Per supportare miliardi di URL, abbiamo bisogno di partizionare il nostro database per dividere e conservare i nostri dati in diversi server DB.

i) Possiamo partizionare il database in base alla prima lettera della chiave hash. Possiamo mettere le chiavi che iniziano con ‘A’ in un server, ‘B’ in un altro server. Questo è chiamato partizionamento basato sul range.

Il problema con questo approccio è che può portare ad un partizionamento sbilanciato. Per esempio, ci sono pochissime parole che iniziano per ‘Z.’ D’altra parte, potremmo avere troppi URL che iniziano con la lettera ‘E.’

Possiamo combinare lettere che si presentano meno frequentemente in una partizione del database.

ii) Possiamo anche partizionare in base all’hash degli oggetti che stiamo memorizzando. Possiamo prendere l’hash della chiave per determinare la partizione in cui possiamo memorizzare l’oggetto dei dati. La funzione di hash genererà un numero di server, e memorizzeremo la chiave in quel server. Questo processo può rendere la distribuzione più casuale. Questo è Hash-Based Partitioning.

Se questo approccio porta ancora a partizioni sovraccariche, dobbiamo usare Consistent Hashing.

★ Cache:

Possiamo mettere in cache gli URL che sono frequentemente consultati dagli utenti. I server UGS, prima di fare una query al database, possono controllare se la cache ha l’URL desiderato. Allora non c’è bisogno di ripetere l’interrogazione.

Cosa succede quando la cache è piena? Possiamo sostituire un vecchio link non utilizzato con un URL più recente o popolare. Possiamo scegliere la politica di eliminazione della cache Least Recently Used (LRU) per il nostro sistema. In questa politica, rimuoviamo prima l’URL usato più di recente.

★ Load balancer:

Possiamo aggiungere uno strato di bilanciamento del carico in diversi punti del nostro sistema, davanti al server di accorciamento degli URL, al database e ai server della cache.

Possiamo usare un semplice approccio Round Robin per la distribuzione delle richieste. In questo approccio, LB distribuisce equamente le richieste in arrivo tra i server di backend. Questo approccio di LB è semplice da implementare. Se un server è morto, LB smetterà di inviare qualsiasi traffico ad esso.

Problema: se un server è sovraccarico, LB non smetterà di inviare una nuova richiesta a quel server in questo approccio. Potremmo aver bisogno di un LB intelligente in seguito.

★ Scadenza del link dopo una durata:

Se il tempo di scadenza viene raggiunto per un URL, cosa accadrebbe al link?

Possiamo cercare nei nostri datastore e rimuoverli. Il problema qui è che se scegliessimo di cercare i link scaduti per rimuoverli dal nostro datastore, questo metterebbe molta pressione sul nostro database.

Possiamo farlo in un altro modo. Possiamo rimuovere lentamente i link scaduti periodicamente. Anche se alcuni link morti vivono più a lungo, non dovrebbero mai essere restituiti agli utenti.

Se un utente cerca di accedere a un link scaduto, possiamo rimuovere il link e restituire un errore all’utente. Un processo di pulizia periodica può essere eseguito per rimuovere i link scaduti dal nostro database. Dato che l’archiviazione sta diventando più economica, alcuni link potrebbero rimanere lì anche se manchiamo durante la pulizia.

Dopo aver rimosso il link, possiamo rimetterlo nel nostro database per riutilizzarlo.

★ Sicurezza:

Possiamo memorizzare il tipo di accesso (pubblico/privato) con ogni URL nel database. Se un utente cerca di accedere a un URL di cui non ha il permesso, il sistema può rimandare indietro un errore (HTTP 401).

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.