Hướng dẫn thiết kế hệ thống (Phần 2) - Dựng hệ thống dán văn bản

Trong phần 2 này mình sẽ giới thiệu đến các bạn một dịch vụ cụ thể, bài viết đề cập tới một dịch vụ lưu trữ text online. Giải thích qua một chút, đây là 1 dịch vụ mà khi bạn copy text chuyển nó thành link chia sẻ cho người khác mà ko phải paste thẳng qua một công cụ chat nào .Vậy để thiết kế được một dịch vụ như vậy chúng ta phải làm thế nào ? Dưới đây mình xin chia sẻ những kinh nghiệm cũng như hiểu biết dưới góc độ của bản thân.

Step 1 : Phác thảo ra các use case và những ràng buộc

Thu thập các yêu cầu và phạm vi vấn đề. Đặt ra các câu hỏi để làm rõ các trường hợp sử dụng và các ràng buộc. Thảo luận về những giả định. Nếu không có ai để giải đáp các câu hỏi, người đưa ra giải đáp ở đây là người đưa ra những yêu cầu cho bạn (VD: khách hàng, project owner). Vậy thì chúng ta sẽ phải tự xác định một số trường hợp sử dụng và khó khăn.

Các use case

  • Người dùng nhập một khối văn bản và nhận được 1 link được tạo ngẫu nhiễn
  • Expiration - Hết hạn
    • Mặc định không bao giờ hết hạn
    • Có thể tuỳ chọn đặt thời gian hết hạn
  • Người dùng sẽ paste link vào trình duyệt và xem các nội dung
  • Người dùng có thể là bất kỳ ai, không cần phải đăng nhập
  • Có service theo dõi và phân tích thống kế truy cập hàng tháng
  • Có service xoá những link đã hết hạn
  • Service có tính sẵn sàng cào, điều này là hiển nhiên.

Out of scope

  • Người dùng có nhu cầu đăng ký tài khoản —> verify email
  • Người dùng đăng nhập vào tài khoản của họ —> thêm/sửa/xoá
  • Người dùng có thể giới hạn được quyền view, tự thiết lập lại được các link

Hạn chế và giả định

Các trạng thái giả định - Băng thông không đều, khi cao khi thấp - Lấy được short link nhanh nhất - Short link chỉ text only - Trang phân tích không cần phải realtime - Khoảng 1 triệu người dùng - Khoảng 1 triệu lần write trên 1 tháng - Khoảng 10 triệu lần read trên 1 tháng - Tỉ lệ ratio của read/write là 10:1

Tính toán sử dụng

  • Size trên 1 paste
    • 1 KB content cho mỗi lần paste link
    • short link khoảng 7 bytes
    • Tổng cổng khoảng 1.1 Kb
  • 1.1 GB sử dụng trên 1 tháng
    • 1.1 Kb trên 1 paste * 1 triệu paste/month
    • 1 năm sử dụng khoảng 13G
    • 12 triệu link trong 1 năm
    • Giả sử mọi paste đều là paste mới chứ không phải update những link đã tồn tại
  • 0.4 dán link/s tính trung bình
  • 4 lấy link/s tính trung bình Công thức tính nhanh
  • 2,5 triệu giây mỗi tháng
  • 1 yêu cầu mỗi giây = 2,5 triệu yêu cầu mỗi tháng
  • 40 yêu cầu mỗi giây = 100 triệu yêu cầu mỗi tháng
  • 400 yêu cầu mỗi giây = 1 tỷ yêu cầu mỗi tháng

Step 2 : Thiết kế high level

Step 3 : Thiết các thành phần lõi

Use case: Người dùng nhập một khối văn bản và nhận được 1 link được tạo ngẫu nhiễn

Chúng ta có thể sử dụng một cơ sở dữ liệu quan hệ như một bảng hash, ánh xạ generate url đã tạo ra thành file và đường dẫn chứa paste file . Thay vì quản lý các file, chúng tôi có thể sử dụng Amazon S3 hoặc NoSQL document store. Để thay thế cho một cơ sở dữ liệu quan hệ hoạt động là bảng hash, chúng ta có thể sử dụng NoSQL. Chúng ta nên thảo luận về sự giữa việc chọn SQL hoặc NoSQL. Dưới đây là cách tiếp cận cơ sở dữ liệu quan hệ :

  • Client gửi một yêu cầu tạo link rút gọn tới web server
  • Web server sẽ chuyển yêu cầu đến máy chủ **write API **
  • Server write API sẽ làm các bước sau :
    • Tạo ra một URL duy nhất - Kiểm tra bằng cách so sánh với DB để tránh trùng lặp - Nếu URL chưa tồn tạ thì sẽ tạo ra 1 URL khác - Nếu support custom URL, thì người dùng sẽ cung cấp URL (đương nhiên cũng phải check trùng lặp)
    • Lưu vào bảng trên DB
    • Lưu data vào các Object Store (S3 hoặc lưu trên local)
    • Trả kết quả

Làm rõ yêu cầu sẽ cho phép tối thiểu bao nhiêu write trên 1 lần Bảng dùng để lưu trữ write có thể có cấu trúc như sau :

shortlink char(7) NOT NULL
expiration_length_in_minutes int NOT NULL
created_at datetime NOT NULL
paste_path varchar(255) NOT NULL
PRIMARY KEY(shortlink)

Chúng ta sẽ đánh index trên shortlink và created_at để tăng tốc tra cứu và lưu trữ dữ liệu trên RAM. Đọc 1MB liên tục từ bộ nhớ mất khoảng 250ms, trong khi đó đọc trên SSD gấp 4 lần và 80 lần trên HDD Để tạo URL duy nhất thì :

  • Lấy MD5 hash của IP người dùng cộng với timestamp
    • Tạo MD5 128 bit
    • Sử dụng đồng nhất mã MD5
    • Ngoài ra chúng ta có thể lấy mã MD5 bằng cách tạo random ngẫu nhiên
  • Base62 để encode mã MD5
    • Base 62 encode thành [a-zA-Z0-9], loại bỏ việc yêu cầu những ký tự đặc biệt
    • Chỉ có 1 kết quả hask cho đầu vào và Base62 là mặc định (không random)
    • Base 64 là một kiểu mã hoá khác khá phổ biến nhưng gặp những vấn đề với URL bởi vì có thêm ký tự “+” và “/”

Use case : Người dùng sẽ paste link vào trình duyệt và xem các nội dung

  • Client gửi một yêu cầu dán vào Web server
  • Web server chuyển tiếp yêu cầu đến máy chủ Read API
  • Server Read API Đọc sẽ làm như sau:
    • Kiểm tra cơ sở dữ liệu SQL cho URL đã tạo ra
      • Nếu URL nằm trong SQL DB, paste contact đó tới Object Store
      • Ngược lại trả lại thông tin lỗi cho người dùng

REST API:

curl https://example.com/api/v1/paste?shortlink=foobar

Response:

{
    "paste_contents": "Hello World"
    "created_at": "YYYY-MM-DD HH:MM:SS"
    "expiration_length_in_minutes": "60"``
}

Use case : Dịch vụ phân tích

  • Trích xuất được URL từ trong log file
  • Trả lại được ngày tháng năm từ timestamp
  • Phân tích log, trích xuất những thông tin cần, tạo thành các bảng phù hợp với mục đích và có thể sort được theo một trường bất kỳ trong bảng

Use case : Có service xoá những link đã hết hạn

Để xoá những paste đã hết hạn, đơn giản bạn chỉ cần quét cơ sở dữ liệu và với nhưng link nào có thời gian lớn hơn 1 khoảng thời gian thì sẽ bị xoá đi. Khoảng thời gian này có thể là 3 tháng, 6 tháng hay 1 năm tuỳ vào bạn .

Step 4: Scale thiết kế của bạn

Bạn sẽ phải làm việc này lặp đi lặp lại :

  • Benchmark/Load Test
  • Có được thông tin nghẽn cổ chai
  • Có được phương án xử lý các trường hợp nghẽn cổ chai
  • Làm lại các bước trên Điều quan trọng là bạn phải trao đổi thảo luận về những nút thắt cổ chai bạn có thể gặp phải với thiết kế ban đầu và cách bạn có thể giải quyết từng vấn đề. Ví dụ, những vấn đề nào được giải quyết bằng cách thêm một Load Balancer với nhiều server Web? CDN? Master-Slave Replication . Các lựa chọn thay thế cho mỗi trường hợp là gì ?

Kết luận

Bản thân người viết bạn cũng còn nhiều hạn chế, rất mong các bạn có thể tham khảo cũng như thảo luận thêm cùng với mình để cùng hiểu rõ và sâu hơn. Rất mong nhận được các ý kiến đóng góp từ phía các bạn.

Contact

Email : [email protected] Skype : ltminh258