System design
لم يُترجم بعد؛ يُعرض باللغة الإنجليزية
Design a URL shortener from end to end. Start with the two API calls and a back-of-the-envelope estimate (about 1,160 writes and 11,600 reads a second, 3.65 TB a year), choose a one-table data model and a base 62 code, then follow real requests through a load balancer, app servers, a cache, a primary database with read replicas and a CDN, and weigh the bottlenecks and trade-offs.
5 أسئلة سريعة
اختر إجابة لتعرف السبب. تُحفَظ نتيجتك مع تقدّمك.
01With 100 million new links a day, about how many writes per second is that?
A day has 86,400 seconds, so 100,000,000 / 86,400 ≈ 1,160 writes a second. With 10 clicks per link, reads are about 11,600 a second.
02The service's only lookup is "find the row for this short code". What should the table's primary key be?
Every GET /<code> request looks a row up by its code, so the code is the primary key: unique per row and indexed, so the lookup is fast with no joins. The code itself is the link's unique ID written in base 62, e.g. 2009215674938 → zn9edcu.
03A click asks the cache and the code is not there. What does the app do next?
That is a cache miss. In the cache-aside pattern the app reads from the database (here a read replica) and puts the result in the cache, so the next click is a hit.
04Every write still goes to one primary database. Which fix spreads the writes, and what does it cost?
Replicas and caches only share the reads: every write still lands on the primary. Sharding splits the rows by code across several databases, so each takes part of the writes. The cost is routing each code to its shard and more databases to run and watch.
05You need to count every click on every short link. Which redirect status fits better?
A 301 may be cached by browsers and CDNs, so repeat clicks may never reach your servers. A 302 is not cached by default, so every click arrives and can be counted.
المسرد
- API
- Application programming interface: the list of requests a service accepts and what each returns, such as POST /urls and GET /<code>.
- Back-of-the-envelope estimate
- A quick calculation with rounded assumptions (requests per second, storage per year) to see how big a system must be.
- Base 62
- Writing a number with 62 symbols (0-9, a-z, A-Z). Seven base 62 characters can name about 3.5 trillion different values.
- Load balancer
- A server that spreads incoming requests over several identical app servers.
- Cache
- A small, fast store kept in memory (RAM) that holds copies of popular data. A hit finds the data there; a miss does not.
- Read replica
- A copy of the primary database that serves reads. It applies the primary's changes a little later (replication lag).
- CDN
- Content delivery network: servers in many places, close to users, that answer with cached copies of responses.
- Sharding
- Splitting one table across several databases, each holding part of the rows (for example by code).
الملاحظات والمصادر
- The traffic figures are classroom assumptions (100 million new links a day, 10 reads per write, 100 bytes a link), not measurements of any real service. Their job is to show the scale: thousands of reads a second and terabytes a year.
- 100 bytes a row counts only the code and the URL. Indexes, replicas and backups multiply the real disk use several times over.
- One counter is the simplest unique-ID source. Real systems avoid a single counter by giving each generator a range, or by building IDs from a timestamp and a machine number, as Twitter's Snowflake does.
- 301 is cacheable unless headers say otherwise; 302 is cached only when headers allow it (RFC 9110 and RFC 9111).
- Base 62 codes depend on upper versus lower case, so the code column must compare case-sensitively (for example with a binary collation); otherwise zn9edcu and ZN9EDCU would collide. Small IDs give codes shorter than 7 characters, so the column is VARCHAR(7), not CHAR(7).
- With asynchronous replication a replica applies the primary's changes a little later. The delay is usually small but has no fixed upper bound.
- A. Xu, System Design Interview: An Insider's Guide, ch. 8 "Design a URL Shortener" (ByteByteGo)
- Google SRE Workbook, ch. 12 "Non-Abstract Large System Design"
- RFC 9110, HTTP Semantics, §15.4 Redirection 3xx
- RFC 9111, HTTP Caching, §4.2.2 Calculating Heuristic Freshness
- MDN Web Docs: 301 Moved Permanently
- AWS whitepaper: Database Caching Strategies Using Redis, Caching patterns
- PostgreSQL documentation: High Availability, Load Balancing, and Replication
- PostgreSQL documentation §26.2.5: Streaming Replication (replication lag)
- MySQL documentation: Case Sensitivity in String Searches
- M. Kleppmann, Designing Data-Intensive Applications (O'Reilly, 2017), ch. 5 Replication and ch. 6 Partitioning
- Twitter Engineering: Announcing Snowflake (2010)
- Python documentation: Built-in functions, divmod()
اختبار يتاح بعد الخطوة الأخيرة.