Systemdesign av URL Shortening Service
När vi behöver en ny nyckel kan vi ta ett av de redan genererade ID-numren. Detta tillvägagångssätt kan göra saker och ting snabbare eftersom vi, när en ny begäran kommer, inte behöver skapa ett ID, se till att det är unikt osv. UGS kommer att se till att alla ID:n är unika, och de kan lagras i en databas så att ID:n inte behöver genereras varje gång.
Då vi behöver en byte för att lagra ett tecken, kan vi lagra alla dessa nycklar i:
6 (tecken) * 68.7B (unika nycklar) ~= 412 GB.
★ Tillgänglighet & Tillförlitlighet:
Om vi har en kopia av UGS är det en enda felpunkt. Därför måste vi skapa en kopia av UGS. Om den primära servern dör kan den sekundära hantera användarnas förfrågningar.
Varje UGS-server kan cacha vissa nycklar från key-DB. Det kan påskynda saker och ting. Men vi måste vara försiktiga; om en server dör innan alla nycklar är förbrukade kommer vi att förlora dessa nycklar. Men vi kan anta att detta är acceptabelt eftersom vi har nästan 68B unika nycklar med sex bokstäver.
För att säkerställa tillgängligheten måste vi se till att ta bort en enda felpunkt i systemet. Replication for Data kommer att ta bort en enda felpunkt och tillhandahålla säkerhetskopiering. Vi kan hålla flera replikeringar för att säkerställa databasserverns tillförlitlighet. Och för oavbruten service behöver även andra servrar kopior.
★DataStorage:
I det här systemet måste vi lagra miljarder poster. Varje objekt som vi behåller är möjligen mindre än 1 KB. En URL-data är inte relaterad till en annan. Därför kan vi använda en NoSQL-databas som Cassandra, DynamoDB osv. Ett NoSQL-val skulle vara lättare att skala, vilket är ett av våra krav.
★ Skalbarhet:
För att stödja miljarder webbadresser måste vi partitionera vår databas för att dela upp och lagra våra data på olika DB-servrar.
i) Vi kan partitionera databasen baserat på den första bokstaven i hashnyckeln. Vi kan lägga nycklar som börjar med ”A” på en server och ”B” på en annan server. Detta kallas Range Based Partitioning.
Problemet med detta tillvägagångssätt är att det kan leda till obalanserad partitionering. Det finns till exempel väldigt få ord som börjar med ”Z”. Å andra sidan kan vi ha för många webbadresser som börjar med bokstaven ”E.”
Vi kan kombinera mindre frekvent förekommande bokstäver i en databaspartition.
ii) Vi kan också partitionera baserat på hashen för de objekt som vi lagrar. Vi kan använda nyckelns hash för att bestämma i vilken partition vi kan lagra dataobjektet. Hashfunktionen genererar ett servernummer och vi lagrar nyckeln på den servern. Denna process kan göra fördelningen mer slumpmässig. Detta är hashbaserad partitionering.
Om detta tillvägagångssätt fortfarande leder till överbelastade partitioner måste vi använda Consistent Hashing.
★ Cache:
Vi kan cachelagra webbadresser som ofta nås av användarna. UGS-servrarna kan, innan de gör en förfrågan till databasen, kontrollera om cacheminnet innehåller den önskade webbadressen. Då behöver den inte göra förfrågan igen.
Vad händer när cacheminnet är fullt? Vi kan ersätta en äldre oanvänd länk med en nyare eller populär URL. Vi kan välja LRU-strategin (Least Recently Used) för att rensa ut cacheminnet i vårt system. I denna policy tar vi bort den minst nyligen använda URL:n först.
★ Lastutjämnare:
Vi kan lägga till ett lager för lastutjämning på olika ställen i vårt system, framför URL-förkortningsservern, databasen och cacheservrarna.
Vi kan använda en enkel Round Robin-metod för fördelning av förfrågningar. I detta tillvägagångssätt distribuerar LB inkommande förfrågningar jämnt mellan backend-servrarna. Detta tillvägagångssätt för LB är enkelt att genomföra. Om en server är död slutar LB att skicka trafik till den.
Problem: Om en server är överbelastad slutar LB inte att skicka nya förfrågningar till den servern i detta tillvägagångssätt. Vi kan behöva en intelligent LB senare.
★ Länken upphör att gälla efter en viss tid:
Om utgångstiden för en webbadress har uppnåtts, vad händer då med länken?
Vi kan söka i våra datalager och ta bort dem. Problemet här är att om vi väljer att söka efter utlösta länkar för att ta bort dem från vårt datalager skulle det sätta stor press på vår databas.
Vi kan göra det på ett annat sätt. Vi kan långsamt ta bort utgångna länkar med jämna mellanrum. Även om vissa döda länkar lever längre bör de aldrig återlämnas till användarna.
Om en användare försöker komma åt en utgången länk kan vi ta bort länken och returnera ett felmeddelande till användaren. En periodisk rensningsprocess kan köras för att ta bort utgångna länkar från vår databas. Eftersom lagringsutrymmet blir billigare kan vissa länkar finnas kvar även om vi missar medan vi rensar upp.
När vi tagit bort länken kan vi lägga tillbaka den i vår databas för återanvändning.
★ Säkerhet:
Vi kan lagra åtkomsttypen (offentlig/privat) med varje URL i databasen. Om en användare försöker komma åt en URL som han inte har behörighet kan systemet skicka tillbaka ett felmeddelande (HTTP 401).