Cách chia tỷ lệ từ 1 đến 100 người dùng

Nhiều công ty khởi nghiệp đã trải qua điều này: rất đông người dùng mới đăng ký mỗi ngày và nhóm phát triển phải vật lộn để duy trì hoạt động của dịch vụ.

Đó là một vấn đề thú vị nhưng có rất ít thông tin rõ ràng trên web về cách cẩn thận mở rộng quy mô ứng dụng web từ con số không cho đến hàng trăm nghìn người dùng. Thông thường có giải pháp chữa cháy hoặc giải pháp thắt cổ chai (và thường là cả hai). Do đó, mọi người sử dụng những kỹ thuật khá sáo rỗng để mở rộng dự án nghiệp dư của họ thành một dự án thực sự nghiêm túc.

Hãy thử lọc thông tin và viết ra công thức cơ bản. Chúng tôi sẽ mở rộng quy mô trang chia sẻ ảnh mới Graminsta của mình từng bước từ 1 đến 100 người dùng.

Hãy viết ra những hành động cụ thể cần thực hiện khi lượng khán giả tăng lên 10, 100, 1000, 10 và 000 người.

1 người dùng: 1 máy

Hầu hết mọi ứng dụng, dù là trang web hay ứng dụng di động, đều có ba thành phần chính:

  • API
  • cơ sở dữ liệu
  • khách hàng (chính ứng dụng di động hoặc trang web)

Cơ sở dữ liệu lưu trữ dữ liệu liên tục. API phục vụ các yêu cầu đến và xung quanh dữ liệu này. Máy khách truyền dữ liệu đến người dùng.

Tôi đi đến kết luận rằng việc nói về việc mở rộng quy mô ứng dụng sẽ dễ dàng hơn nhiều nếu, từ quan điểm kiến ​​trúc, ứng dụng khách và các thực thể API hoàn toàn tách biệt.

Khi chúng ta bắt đầu xây dựng một ứng dụng lần đầu tiên, cả ba thành phần đều có thể chạy trên cùng một máy chủ. Ở một khía cạnh nào đó, điều này tương tự như môi trường phát triển của chúng tôi: một kỹ sư chạy cơ sở dữ liệu, API và ứng dụng khách trên cùng một máy.

Về lý thuyết, chúng tôi có thể triển khai nó trên đám mây trên một phiên bản DigitalOcean Droplet hoặc AWS EC2, như minh họa bên dưới:
Cách chia tỷ lệ từ 1 đến 100 người dùng
Như đã nói, nếu có nhiều hơn một người dùng trên một trang web, thì việc dành một lớp cơ sở dữ liệu hầu như luôn hợp lý.

10 người dùng: chuyển cơ sở dữ liệu sang một cấp độ riêng

Việc chia cơ sở dữ liệu thành các dịch vụ được quản lý như Amazon RDS hoặc Cơ sở dữ liệu được quản lý bởi Digital Ocean sẽ phục vụ tốt cho chúng ta trong thời gian dài. Nó đắt hơn một chút so với việc tự lưu trữ trên một máy hoặc phiên bản EC2, nhưng với những dịch vụ này, bạn sẽ nhận được rất nhiều tiện ích mở rộng hữu ích sẵn có và sẽ hữu ích trong tương lai: sao lưu đa vùng, đọc bản sao, tự động bản sao lưu và hơn thế nữa.

Đây là giao diện của hệ thống bây giờ:
Cách chia tỷ lệ từ 1 đến 100 người dùng

100 người dùng: chuyển khách hàng sang một cấp độ riêng

May mắn thay, những người dùng đầu tiên thực sự thích ứng dụng của chúng tôi. Lưu lượng truy cập ngày càng ổn định hơn, vì vậy đã đến lúc chuyển khách hàng sang một cấp độ riêng. Cần lưu ý rằng tách biệt thực thể là một khía cạnh quan trọng của việc xây dựng một ứng dụng có thể mở rộng. Khi một phần của hệ thống nhận được nhiều lưu lượng truy cập hơn, chúng tôi có thể phân vùng nó để kiểm soát cách dịch vụ mở rộng quy mô dựa trên các mẫu lưu lượng truy cập cụ thể.

Đây là lý do tại sao tôi thích coi ứng dụng khách tách biệt với API. Điều này giúp bạn dễ dàng nghĩ đến việc phát triển cho nhiều nền tảng: web, web di động, iOS, Android, ứng dụng dành cho máy tính để bàn, dịch vụ của bên thứ ba, v.v. Tất cả đều chỉ là những ứng dụng khách sử dụng cùng một API.

Ví dụ: hiện nay người dùng của chúng tôi thường yêu cầu phát hành một ứng dụng di động. Nếu bạn tách biệt các thực thể ứng dụng khách và API thì việc này sẽ trở nên dễ dàng hơn.

Một hệ thống như vậy trông như thế này:

Cách chia tỷ lệ từ 1 đến 100 người dùng

1000 người dùng: thêm bộ cân bằng tải

Mọi thứ đang được cải thiện. Người dùng Graminsta ngày càng tải lên nhiều ảnh hơn. Số lượng đăng ký cũng ngày càng tăng. Máy chủ API duy nhất của chúng tôi đang gặp khó khăn trong việc theo kịp tất cả lưu lượng truy cập. Cần thêm sắt!

Cân bằng tải là một khái niệm rất mạnh mẽ. Ý tưởng chính là chúng tôi đặt bộ cân bằng tải trước API và nó phân phối lưu lượng truy cập đến các phiên bản dịch vụ riêng lẻ. Đây là cách chúng tôi mở rộng quy mô theo chiều ngang, nghĩa là chúng tôi thêm nhiều máy chủ có cùng mã, tăng số lượng yêu cầu chúng tôi có thể xử lý.

Chúng tôi sẽ đặt các bộ cân bằng tải riêng biệt trước máy khách web và trước API. Điều này có nghĩa là bạn có thể chạy nhiều phiên bản chạy mã API và mã máy khách web. Bộ cân bằng tải sẽ chuyển các yêu cầu đến máy chủ được tải ít hơn.

Ở đây chúng ta có được một lợi thế quan trọng khác - tính dự phòng. Khi một phiên bản bị lỗi (có thể bị quá tải hoặc bị hỏng), chúng tôi chỉ còn lại những phiên bản khác tiếp tục phản hồi các yêu cầu đến. Nếu chỉ có một phiên bản hoạt động thì trong trường hợp xảy ra lỗi, toàn bộ hệ thống sẽ bị hỏng.

Bộ cân bằng tải cũng cung cấp tính năng tự động điều chỉnh quy mô. Chúng tôi có thể định cấu hình nó để tăng số lượng phiên bản trước khi tải tối đa và giảm số lượng phiên bản khi tất cả người dùng đang ngủ.

Với bộ cân bằng tải, cấp độ API có thể được điều chỉnh gần như vô thời hạn, chỉ cần thêm phiên bản mới khi số lượng yêu cầu tăng lên.

Cách chia tỷ lệ từ 1 đến 100 người dùng

Ghi chú. Hiện tại, hệ thống của chúng tôi rất giống với những gì các công ty PaaS như Heroku hoặc Elastic Beanstalk trên AWS cung cấp ngay lập tức (đó là lý do tại sao chúng rất phổ biến). Heroku đặt cơ sở dữ liệu trên một máy chủ riêng biệt, quản lý bộ cân bằng tải tự động mở rộng quy mô và cho phép bạn lưu trữ ứng dụng khách web riêng biệt với API. Đây là lý do tuyệt vời để sử dụng Heroku cho các dự án hoặc công ty khởi nghiệp ở giai đoạn đầu - bạn nhận được tất cả các dịch vụ cơ bản ngay lập tức.

10 người dùng: CDN

Có lẽ chúng ta nên làm điều này ngay từ đầu. Việc xử lý yêu cầu và chấp nhận ảnh mới đang bắt đầu gây quá nhiều áp lực lên máy chủ của chúng tôi.

Ở giai đoạn này, bạn cần sử dụng dịch vụ đám mây để lưu trữ nội dung tĩnh - hình ảnh, video, v.v. (AWS S3 hoặc Digital Ocean Spaces). Nói chung, API của chúng tôi nên tránh xử lý những việc như cung cấp hình ảnh và tải hình ảnh lên máy chủ.

Một ưu điểm khác của dịch vụ lưu trữ đám mây là CDN (AWS gọi tiện ích bổ sung này là Cloudfront, nhưng nhiều nhà cung cấp dịch vụ lưu trữ đám mây cung cấp ngay tính năng này). CDN tự động lưu trữ hình ảnh của chúng tôi ở nhiều trung tâm dữ liệu khác nhau trên khắp thế giới.

Mặc dù trung tâm dữ liệu chính của chúng tôi có thể được đặt tại Ohio, nhưng nếu ai đó yêu cầu hình ảnh từ Nhật Bản, nhà cung cấp đám mây sẽ tạo một bản sao và lưu trữ nó trong trung tâm dữ liệu Nhật Bản của họ. Người tiếp theo yêu cầu hình ảnh này ở Nhật Bản sẽ nhận được nó nhanh hơn nhiều. Điều này rất quan trọng khi chúng ta làm việc với các tệp lớn, như ảnh hoặc video, mất nhiều thời gian để tải xuống và truyền đi khắp hành tinh.

Cách chia tỷ lệ từ 1 đến 100 người dùng

100 người dùng: mở rộng lớp dữ liệu

CDN đã giúp ích rất nhiều: lưu lượng truy cập đang tăng ở tốc độ tối đa. Blogger video nổi tiếng Mavid Mobrick vừa đăng ký với chúng tôi và đăng “câu chuyện” của anh ấy, như họ nói. Nhờ có bộ cân bằng tải, mức sử dụng CPU và bộ nhớ trên máy chủ API được giữ ở mức thấp (mười phiên bản API đang chạy), nhưng chúng tôi bắt đầu gặp nhiều tình trạng hết thời gian chờ đối với các yêu cầu... những sự chậm trễ này đến từ đâu?

Đi sâu hơn một chút vào các số liệu, chúng ta thấy rằng CPU trên máy chủ cơ sở dữ liệu đã được tải 80-90%. Chúng ta đang ở giới hạn.

Chia tỷ lệ lớp dữ liệu có lẽ là phần khó nhất của phương trình. Máy chủ API phục vụ các yêu cầu không trạng thái, vì vậy chúng tôi chỉ cần thêm nhiều phiên bản API hơn. Mũi đa số cơ sở dữ liệu không thể làm điều này. Chúng ta sẽ nói về các hệ thống quản lý cơ sở dữ liệu quan hệ phổ biến (PostgreSQL, MySQL, v.v.).

bộ nhớ đệm

Một trong những cách dễ nhất để tăng hiệu suất cơ sở dữ liệu của chúng tôi là giới thiệu một thành phần mới: lớp bộ đệm. Phương pháp lưu vào bộ nhớ đệm phổ biến nhất là lưu trữ bản ghi khóa-giá trị trong bộ nhớ, chẳng hạn như Redis hoặc Memcached. Hầu hết các đám mây đều có phiên bản được quản lý của các dịch vụ này: Elasticache trên AWS và Memorystore trên Google Cloud.

Bộ đệm rất hữu ích khi một dịch vụ thực hiện nhiều lệnh gọi lặp lại tới cơ sở dữ liệu để truy xuất cùng một thông tin. Về cơ bản, chúng tôi chỉ truy cập cơ sở dữ liệu một lần, lưu trữ thông tin vào bộ đệm và không chạm vào nó nữa.

Ví dụ: trong dịch vụ Graminsta của chúng tôi, mỗi khi ai đó truy cập trang hồ sơ của ngôi sao Mobrik, máy chủ API sẽ truy vấn cơ sở dữ liệu để biết thông tin từ hồ sơ của anh ấy. Điều này xảy ra nhiều lần. Vì thông tin hồ sơ của Mobrik không thay đổi theo mỗi yêu cầu nên rất lý tưởng cho việc lưu vào bộ nhớ đệm.

Chúng tôi sẽ lưu trữ kết quả từ cơ sở dữ liệu trong Redis bằng khóa user:id với thời gian hiệu lực là 30 giây. Bây giờ, khi ai đó truy cập hồ sơ của Mobrik, trước tiên chúng tôi sẽ kiểm tra Redis và nếu dữ liệu có ở đó, chúng tôi chỉ cần chuyển dữ liệu trực tiếp từ Redis. Bây giờ các yêu cầu tới hồ sơ phổ biến nhất trên trang web thực tế không tải cơ sở dữ liệu của chúng tôi.

Một ưu điểm khác của hầu hết các dịch vụ bộ nhớ đệm là chúng dễ mở rộng quy mô hơn các máy chủ cơ sở dữ liệu. Redis có chế độ Redis Cluster tích hợp sẵn. Tương tự với cân bằng tải1, nó cho phép bạn phân phối bộ đệm Redis của mình trên nhiều máy (trên hàng nghìn máy chủ nếu cần).

Hầu như tất cả các ứng dụng quy mô lớn đều sử dụng bộ nhớ đệm; nó là một phần không thể thiếu của API nhanh. Xử lý truy vấn nhanh hơn và mã hiệu quả hơn đều quan trọng, nhưng nếu không có bộ đệm thì gần như không thể mở rộng dịch vụ cho hàng triệu người dùng.

Đọc bản sao

Khi số lượng truy vấn tới cơ sở dữ liệu tăng lên rất nhiều, một điều nữa chúng ta có thể làm là thêm các bản sao chỉ có quyền đọc vào hệ thống quản lý cơ sở dữ liệu. Với các dịch vụ được quản lý được mô tả ở trên, việc này có thể được thực hiện chỉ bằng một cú nhấp chuột. Bản sao chỉ có quyền đọc sẽ vẫn hiện hành trong cơ sở dữ liệu chính và có sẵn cho các câu lệnh SELECT.

Đây là hệ thống của chúng tôi bây giờ:

Cách chia tỷ lệ từ 1 đến 100 người dùng

Các bước tiếp theo

Khi ứng dụng tiếp tục mở rộng quy mô, chúng tôi sẽ tiếp tục tách các dịch vụ để mở rộng quy mô một cách độc lập. Ví dụ: nếu chúng ta bắt đầu sử dụng Websockets, thì việc kéo mã xử lý Websockets vào một dịch vụ riêng là điều hợp lý. Chúng tôi có thể đặt nó trên các phiên bản mới đằng sau bộ cân bằng tải của riêng mình. Bộ cân bằng tải này có thể mở rộng quy mô dựa trên các kết nối Websockets mở và bất kể số lượng yêu cầu HTTP.

Chúng tôi cũng sẽ tiếp tục chống lại các hạn chế ở cấp cơ sở dữ liệu. Ở giai đoạn này là lúc nghiên cứu phân vùng và phân mảnh cơ sở dữ liệu. Cả hai phương pháp đều yêu cầu thêm chi phí nhưng cho phép bạn mở rộng quy mô cơ sở dữ liệu gần như vô thời hạn.

Chúng tôi cũng muốn cài đặt dịch vụ giám sát và phân tích như New Relic hoặc Datadog. Điều này sẽ giúp bạn xác định các truy vấn chậm và hiểu những điểm cần cải thiện. Khi mở rộng quy mô, chúng tôi muốn tập trung vào việc tìm ra các điểm nghẽn và loại bỏ chúng—thường sử dụng một số ý tưởng từ các phần trước.

nguồn

Bài đăng này được lấy cảm hứng từ một trong những bài viết yêu thích của tôi về khả năng mở rộng cao. Tôi muốn làm cho bài viết cụ thể hơn một chút về giai đoạn đầu của dự án và tháo gỡ nó khỏi một nhà cung cấp. Hãy chắc chắn đọc nếu bạn quan tâm đến chủ đề này.

Chú thích

  1. Mặc dù tương tự về mặt phân phối tải trên nhiều phiên bản, nhưng cách triển khai cơ bản của cụm Redis rất khác so với bộ cân bằng tải. [trở lại]

Cách chia tỷ lệ từ 1 đến 100 người dùng

Nguồn: www.habr.com

Thêm một lời nhận xét