0
0
Lập trình
Admin Team
Admin Teamtechmely

Thiết kế dịch vụ rút gọn URL như TinyURL

Đăng vào 7 tháng trước

• 7 phút đọc

Giới thiệu

Dịch vụ rút gọn URL giúp chuyển đổi một URL dài (ví dụ: https://example.com/some/very/deep/path) thành một alias ngắn gọn hơn (ví dụ: https://short.ly/aBcD12). Khi người dùng truy cập vào URL ngắn, họ sẽ được chuyển hướng đến URL gốc. Một số ví dụ điển hình bao gồm TinyURL, Bitly, v.v.

Yêu cầu chức năng

Tính năng

  • Rút gọn một URL dài
  • Chuyển hướng từ URL ngắn → URL dài
  • Phân tích số liệu

Người dùng

  • 100 triệu người dùng hoạt động hàng ngày (DAU)
  • Tỷ lệ đọc/ghi 100:1
  • 1 triệu ghi mỗi ngày
  • Kích thước mỗi mục dữ liệu 500 byte
  • Thời gian lưu trữ dữ liệu là 5 năm

Yêu cầu phi chức năng

  • Tính khả dụng cao - Hệ thống cần phải hoạt động 24/7, thời gian ngừng hoạt động tối thiểu.
  • Độ trễ thấp - Chuyển hướng cần phải rất nhanh (~200 ms).
  • Độ bền cao - Dữ liệu phải được lưu trữ ngay cả khi máy chủ gặp sự cố.

Các điểm cuối API

POST /api/urls/shorten

Nội dung yêu cầu:

json Copy
{
  "longUrl": "https://example.com/some/very/deep/path"
}

Nội dung phản hồi:

json Copy
{
  "shortUrl": "https://short.ly/aBcD12"
}

GET /:shorturl

Nội dung phản hồi:

json Copy
{
  "longUrl": "https://example.com/some/very/deep/path"
}

Thiết kế cấp cao

Quy trình ban đầu cho dịch vụ rút gọn URL sẽ bao gồm:

  1. Khách hàng gửi một URL để rút gọn

    • Khách hàng gửi yêu cầu POST đến API Gateway, bao gồm URL dài gốc.
  2. API Gateway chuyển tiếp đến dịch vụ rút gọn URL

    • API Gateway định tuyến yêu cầu đến Dịch vụ rút gọn URL.
    • Dịch vụ này:
      • Tạo một shortCode
      • Lưu trữ ánh xạ (shortCode → longUrl) trong cơ sở dữ liệu
      • Trả về URL ngắn cho khách hàng (ví dụ: https://short.ly/abc123)
  3. Khách hàng sử dụng URL ngắn

    • Khi ai đó nhấp vào URL ngắn (https://short.ly/abc123), một yêu cầu GET được gửi đến API Gateway.
  4. API Gateway định tuyến đến Dịch vụ chuyển hướng URL

    • Dịch vụ Chuyển hướng tìm kiếm mã ngắn (abc123) trong cơ sở dữ liệu.
  5. Chuyển hướng đến URL gốc

    • Khi URL dài được lấy ra, dịch vụ phản hồi với một chuyển hướng 301 hoặc 302 đến URL dài gốc.
    • Trình duyệt sẽ theo dõi chuyển hướng này và tải URL dài.

Tối ưu thiết kế & Chi tiết sâu

  1. Làm thế nào để một người được chuyển hướng đến URL gốc khi nhấp vào URL ngắn?

    • Khi một người nhấp vào URL ngắn, Dịch vụ Chuyển hướng tìm mã ngắn tương ứng trong cơ sở dữ liệu.
    • Và phản hồi với mã trạng thái HTTP 302 (hoặc 301), cùng với tiêu đề Location:
      http Copy
      HTTP 302 Found
      Location: https://www.example.com/very/long/path?ref=campaign
  2. Tại sao sử dụng 302 (Found) thay vì 301 (Moved Permanently)?

    • 302 là Tạm thời:
      • Thông báo cho trình duyệt - "Chuyển hướng này có thể thay đổi sau. Đừng lưu vào bộ nhớ cache vĩnh viễn."
    • 301 là Vĩnh viễn:
      • Thông báo cho trình duyệt và các công cụ tìm kiếm: "Liên kết này sẽ luôn đến cùng một nơi."
      • Trình duyệt sẽ lưu vào bộ nhớ cache vĩnh viễn.
  3. Tại sao sử dụng CSDL NoSQL cho dịch vụ rút gọn URL?

    • Dịch vụ rút gọn URL rất phù hợp với NoSQL vì chúng liên quan đến việc tra cứu đơn giản theo cặp khóa-giá trị. Ví dụ, bạn chỉ cần ánh xạ shortCode → longUrl, điều này không yêu cầu các phép nối hoặc mối quan hệ phức tạp.
    • NoSQL cung cấp:
      • Độ thông lượng đọc/ghi cao
      • Tính linh hoạt về cấu trúc (bạn có thể thêm dữ liệu theo dõi sau)
      • Khả năng mở rộng theo chiều ngang (dễ dàng xử lý hàng triệu yêu cầu)
      • Truy cập dựa trên khóa với độ trễ thấp
    • Chúng ta có thể sử dụng một cơ sở dữ liệu có tính khả dụng cao (ví dụ: DynamoDB hoặc Cassandra) để lưu trữ các ánh xạ.
  4. Dữ liệu gì nên được lưu trữ trong CSDL?

    • URL
    json Copy

{
"shortCode": "abc123",
"longUrl": "https://www.example.com/very/long/article?id=12345",
"createdAt": "2025-09-14T10:00:00Z",
"userId": "77a211ff"
}

Copy
   - Người dùng
   ```json
{
  "userId": "77a211ff",
  ....
}

Các phương pháp tối ưu hóa hệ thống rút gọn URL

  1. Thêm lớp caching (ví dụ: Redis)

    • Lưu trữ các ánh xạ shortCode → longUrl phổ biến
    • Giảm số lần đọc từ cơ sở dữ liệu và độ trễ
    • Sử dụng chính sách TTL hoặc LRU để quản lý bộ nhớ
  2. Sử dụng chỉ mục trên trường shortcode trong CSDL

    • Đảm bảo cơ sở dữ liệu có chỉ mục đúng trên trường shortcode.
    • Tăng tốc độ truy vấn tìm kiếm cho việc chuyển hướng.

Cách tạo mã duy nhất cho mỗi URL dài?

Việc tạo các mã ngắn duy nhất, không bị xung đột là quan trọng đối với thiết kế của dịch vụ rút gọn URL. Dưới đây là một số phương pháp phổ biến:

  1. Bộ đếm tự động tăng + Mã hóa Base62

    • Sử dụng một bộ đếm toàn cục tăng lên cho mỗi URL mới.
    • Chuyển đổi số bộ đếm sang Base62 (0-9, A-Z, a-z) để có một chuỗi ngắn gọn, thân thiện với URL.
    • Ví dụ: 125 → "cb"
    • Ưu điểm:
      • Đơn giản, có thể dự đoán, không xảy ra xung đột.
      • Mã rất ngắn.
    • Nhược điểm:
      • Cần bộ đếm trung tâm (khó mở rộng).
      • URL tuần tự có thể tiết lộ lượng truy cập.
  2. Chuỗi ngẫu nhiên với kiểm tra xung đột

    • Tạo một chuỗi ngẫu nhiên Base62 có độ dài cố định (ví dụ: 6 ký tự).
    • Kiểm tra cơ sở dữ liệu để tìm xung đột, tái tạo nếu đã tồn tại.
    • Ưu điểm:
      • Dễ dàng mở rộng theo chiều ngang.
      • Khó đoán mã ngắn tiếp theo (tăng tính riêng tư).
    • Nhược điểm:
      • Nguy cơ xung đột nhỏ (có thể giảm thiểu bằng độ dài).
      • Cần kiểm tra cơ sở dữ liệu cho mỗi lần tạo.
  3. Băm URL dài

    • Băm URL gốc (MD5/SHA) và sử dụng N ký tự đầu tiên làm mã ngắn.
    • URL dài giống nhau luôn nhận được mã ngắn giống nhau.
    • Ưu điểm:
      • Idempotent (không có bản sao cho cùng một URL).
      • Không cần trạng thái trung tâm.
    • Nhược điểm:
      • Nguy cơ xung đột.
      • Mã có thể dài hơn hoặc ít thân thiện hơn.
  4. Mã hóa UUID hoặc GUID

    • Tạo một UUID, mã hóa thành Base62 hoặc hex.
    • Sử dụng một chuỗi con làm mã ngắn.
    • Ưu điểm:
      • Duy nhất toàn cầu.
    • Nhược điểm:
      • Mã dài hơn.

Lưu ý: Đối với hầu hết các dịch vụ rút gọn URL, đặc biệt ở quy mô nhỏ đến trung bình, phương pháp Chuỗi ngẫu nhiên + Kiểm tra xung đột là lựa chọn tối ưu nhất.

Cách mở rộng hệ thống để xử lý lưu lượng truy cập cao?

  • Sharding:

    • Để xử lý lưu lượng truy cập cao và mở rộng hiệu quả, chúng ta có thể sử dụng sharding để phân phối dữ liệu và tải giữa nhiều máy chủ. Điều này cho phép mở rộng theo chiều ngang, cho phép thêm nhiều nút khi lưu lượng tăng mà không cần cấu hình lại lớn.
  • Cân bằng tải:

    • Sử dụng các bộ cân bằng tải để phân phối đồng đều các yêu cầu đến các dịch vụ.
    • Ngăn chặn bất kỳ máy chủ nào bị quá tải.
  • Caching CDN ở biên:

    • Sử dụng CDN (ví dụ: Cloudflare) để lưu trữ các chuyển hướng tại các vị trí biên.
    • Giảm độ trễ cho người dùng toàn cầu.
    • Giảm tải yêu cầu trước khi chúng đến backend của bạn.

Thiết kế cuối cùng

Nếu bạn thấy bài viết này hữu ích, hãy:

  • 💬 Để lại bình luận - Tôi rất muốn nghe ý kiến của bạn hoặc trả lời các câu hỏi của bạn!
  • 🔁 Chia sẻ với những người khác đang học thiết kế hệ thống.
  • 📌 Theo dõi tôi trên Dev.to để nhận thêm nhiều bài viết sâu hơn như thế này!

Cảm ơn bạn đã đọc! :)

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào