Mở rộng quy mô tải của các ứng dụng web. Tỉ lệ theo chiều dọc và chiều ngang. Thành phần không quốc tịch

Rất nhiều lời đã được nói về chủ đề này cả trên blog của tôi và hơn thế nữa. Đối với tôi, có vẻ như đã đến lúc phải chuyển từ cái cụ thể sang cái chung và cố gắng xem xét chủ đề này một cách tách biệt với bất kỳ việc triển khai thành công nào của nó.

Chúng ta bắt đầu nhé?

Để bắt đầu, việc quyết định chúng ta sẽ nói về điều gì là điều hợp lý. Trong bối cảnh này, ứng dụng web có ba mục tiêu chính:

  • khả năng mở rộng- khả năng đáp ứng kịp thời trước sự tăng trưởng tải liên tục và lượng người dùng bất ngờ;
  • khả dụng- cung cấp quyền truy cập vào ứng dụng ngay cả trong trường hợp khẩn cấp;
  • hiệu suất- ngay cả một sự chậm trễ nhỏ nhất trong việc tải trang cũng có thể để lại ấn tượng tiêu cực cho người dùng.

Như bạn có thể đoán, chủ đề chính của cuộc trò chuyện sẽ là khả năng mở rộng, nhưng tôi không nghĩ các mục tiêu khác sẽ bị gạt sang một bên. Tôi muốn nói ngay vài lời về khả năng truy cập, để sau này không quay lại vấn đề này, nghĩa là “không cần phải nói”: bất kỳ trang web nào bằng cách này hay cách khác đều cố gắng hoạt động ổn định nhất có thể, nghĩa là có thể truy cập được dành cho tất cả khách truy cập tiềm năng vào mọi thời điểm, nhưng đôi khi tất cả các loại tình huống không lường trước được đều xảy ra có thể gây ra tình trạng không có sẵn tạm thời. Để giảm thiểu tác động tiềm ẩn đối với tính khả dụng của ứng dụng, cần tránh có các thành phần trong hệ thống, nếu lỗi có thể xảy ra sẽ dẫn đến không có sẵn bất kỳ chức năng hoặc dữ liệu nào (hoặc ít nhất là toàn bộ trang web). Do đó, mỗi máy chủ hoặc bất kỳ thành phần nào khác của hệ thống phải có ít nhất một bản sao lưu (bất kể chúng sẽ hoạt động ở chế độ nào: song song hay một cái “sao lưu” cái kia, khi đang ở chế độ chế độ thụ động) và dữ liệu phải được sao chép thành ít nhất hai bản sao (và tốt nhất không phải ở cấp độ RAID mà trên các máy vật lý khác nhau). Lưu trữ nhiều bản sao lưu dữ liệu ở đâu đó tách biệt khỏi hệ thống chính (ví dụ: trên những dịch vụ đặc biệt hoặc trên một cụm riêng biệt) cũng sẽ giúp tránh được nhiều vấn đề nếu có sự cố xảy ra. Đừng quên khía cạnh tài chính của vấn đề: bảo hiểm trong trường hợp hỏng hóc đòi hỏi phải đầu tư thêm đáng kể vào thiết bị, điều này là hợp lý để cố gắng giảm thiểu.

Khả năng mở rộng thường được chia thành hai lĩnh vực:

Khả năng mở rộng theo chiều dọc Tăng hiệu suất của từng thành phần hệ thống để cải thiện Tổng hiệu suất. Khả năng mở rộng theo chiều ngang Chia nhỏ một hệ thống thành các thành phần cấu trúc nhỏ hơn và tách chúng thành các thành phần riêng biệt máy vật lý(hoặc nhóm của họ) và/hoặc tăng số lượng máy chủ thực hiện song song cùng chức năng.

Bằng cách này hay cách khác, khi phát triển chiến lược phát triển hệ thống, bạn phải tìm kiếm sự dung hòa giữa giá cả, thời gian phát triển, hiệu suất cuối cùng, tính ổn định và một loạt các tiêu chí khác. Từ quan điểm tài chính, khả năng mở rộng theo chiều dọc không phải là giải pháp hấp dẫn nhất, bởi vì giá máy chủ có số lượng bộ xử lý lớn luôn tăng gần như theo cấp số nhân so với số lượng bộ xử lý. Đây là lý do tại sao cách tiếp cận theo chiều ngang là thú vị nhất, vì nó được sử dụng trong hầu hết các trường hợp. Nhưng khả năng mở rộng theo chiều dọc đôi khi có quyền tồn tại, đặc biệt là trong các tình huống mà thời gian và tốc độ giải quyết vấn đề đóng vai trò chính chứ không phải vấn đề tài chính: suy cho cùng, hãy mua máy chủ LỚN nhanh hơn đáng kể so với việc phát triển một ứng dụng từ đầu trên thực tế, điều chỉnh nó để hoạt động trên một số lượng lớn các máy chủ chạy song song.

Đã kết thúc với trong các điều khoản chung chúng ta hãy đi đến phần đánh giá vấn đề tiềm ẩn và các lựa chọn cho giải pháp của họ khi mở rộng quy mô theo chiều ngang. Xin đừng chỉ trích quá nhiều - Tôi không khẳng định sự đúng đắn và đáng tin cậy tuyệt đối, tôi chỉ “nghĩ lớn ra” và chắc chắn tôi sẽ không thể đề cập đến tất cả các điểm trong chủ đề này.

Máy chủ ứng dụng

Trong quá trình mở rộng quy mô ứng dụng, các vấn đề hiếm khi phát sinh nếu trong quá trình phát triển, bạn luôn lưu ý rằng mỗi phiên bản của ứng dụng không được kết nối trực tiếp với “đồng nghiệp” của nó và có thể xử lý hoàn toàn mọi yêu cầu của người dùng, bất kể về nơi các yêu cầu trước đó được xử lý người dùng nhất định và chính xác thì anh ấy muốn gì từ toàn bộ ứng dụng vào lúc này.

Hơn nữa, đảm bảo tính độc lập của mỗi cá nhân ứng dụng đang chạy, ngày càng có nhiều thứ có thể được xử lý và số lượng lớn yêu cầu trên một đơn vị thời gian chỉ bằng cách tăng số lượng máy chủ ứng dụng hoạt động song song tham gia vào hệ thống. Mọi thứ khá đơn giản (tương đối).

Cân bằng tải

Nhiệm vụ tiếp theo là phân bổ đều các yêu cầu giữa các máy chủ ứng dụng có sẵn. Có nhiều cách tiếp cận để giải quyết vấn đề này và thậm chí còn có nhiều sản phẩm cung cấp cách triển khai cụ thể hơn.

Thiết bị phần cứng mạng, cho phép bạn phân phối tải giữa một số máy chủ, thường tốn một khoản khá lớn, nhưng trong số các tùy chọn khác, phương pháp này thường mang lại hiệu suất và độ ổn định cao nhất (chủ yếu là do chất lượng, cộng với những thiết bị như vậy đôi khi đi kèm theo cặp, hoạt động theo nguyên tắc). Có khá nhiều thương hiệu nghiêm túc trong ngành này cung cấp giải pháp của họ - có rất nhiều lựa chọn: Cisco, xưởng đúc, NetScalar và nhiều người khác. Phần mềm Thậm chí còn có sự đa dạng hơn trong lĩnh vực này những lựa chọn khả thi. Không dễ để đạt được hiệu suất phần mềm có thể so sánh với các giải pháp phần cứng và HeartBeat sẽ phải được cung cấp trong phần mềm, nhưng thiết bị để vận hành giải pháp đó là một máy chủ thông thường (có thể nhiều hơn một). Như là sản phẩm phần mềm khá nhiều, chúng thường chỉ là các máy chủ HTTP chuyển tiếp yêu cầu đến đồng nghiệp của chúng trên các máy chủ khác thay vì gửi chúng trực tiếp đến trình thông dịch ngôn ngữ lập trình để xử lý. Ví dụ: bạn có thể đề cập đến mod_proxy. Ngoài ra, còn có nhiều tùy chọn kỳ lạ hơn dựa trên DNS, nghĩa là trong quá trình khách hàng xác định địa chỉ IP của máy chủ với tài nguyên Internet mà nó cần, địa chỉ được cấp có tính đến tải trên các máy chủ có sẵn, cũng như một số cân nhắc về địa lý.

Mỗi lựa chọn đều có những mặt tích cực và tiêu cực riêng, đó là lý do tại sao không có giải pháp rõ ràng cho vấn đề này - mỗi lựa chọn đều tốt trong tình huống cụ thể của riêng nó. Đừng quên rằng không ai giới hạn bạn chỉ sử dụng một trong số chúng; nếu cần, bạn có thể dễ dàng thực hiện sự kết hợp gần như tùy ý giữa chúng.

Điện toán sử dụng nhiều tài nguyên

Nhiều ứng dụng sử dụng một số cơ chế phức tạp, điều này có thể là chuyển đổi video, hình ảnh, âm thanh hoặc đơn giản là thực hiện một số phép tính tốn nhiều tài nguyên. Những tác vụ như vậy đòi hỏi sự chú ý đặc biệt nếu chúng ta đang nói về Web, vì người dùng tài nguyên Internet khó có thể hài lòng khi xem tải trang trong vài phút, chỉ chờ nhìn thấy thông báo như: "Thao tác đã hoàn tất thành công!"

Để tránh những tình huống như vậy, bạn nên cố gắng giảm thiểu hiệu suất của các hoạt động sử dụng nhiều tài nguyên một cách đồng bộ với việc tạo các trang Internet. Nếu một hoạt động cụ thể không ảnh hưởng trang mớiđược gửi tới người dùng, bạn chỉ cần sắp xếp xếp hàng những nhiệm vụ cần phải hoàn thành. Trong trường hợp này, tại thời điểm người dùng đã hoàn thành tất cả các hành động cần thiết để bắt đầu thao tác, máy chủ ứng dụng chỉ cần thêm một tác vụ mới vào hàng đợi và ngay lập tức bắt đầu tạo trang tiếp theo mà không cần chờ kết quả. Nếu nhiệm vụ thực sự tốn nhiều công sức thì hàng đợi và trình xử lý công việc như vậy có thể được đặt trên một máy chủ hoặc cụm riêng biệt.

Nếu kết quả của một hoạt động có liên quan đến Trang tiếp theođược gửi cho người dùng, thì nếu nó được thực thi không đồng bộ, bạn sẽ phải gian lận một chút và bằng cách nào đó khiến người dùng mất tập trung trong khi nó đang được thực thi. Ví dụ, nếu Chúng ta đang nói về về việc chuyển đổi video sang flv, chẳng hạn, bạn có thể nhanh chóng tạo ảnh chụp màn hình với khung đầu tiên trong quá trình biên dịch trang và thay thế nó vào vị trí của video, đồng thời tự động thêm tùy chọn xem vào trang sau khi quá trình chuyển đổi hoàn tất.

Một phương pháp tốt khác để xử lý những tình huống như vậy là chỉ cần yêu cầu người dùng "quay lại sau". Ví dụ: nếu dịch vụ tạo ảnh chụp màn hình của các trang web từ các trình duyệt khác nhauđể chứng minh tính chính xác của màn hình hiển thị của chúng cho chủ sở hữu hoặc những người chỉ quan tâm, thì việc tạo một trang với chúng có thể không chỉ mất vài giây mà là vài phút. Cách thuận tiện nhất cho người dùng trong tình huống như vậy là đề nghị truy cập trang tại địa chỉ được chỉ định trong rất nhiều phút, và không phải chờ đợi một khoảng thời gian vô thời hạn bên bờ biển để biết thời tiết.

Phiên

Hầu hết tất cả các ứng dụng web đều tương tác theo cách nào đó với khách truy cập và trong phần lớn các trường hợp cần phải theo dõi chuyển động của người dùng trên các trang của trang web. Để giải quyết vấn đề này người ta thường sử dụng cơ chế phiên, bao gồm việc gán cho mỗi khách truy cập một địa chỉ duy nhất mã số, được chuyển đến nó để lưu trữ trong cookie hoặc, trong trường hợp không có cookie, để liên tục “kéo” cùng với chính nó thông qua GET. Sau khi nhận được một ID nhất định từ người dùng cùng với yêu cầu HTTP tiếp theo, máy chủ có thể xem danh sách các số đã được phát hành và xác định rõ ràng ai đã gửi nó. Mỗi ID có thể được liên kết với một bộ dữ liệu nhất định mà ứng dụng web có thể sử dụng theo ý mình; dữ liệu này thường được lưu trữ theo mặc định trong một tệp trong thư mục tạm thời trên máy chủ.

Có vẻ như mọi thứ đều đơn giản, nhưng... nhưng yêu cầu từ khách truy cập vào cùng một trang web có thể được xử lý bởi một số máy chủ cùng một lúc, làm cách nào để xác định xem ID nhận được có được cấp trên máy chủ khác hay không và dữ liệu của nó thường được lưu trữ ở đâu ?

Các giải pháp phổ biến nhất là tập trung hóa hoặc phân cấp dữ liệu phiên. Một cụm từ hơi vô lý, nhưng hy vọng một vài ví dụ có thể làm sáng tỏ mọi thứ:

Lưu trữ phiên tập trungÝ tưởng rất đơn giản: tạo một “con heo đất” chung cho tất cả các máy chủ, nơi họ có thể đặt các phiên mà họ phát hành và tìm hiểu về các phiên của khách truy cập vào các máy chủ khác. Về mặt lý thuyết, vai trò của một “con heo đất” như vậy có thể chỉ đơn giản là một hệ thống tệp được gắn trên mạng, nhưng vì một số lý do, việc sử dụng một số loại DBMS có vẻ hứa hẹn hơn, vì điều này giúp loại bỏ rất nhiều vấn đề liên quan đến việc lưu trữ dữ liệu phiên trong các tập tin. Nhưng trong phiên bản có cơ sở, nền tảng chung dữ liệu, đừng quên rằng tải trên đó sẽ tăng đều đặn khi số lượng khách truy cập tăng lên và cũng đáng để cung cấp trước các tùy chọn để giải quyết các tình huống có vấn đề liên quan đến các lỗi tiềm ẩn trong hoạt động của máy chủ với DBMS này. Lưu trữ phiên phi tập trung Một ví dụ tốt- lưu trữ các phiên trong , ban đầu được thiết kế để lưu trữ dữ liệu phân tán trong bộ nhớ truy cập tạm thời hệ thống sẽ cho phép tất cả các máy chủ nhận truy cập nhanh với bất kỳ dữ liệu phiên nào, nhưng đồng thời (không giống như phương pháp trước đó) bất kỳ trung tâm một cửa sẽ không có nơi lưu trữ cho chúng. Điều này sẽ tránh được tình trạng tắc nghẽn về hiệu suất và độ ổn định trong thời gian bận rộn.

Để thay thế cho phiên, các cơ chế có mục đích tương tự, được xây dựng trên cookie, đôi khi được sử dụng, nghĩa là tất cả được yêu cầu bởi ứng dụng dữ liệu người dùng được lưu trữ ở phía máy khách (có thể được mã hóa) và được yêu cầu khi cần. Nhưng ngoài những lợi ích rõ ràng liên quan đến việc không phải lưu trữ dữ liệu không cần thiết trên máy chủ, một số vấn đề về bảo mật cũng phát sinh. Dữ liệu được lưu trữ ở phía máy khách, ngay cả ở dạng mã hóa, gây ra mối đe dọa tiềm tàng đối với hoạt động của nhiều ứng dụng, vì bất kỳ ai cũng có thể cố gắng sửa đổi dữ liệu đó vì lợi ích riêng của họ hoặc nhằm gây hại cho ứng dụng. Cách tiếp cận này chỉ tốt nếu có niềm tin rằng mọi thao tác dữ liệu được người dùng lưu trữ đều an toàn. Nhưng có thể chắc chắn 100% được không?

Nội dung tĩnh

Mặc dù khối lượng dữ liệu tĩnh nhỏ - không ai bận tâm đến việc lưu trữ chúng trong hệ thống tệp cục bộ và cung cấp quyền truy cập vào chúng một cách đơn giản thông qua một máy chủ web nhẹ riêng biệt như (ý tôi chủ yếu là các dạng dữ liệu phương tiện khác nhau), nhưng sớm hay muộn thì máy chủ sẽ đạt tới giới hạn về dung lượng ổ đĩa hoặc giới hạn của hệ thống tệp về số lượng tệp trong một thư mục và bạn sẽ phải nghĩ đến việc phân phối lại nội dung. Một giải pháp tạm thời có thể là phân phối dữ liệu theo loại vào máy chủ khác nhau hoặc có thể sử dụng cấu trúc thư mục phân cấp.

Nếu nội dung tĩnh đóng một trong những vai trò chính trong hoạt động của ứng dụng thì bạn nên suy nghĩ đến việc sử dụng hệ thống tệp phân tán để lưu trữ nội dung đó. Đây có lẽ là một trong số ít cách để tăng quy mô âm lượng theo chiều ngang không gian đĩa bằng cách thêm các máy chủ bổ sung mà không thực hiện bất kỳ thay đổi cơ bản nào đối với hoạt động của chính ứng dụng. Tôi không muốn đưa ra bất kỳ lời khuyên nào về việc nên chọn hệ thống tệp cụm nào ngay bây giờ; Tôi đã xuất bản nhiều bài đánh giá về các triển khai cụ thể - hãy thử đọc tất cả và so sánh, nếu điều này là chưa đủ, phần còn lại của Mạng là theo ý của bạn.

Có lẽ tùy chọn này sẽ không khả thi vì một số lý do, khi đó bạn sẽ phải “phát minh lại bánh xe” để triển khai ở các nguyên tắc cấp ứng dụng tương tự như phân đoạn dữ liệu liên quan đến DBMS, mà tôi sẽ đề cập sau. Tùy chọn này cũng khá hiệu quả nhưng yêu cầu sửa đổi logic ứng dụng và do đó việc thực thi công việc làm thêm nhà phát triển.

Một giải pháp thay thế cho các phương pháp này là sử dụng cái gọi là Mạng phân phối nội dung - Dịch vụ bên ngoài, đảm bảo cung cấp nội dung của bạn cho người dùng để nhận được phần thưởng vật chất nhất định cho dịch vụ. Ưu điểm là rõ ràng - không cần phải tổ chức cơ sở hạ tầng của riêng bạn để giải quyết vấn đề này mà lại xuất hiện một khoản chi phí bổ sung khác. Tôi sẽ không đưa ra danh sách những dịch vụ như vậy nhưng nếu ai đó cần thì sẽ không khó tìm.

Bộ nhớ đệm

Bộ nhớ đệm có ý nghĩa ở tất cả các giai đoạn xử lý dữ liệu, nhưng chỉ có một số phương pháp bộ nhớ đệm là hiệu quả nhất đối với các loại ứng dụng khác nhau.

cơ sở dữ liệu Hầu hết tất cả các DBMS hiện đại đều cung cấp các cơ chế tích hợp sẵn để lưu trữ kết quả của một số truy vấn nhất định. Phương pháp này khá hiệu quả nếu hệ thống của bạn thường xuyên tạo các mẫu dữ liệu giống nhau, nhưng nó cũng có một số nhược điểm, nguyên nhân chính là làm mất hiệu lực bộ đệm của toàn bộ bảng chỉ với một thay đổi nhỏ nhất, cũng như vị trí cục bộ của bảng. bộ đệm, điều này không hiệu quả nếu có một số máy chủ trong bộ lưu trữ dữ liệu hệ thống. Ứng dụngỞ cấp độ ứng dụng, các đối tượng của bất kỳ ngôn ngữ lập trình nào thường được lưu trữ trong bộ nhớ đệm. Phương pháp này cho phép bạn tránh hoàn toàn một phần đáng kể các truy vấn tới DBMS, giảm đáng kể tải cho nó. Giống như bản thân các ứng dụng, bộ đệm như vậy phải độc lập với yêu cầu cụ thể và máy chủ mà nó được thực thi, nghĩa là nó phải có sẵn cho tất cả các máy chủ ứng dụng cùng một lúc và thậm chí tốt hơn là nó phải được phân phối trên nhiều máy chủ ứng dụng. máy để sử dụng RAM hiệu quả hơn. Người dẫn đầu trong khía cạnh bộ nhớ đệm này có thể được gọi một cách chính đáng, điều mà tôi đã từng đề cập. máy chủ HTTP Nhiều máy chủ web có các mô-đun bộ nhớ đệm như nội dung tĩnh và kết quả của các tập lệnh. Nếu trang hiếm khi được cập nhật thì việc sử dụng phương pháp này cho phép bạn tránh tạo trang để đáp ứng một phần khá lớn các yêu cầu mà người dùng không nhìn thấy bất kỳ thay đổi nào. Proxy ngược Bằng cách đặt một máy chủ proxy trong suốt giữa người dùng và máy chủ web, bạn có thể cung cấp cho người dùng dữ liệu từ bộ đệm proxy (có thể trong RAM hoặc đĩa) mà không cần gửi yêu cầu ngay cả đến máy chủ HTTP. Trong hầu hết các trường hợp, cách tiếp cận này chỉ phù hợp với nội dung tĩnh, chủ yếu các hình thức khác nhau dữ liệu đa phương tiện: hình ảnh, video và những thứ tương tự. Điều này cho phép các máy chủ web chỉ tập trung vào làm việc với chính các trang đó.

Về bản chất, bộ nhớ đệm thực tế không yêu cầu thêm chi phí phần cứng, đặc biệt nếu bạn giám sát cẩn thận việc sử dụng RAM của các thành phần máy chủ khác và sử dụng tất cả các dạng bộ nhớ đệm “dư thừa” có sẵn phù hợp nhất cho một ứng dụng cụ thể.

Việc vô hiệu hóa bộ đệm trong một số trường hợp có thể trở thành nhiệm vụ không tầm thường, nhưng bằng cách này hay cách khác giải pháp phổ quát mọi người vấn đề có thể xảy ra Không thể viết bất cứ điều gì liên quan đến nó (ít nhất là đối với cá nhân tôi), vì vậy hãy để câu hỏi này cho đến thời điểm tốt hơn. TRONG trường hợp chung Giải pháp cho vấn đề này nằm ở chính ứng dụng web, ứng dụng này thường thực hiện một số loại cơ chế vô hiệu hóa bằng cách xóa đối tượng bộ đệm thông qua một cơ chế nhất định. khoảng thời gian sau khi được tạo ra hoặc sử dụng lần cuối, hoặc “thủ công” khi nhất định sự kiện từ người dùng hoặc các thành phần hệ thống khác.

Cơ sở dữ liệu

Tôi để lại phần thú vị nhất cho món khai vị, vì thành phần không thể thiếu này của bất kỳ ứng dụng web nào gây ra nhiều vấn đề hơn khi tải tăng lên so với tất cả những thành phần khác cộng lại. Đôi khi, có vẻ như bạn nên từ bỏ hoàn toàn việc chia tỷ lệ theo chiều ngang của hệ thống lưu trữ dữ liệu để chuyển sang chia tỷ lệ theo chiều dọc - chỉ cần mua cùng một máy chủ LỚN đó với số tiền không phải là sáu hoặc bảy con số và không bận tâm đến những vấn đề không cần thiết.

Nhưng đối với nhiều dự án thì đây là quyết định hồng y(và nói chung là tạm thời) không phù hợp, có nghĩa là trước mắt họ chỉ còn một con đường - mở rộng quy mô theo chiều ngang. Hãy nói về cô ấy.

Con đường của hầu hết mọi dự án web từ quan điểm cơ sở dữ liệu đều bắt đầu bằng một máy chủ đơn giản, trên đó toàn bộ dự án đã hoạt động. Sau đó, tại một thời điểm thích hợp, nảy sinh nhu cầu di chuyển DBMS sang một máy chủ riêng, nhưng theo thời gian, nó cũng bắt đầu không đáp ứng được tải. Không có điểm cụ thể nào khi đi sâu vào chi tiết về hai giai đoạn này - mọi thứ đều tương đối tầm thường.

Bước tiếp theo thường hay xảy ra chủ nô với sao chép dữ liệu không đồng bộ, cách thức hoạt động của sơ đồ này đã được đề cập nhiều lần trong blog, nhưng có lẽ tôi sẽ nhắc lại: với phương pháp này, tất cả các thao tác ghi chỉ được thực hiện trên một máy chủ (chính) và các máy chủ còn lại (phụ) ) nhận dữ liệu trực tiếp từ “master”, trong khi chỉ xử lý các yêu cầu đọc dữ liệu. Như bạn đã biết, hoạt động đọc và ghi của bất kỳ dự án web nào luôn tăng tỷ lệ thuận với tải, trong khi tỷ lệ giữa cả hai loại yêu cầu vẫn gần như cố định: với mỗi yêu cầu cập nhật dữ liệu, thường có trung bình khoảng chục lượt đọc. yêu cầu. Theo thời gian, tải tăng lên, nghĩa là số lượng thao tác ghi trên một đơn vị thời gian cũng tăng lên, nhưng chỉ có một máy chủ xử lý chúng và sau đó nó cũng đảm bảo tạo ra một số lượng bản sao nhất định trên các máy chủ khác. Sớm hay muộn, chi phí cho các hoạt động sao chép dữ liệu sẽ trở nên cao đến mức quá trình này sẽ bắt đầu chiếm một phần rất lớn thời gian xử lý của mỗi máy chủ và mỗi máy chủ sẽ chỉ có thể xử lý một phần tương đối. một lượng nhỏđọc các hoạt động và do đó, mỗi máy chủ nô lệ bổ sung sẽ bắt đầu chỉ tăng tổng hiệu suất một chút, đồng thời phần lớn chỉ duy trì dữ liệu của mình theo “chính”.

Một giải pháp tạm thời cho vấn đề này có thể là thay thế máy chủ chính bằng một máy chủ hiệu quả hơn, nhưng bằng cách này hay cách khác, sẽ không thể trì hoãn vô tận quá trình chuyển đổi sang “cấp độ” phát triển hệ thống lưu trữ dữ liệu tiếp theo: "phân mảnh", mà gần đây tôi đã cống hiến. Vì vậy, hãy để tôi nói ngắn gọn về nó: ý tưởng là chia tất cả dữ liệu thành các phần theo một số đặc điểm và lưu trữ từng phần trên một máy chủ hoặc cụm riêng biệt, phần dữ liệu đó kết hợp với hệ thống lưu trữ dữ liệu chứa nó. nằm và được gọi là một đoạn hoặc mảnh vỡừm. Cách tiếp cận này cho phép bạn tránh được các chi phí liên quan đến việc sao chép dữ liệu (hoặc giảm chúng đi nhiều lần), và do đó đáng kể tăng hiệu suất tổng thể của hệ thống lưu trữ. Nhưng thật không may, việc chuyển đổi sang sơ đồ tổ chức dữ liệu này đòi hỏi rất nhiều chi phí thuộc loại khác. Vì không có giải pháp làm sẵn để triển khai nó, nên bạn phải sửa đổi logic ứng dụng hoặc thêm một “lớp” bổ sung giữa ứng dụng và DBMS và tất cả những điều này thường được các nhà phát triển dự án triển khai nhất. Các sản phẩm sẵn có chỉ có thể giúp công việc của chúng trở nên dễ dàng hơn bằng cách cung cấp một khuôn khổ để xây dựng kiến ​​trúc cơ bản của hệ thống lưu trữ dữ liệu và sự tương tác của nó với các thành phần ứng dụng còn lại.

Ở giai đoạn này, chuỗi thường kết thúc, vì cơ sở dữ liệu được phân đoạn có thể mở rộng theo chiều ngang để đáp ứng đầy đủ nhu cầu của ngay cả những tài nguyên Internet được tải nặng nhất. Sẽ là thích hợp nếu nói vài lời về cấu trúc dữ liệu thực tế trong cơ sở dữ liệu và cách tổ chức truy cập vào chúng, nhưng mọi quyết định đều phụ thuộc rất nhiều vào ứng dụng cụ thể và cách triển khai, vì vậy hãy để tôi đưa ra một vài khuyến nghị chung:

Không chuẩn hóa Các truy vấn thường kết hợp dữ liệu từ nhiều bảng, tất cả các dữ liệu khác đều bằng nhau, yêu cầu nhiều thời gian CPU hơn để thực thi so với truy vấn chỉ ảnh hưởng đến một bảng. Và hiệu suất, như đã đề cập ở đầu câu chuyện, là cực kỳ quan trọng trên Internet. Phân vùng dữ liệu logic Nếu một phần dữ liệu luôn được sử dụng riêng biệt với phần lớn thì đôi khi việc tách nó thành một hệ thống lưu trữ dữ liệu độc lập riêng biệt là điều hợp lý. Tối ưu hóa truy vấn cấp thấp Bằng cách duy trì và phân tích nhật ký yêu cầu, bạn có thể xác định nhật ký yêu cầu chậm nhất. Việc thay thế các truy vấn tìm thấy bằng các truy vấn hiệu quả hơn có cùng chức năng có thể giúp sử dụng sức mạnh tính toán hiệu quả hơn.

Trong phần này cần đề cập đến một loại dự án Internet khác, cụ thể hơn. Những dự án như vậy hoạt động với dữ liệu không có cấu trúc chính thức rõ ràng; trong những tình huống như vậy, việc sử dụng cơ sở dữ liệu quan hệ như một nơi lưu trữ dữ liệu, nói một cách nhẹ nhàng thì nó không thực tế. Trong những trường hợp này, họ thường sử dụng cơ sở dữ liệu ít nghiêm ngặt hơn, với chức năng xử lý dữ liệu thô sơ hơn, nhưng họ có thể xử lý lượng thông tin khổng lồ mà không phát hiện ra lỗi về chất lượng và việc tuân thủ định dạng. Một hệ thống tệp được phân cụm có thể làm cơ sở cho việc lưu trữ dữ liệu như vậy và trong trường hợp này, một cơ chế được gọi là được sử dụng để phân tích dữ liệu; Tôi sẽ chỉ cho bạn biết ngắn gọn về nguyên tắc hoạt động của nó, vì ở quy mô đầy đủ của nó, nó có phần vượt quá giới hạn. phạm vi của câu chuyện này.

Vì vậy, ở đầu vào, chúng tôi có một số dữ liệu tùy ý ở định dạng không nhất thiết phải được quan sát chính xác. Kết quả là bạn cần nhận được một số giá trị hoặc thông tin cuối cùng. Theo cơ chế này, hầu hết mọi phân tích dữ liệu đều có thể được thực hiện theo hai giai đoạn sau:

Bản đồ Mục tiêu chính sân khấu này là sự biểu diễn dữ liệu đầu vào tùy ý dưới dạng các cặp khóa-giá trị trung gian có ý nghĩa nhất định và được hình thức hóa. Các kết quả được sắp xếp và nhóm theo khóa, sau đó được chuyển sang giai đoạn tiếp theo. Giảm bớt Nhận được sau bản đồ các giá trị được sử dụng để tính toán cuối cùng các tổng số cần thiết.

Mỗi giai đoạn của mỗi phép tính cụ thể được thực hiện như một ứng dụng nhỏ độc lập. Cách tiếp cận này cho phép thực hiện song song hầu như không giới hạn các phép tính trên một con số khổng lồ máy, cho phép bạn xử lý khối lượng dữ liệu gần như tùy ý ngay lập tức. Để làm điều này, bạn chỉ cần chạy các ứng dụng này trên mỗi máy chủ có sẵnđồng thời, sau đó tập hợp tất cả các kết quả lại với nhau.

Ví dụ khung hoàn thiệnĐể triển khai xử lý dữ liệu theo nguyên tắc này, hãy sử dụng dự án mã nguồn mở của Quỹ Apache có tên mà tôi đã nói đến nhiều lần trước đây và thậm chí đã từng viết về nó.

Thay vì một kết luận

Thành thật mà nói, tôi cảm thấy khó tin rằng mình có thể viết một bài toàn diện như vậy và gần như không còn sức lực để tóm tắt lại. Tôi chỉ muốn nói rằng trong quá trình phát triển các dự án lớn, mọi chi tiết đều quan trọng và một chi tiết không được tính toán có thể gây ra thất bại. Đó là lý do tại sao trong vấn đề này, bạn không nên học hỏi từ những sai lầm của chính mình mà từ những người khác.

Mặc dù văn bản này có thể trông giống như một kiểu khái quát hóa tất cả các bài viết trong bộ bài, nhưng nó khó có thể trở thành điểm cuối cùng, tôi hy vọng tôi sẽ tìm thấy điều gì đó để nói về chủ đề này trong tương lai, có thể một ngày nào đó nó sẽ dựa trên kinh nghiệm cá nhân và sẽ không chỉ đơn giản là kết quả của việc xử lý khối lượng thông tin tôi nhận được. Ai biết?...

Vậy là bạn đã tạo xong một trang web. Thật thú vị và hấp dẫn khi xem cách bộ đếm lượt truy cập tăng lên chậm nhưng chắc chắn, cho thấy kết quả tốt hơn mỗi ngày. Nhưng một ngày nào đó, khi bạn không mong đợi, ai đó sẽ đăng một liên kết tới tài nguyên của bạn trên một số Reddit hoặc Hacker News (hoặc trên Habré - xấp xỉ làn đường) và máy chủ của bạn sẽ gặp sự cố.

Thay vì có được người dùng thường xuyên mới, bạn sẽ chỉ còn lại Trang trống. Tại thời điểm này, không có gì có thể giúp bạn khôi phục chức năng của máy chủ và lưu lượng truy cập sẽ bị mất vĩnh viễn. Làm thế nào để tránh những vấn đề như vậy? Trong bài viết này chúng ta sẽ nói về tối ưu hóa và mở rộng quy mô.

Một chút về tối ưu hóa

Mọi người đều biết những mẹo cơ bản: cập nhật lên phiên bản mới nhất PHP (5.5 hiện đã tích hợp OpCache), xử lý các chỉ mục trong cơ sở dữ liệu, bộ nhớ đệm tĩnh (các trang hiếm khi được thay đổi, chẳng hạn như “Giới thiệu về chúng tôi”, “Câu hỏi thường gặp”, v.v.).

Cũng đáng đề cập là một khía cạnh cụ thể của việc tối ưu hóa - cung cấp nội dung tĩnh với máy chủ không phải Apache, chẳng hạn như Nginx chẳng hạn. Định cấu hình Nginx để xử lý tất cả nội dung tĩnh (*.jpg, *.png, *.mp4, *.html. ..) và gửi các tệp yêu cầu máy chủ xử lý tới Apache nặng. Nó được gọi là proxy ngược.

Chia tỷ lệ

Có hai loại tỷ lệ - dọc và ngang.
Theo hiểu biết của tôi, một trang web có thể mở rộng nếu nó có thể xử lý lưu lượng truy cập mà không cần thay đổi phần mềm.

Chia tỷ lệ theo chiều dọc.

Hãy tưởng tượng một máy chủ phục vụ một ứng dụng web. Nó có RAM 4GB, bộ xử lý i5 và ổ cứng 1TB. Nó hoạt động tốt, nhưng để đối phó tốt hơn với lưu lượng truy cập cao hơn, bạn quyết định tăng RAM lên 16GB, cài đặt bộ xử lý i7 và bỏ ra Ổ SSD. Bây giờ máy chủ mạnh hơn nhiều và có thể chịu được tải cao. Đó là những gì nó là chia tỷ lệ dọc.

Chia tỷ lệ theo chiều ngang.

Chia tỷ lệ theo chiều ngang là việc tạo ra một cụm máy chủ được kết nối với nhau (thường không mạnh lắm) cùng phục vụ trang web. Trong trường hợp này, nó được sử dụng cân bằng tải(còn gọi là cân bằng tải) - một máy hoặc chương trình có chức năng chính là xác định máy chủ nào sẽ gửi yêu cầu đến. Các máy chủ trong một cụm chia sẻ ứng dụng phục vụ lẫn nhau mà không biết gì về nhau, do đó làm tăng đáng kể thông lượng và khả năng chịu lỗi của trang web của bạn.

Có hai loại bộ cân bằng - phần cứng và phần mềm. Phần mềm - được cài đặt trên một máy chủ thông thường và nhận tất cả lưu lượng truy cập, chuyển nó đến bộ xử lý thích hợp. Ví dụ, một bộ cân bằng như vậy có thể là Nginx. Trong phần “Tối ưu hóa”, nó chặn tất cả các yêu cầu đối với các tệp tĩnh và tự phục vụ các yêu cầu này mà không tạo gánh nặng cho Apache. Một phần mềm phổ biến khác để thực hiện cân bằng tải là Squid. Cá nhân tôi luôn sử dụng nó, bởi vì... nó cung cấp một giao diện tuyệt vời, thân thiện với người dùng để kiểm soát các khía cạnh sâu sắc nhất của việc cân bằng.

Bộ cân bằng phần cứng là một máy chuyên dụng có mục đích duy nhất là phân phối tải. Thông thường, chiếc máy này không còn chạy bất kỳ phần mềm nào khác ngoài phần mềm do nhà sản xuất phát triển. Bạn có thể đọc về cân bằng tải phần cứng.

Xin lưu ý rằng hai phương pháp này không loại trừ lẫn nhau. Bạn có thể chia tỷ lệ theo chiều dọc bất kỳ máy nào (còn gọi là Nodu) trên hệ thống của bạn.
Trong bài viết này, chúng tôi thảo luận về việc chia tỷ lệ theo chiều ngang vì... nó rẻ hơn và hiệu quả hơn, mặc dù khó thực hiện hơn.

Kết nối vĩnh viễn

Khi mở rộng quy mô ứng dụng PHP, một số vấn đề khó khăn sẽ phát sinh. Một trong số họ đang làm việc với dữ liệu phiên của người dùng. Rốt cuộc, nếu bạn đăng nhập vào trang web và bộ cân bằng đã gửi yêu cầu tiếp theo của bạn đến một máy khác thì xe hơi mới sẽ không biết rằng bạn đã đăng nhập. Trong trường hợp này, bạn có thể sử dụng kết nối liên tục. Điều này có nghĩa là bộ cân bằng ghi nhớ nút nào mà yêu cầu của người dùng đã được gửi đến lần trước và gửi yêu cầu tiếp theo tới đó. Tuy nhiên, hóa ra bộ cân bằng quá tải về các chức năng; ngoài việc xử lý hàng trăm nghìn yêu cầu, nó còn phải nhớ chính xác cách xử lý chúng, do đó bản thân bộ cân bằng trở thành một nút cổ chai trong hệ thống.

Trao đổi dữ liệu cục bộ

Chia sẻ dữ liệu phiên của người dùng giữa tất cả các nút trong cụm có vẻ là một ý tưởng hay. Và mặc dù cách tiếp cận này yêu cầu một số thay đổi trong kiến ​​trúc ứng dụng của bạn, nhưng nó đáng giá - bộ cân bằng tải sẽ không được tải và toàn bộ cụm trở nên có khả năng chịu lỗi cao hơn. Việc một trong các máy chủ ngừng hoạt động hoàn toàn không ảnh hưởng đến hoạt động của toàn bộ hệ thống.
Như chúng ta đã biết, dữ liệu phiên được lưu trữ trong một mảng siêu toàn cầu $_SESSION, ghi và lấy dữ liệu từ một tập tin trên đĩa. Nếu đĩa này nằm trên một máy chủ thì rõ ràng các máy chủ khác không thể truy cập được. Làm cách nào chúng tôi có thể cung cấp nó trên nhiều máy?
Đầu tiên, xin lưu ý rằng Trình xử lý phiên trong PHP có thể bị ghi đè. Bạn có thể triển khai lớp phiên của riêng mình.

Sử dụng cơ sở dữ liệu để lưu trữ phiên

sử dụng người xử lý riêng phiên, chúng ta có thể lưu trữ chúng trong cơ sở dữ liệu. Cơ sở dữ liệu có thể nằm trên một máy chủ riêng biệt (hoặc thậm chí là một cụm). Thông thường phương pháp này hoạt động rất tốt, nhưng khi thực sự lưu lượng truy cập cao, Cơ sở dữ liệu trở thành nút cổ chai(và nếu cơ sở dữ liệu bị mất, chúng tôi hoàn toàn mất chức năng), vì nó phải phục vụ tất cả các máy chủ, mỗi máy chủ đang cố gắng ghi hoặc đọc dữ liệu phiên.

Hệ thống tập tin phân tán

Bạn có thể nghĩ rằng việc thiết lập một mạng lưới là một ý tưởng hay hệ thống tập tin, nơi tất cả các máy chủ có thể ghi dữ liệu phiên. Đừng làm thế!Đây là cách tiếp cận rất chậm, dẫn đến hư hỏng hoặc thậm chí mất dữ liệu. Nếu vì lý do nào đó mà bạn vẫn quyết định sử dụng phương pháp này, tôi khuyên bạn nên sử dụng GlusterFS

Memcached

Bạn cũng có thể sử dụng memcached để lưu trữ dữ liệu phiên trong RAM. Tuy nhiên cách này không an toàn, vì dữ liệu trong memcached sẽ bị ghi đè nếu hết nơi miễn phí. Có lẽ bạn đang thắc mắc, RAM có được chia sẻ giữa các máy không? Nó được áp dụng như thế nào cho toàn bộ cụm? Memcached có khả năng kết hợp sẵn trên những chiếc xe khác nhau RAM trong một nhóm.

Bạn càng có nhiều máy thì bạn càng có thể phân bổ nhiều hơn cho nhóm bộ nhớ này. Bạn không cần phải gộp tất cả bộ nhớ của máy, nhưng bạn có thể, và bạn có thể tặng một lượng bộ nhớ tùy ý từ mỗi máy cho nhóm. Vì vậy, có một cơ hội để rời khỏi b hầu hết bộ nhớ dành cho sử dụng bình thường và phân bổ một phần cho bộ đệm, điều này sẽ cho phép bạn lưu trữ không chỉ các phiên mà còn các thông tin liên quan khác vào bộ đệm. Memcached là một giải pháp tuyệt vời và phổ biến.

Để sử dụng phương pháp này, bạn cần chỉnh sửa một chút php.ini

Session.save_handler = memcache session.save_path = "tcp://path.to.memcached.server:port"

Cụm Redis

Redis - Lưu trữ dữ liệu NoSQL. Lưu trữ cơ sở dữ liệu trong RAM. Không giống như memcached, nó hỗ trợ lưu trữ dữ liệu liên tục và các loại dữ liệu phức tạp hơn. Redis không hỗ trợ phân cụm, do đó việc sử dụng nó để chia tỷ lệ theo chiều ngang hơi khó khăn, tuy nhiên, đây chỉ là tạm thời và phiên bản alpha của giải pháp cụm đã được phát hành.

Các giải pháp khác

Tổng cộng

Như bạn có thể thấy, việc mở rộng quy mô theo chiều ngang của các ứng dụng PHP không hề dễ dàng. Có rất nhiều khó khăn, hầu hết các giải pháp đều không thể thay thế cho nhau, vì vậy bạn phải chọn một giải pháp và bám sát nó cho đến cuối cùng, vì khi lưu lượng truy cập vượt quá quy mô, không còn cơ hội để chuyển sang giải pháp khác một cách suôn sẻ.

Tôi hy vọng hướng dẫn nhỏ này sẽ giúp bạn chọn phương pháp mở rộng quy mô cho dự án của mình.

Trong phần thứ hai của bài viết chúng ta sẽ nói về nhân rộng cơ sở dữ liệu.

) Xin chào! Tôi là Alexander Makarov và bạn có thể biết tôi qua Yii framework - Tôi là một trong những nhà phát triển của nó. Tôi cũng có một công việc toàn thời gian - và đây không còn là một công ty khởi nghiệp nữa - Stay.com, chuyên về du lịch.

Hôm nay tôi sẽ nói về tỷ lệ theo chiều ngang, nhưng với những thuật ngữ rất chung chung.

Dù sao thì quy mô là gì? Đây là cơ hội để tăng năng suất dự án cho thời gian tối thiểu bằng cách thêm tài nguyên.

Thông thường, việc mở rộng quy mô không liên quan đến việc viết lại mã mà là thêm máy chủ hoặc tăng tài nguyên của mã hiện có. Loại này bao gồm tỷ lệ dọc và ngang.

Dọc là khi có thêm RAM, đĩa, v.v. trên một máy chủ đã tồn tại và theo chiều ngang là khi họ cài đặt nhiều máy chủ hơnđến các trung tâm dữ liệu và các máy chủ ở đó đã tương tác bằng cách nào đó.

Câu hỏi thú vị nhất mà họ hỏi là: tại sao lại cần nó nếu mọi thứ đều hoạt động tốt với tôi trên một máy chủ? Trên thực tế, chúng ta cần kiểm tra xem điều gì sẽ xảy ra. Tức là bây giờ nó hoạt động, nhưng điều gì sẽ xảy ra sau này? Có hai tiện ích tuyệt vời - ab và bao vây, dường như bắt kịp đám mây người dùng của đối thủ cạnh tranh, những người bắt đầu tấn công máy chủ, cố gắng yêu cầu các trang, gửi một số yêu cầu. Bạn phải cho họ biết phải làm gì và các tiện ích sẽ tạo ra các báo cáo như thế này:

Hai tham số chính: n - số lượng yêu cầu cần thực hiện, c - số lượng yêu cầu đồng thời. Bằng cách này họ kiểm tra sự cạnh tranh.

Ở đầu ra, chúng tôi nhận được RPS, tức là. số lượng yêu cầu mỗi giây mà máy chủ có khả năng xử lý, từ đó sẽ biết rõ nó có thể xử lý bao nhiêu người dùng. Tất nhiên, mọi thứ đều phụ thuộc vào dự án, nó khác nhau, nhưng thông thường điều này đòi hỏi sự chú ý.

Còn một tham số nữa - Thời gian phản hồi - thời gian phản hồi trung bình trong đó máy chủ phục vụ một trang. Nó khác nhau, nhưng người ta biết rằng khoảng 300 ms là tiêu chuẩn và bất cứ điều gì cao hơn đều không tốt lắm, bởi vì 300 ms này được máy chủ xử lý và 300-600 ms khác được thêm vào đây, được khách hàng xử lý. , I E. Trong khi mọi thứ đang tải - kiểu dáng, hình ảnh và phần còn lại - thời gian cũng trôi qua.

Trên thực tế, điều đó xảy ra là không cần phải lo lắng về việc mở rộng quy mô - chúng tôi truy cập máy chủ, cập nhật PHP, hiệu suất tăng 40% và mọi thứ đều ổn. Tiếp theo, chúng tôi định cấu hình Opcache và điều chỉnh nó. Nhân tiện, Opcache được điều chỉnh theo cách tương tự như APC, với một tập lệnh có thể tìm thấy trong kho lưu trữ của Rasmus Lerdorf và hiển thị các lần truy cập và bỏ lỡ, trong đó số lần truy cập là số lần PHP đi vào bộ đệm và số lần bỏ lỡ bao nhiêu lần nó vào hệ thống tập tin để lấy tập tin. Nếu chúng tôi chạy toàn bộ trang web hoặc chạy một số loại trình thu thập thông tin trên các liên kết hoặc tìm kiếm thủ công thì chúng tôi sẽ có số liệu thống kê về những lần truy cập và bỏ lỡ này. Nếu có 100% lượt truy cập và 0% lượt trượt thì mọi thứ đều ổn, nhưng nếu có lượt trượt thì bạn cần đánh dấu thêm bộ nhớđể tất cả mã của chúng tôi phù hợp với Opcache. Cái này lỗi phổ biến, điều mà họ thừa nhận - có vẻ như Opcache ở đó, nhưng có gì đó không ổn...

Họ cũng thường bắt đầu mở rộng quy mô nhưng không hề để ý đến nó, đó là lý do tại sao mọi thứ diễn ra chậm chạp. Thông thường, chúng ta vào cơ sở dữ liệu, nhìn - không có chỉ mục, đặt chỉ mục - mọi thứ hoạt động ngay lập tức, đủ cho 2 năm nữa, người đẹp!

À, bạn cũng cần kích hoạt cache, thay apache bằng nginx và php-fpm để tiết kiệm bộ nhớ. Mọi thứ sẽ tuyệt vời.

Tất cả những điều trên đều khá đơn giản và cho bạn thời gian. Đã đến lúc thực tế là một ngày nào đó điều này sẽ không đủ, và chúng ta phải chuẩn bị cho điều này ngay bây giờ.

Nói chung bạn hiểu vấn đề là gì? Hoặc là bạn đã có tải trọng cao và đây không nhất thiết phải là một số lượng yêu cầu điên rồ, v.v., đó là khi dự án của bạn không thể đáp ứng được tải và điều này không còn có thể được giải quyết theo những cách tầm thường nữa. Bạn cần phải phát triển rộng hơn hoặc cao hơn. Cần phải làm một điều gì đó và rất có thể là có rất ít thời gian cho việc đó;

Nguyên tắc đầu tiên là không bao giờ làm bất cứ điều gì một cách mù quáng, tức là. chúng ta cần sự giám sát tuyệt vời. Đầu tiên, chúng tôi dành thời gian cho một số tối ưu hóa rõ ràng như bật bộ nhớ đệm hoặc lưu vào bộ nhớ đệm Trang chủ, v.v. Sau đó, chúng tôi thiết lập giám sát, nó cho chúng tôi thấy những gì còn thiếu. Và tất cả điều này được lặp lại nhiều lần - bạn không bao giờ có thể ngừng theo dõi và cải tiến.

Việc giám sát có thể cho thấy điều gì? Chúng ta có thể dựa vào đĩa, tức là. đến hệ thống tập tin, bộ nhớ, bộ xử lý, mạng... Và có thể mọi thứ dường như ít nhiều đều ổn nhưng lại xuất hiện một số lỗi. Tất cả điều này được giải quyết theo những cách khác nhau. Bạn có thể giải quyết vấn đề với một ổ đĩa chẳng hạn bằng cách thêm một ổ đĩa mới vào cùng một máy chủ hoặc bạn có thể cài đặt một máy chủ thứ hai chỉ xử lý các tệp.

Lúc này bạn cần chú ý điều gì khi theo dõi? Cái này:

  1. khả năng tiếp cận, tức là máy chủ có hoạt động hay không;
  2. thiếu tài nguyên đĩa, bộ xử lý, v.v.;
  3. lỗi.
Làm thế nào để theo dõi tất cả điều này?

Dưới đây là danh sách các công cụ tuyệt vời cho phép bạn giám sát tài nguyên và hiển thị kết quả một cách rất thuận tiện:

Báo cáo này là bản sao của một trong những bài thuyết trình hay nhất tại hội nghị đào tạo dành cho các nhà phát triển hệ thống tải cao năm 2015.

Đồ cũ! - bạn nói.
- Giá trị vĩnh cửu! - chúng tôi sẽ trả lời. Thêm thẻ

Khả năng mở rộng là một tài sản như vậy hệ thống máy tính, đảm bảo tăng trưởng có thể dự đoán được đặc điểm hệ thống, ví dụ: số lượng người dùng được hỗ trợ, khả năng phản hồi, hiệu suất tổng thể, v.v., khi thêm tài nguyên máy tính vào đó. Trong trường hợp máy chủ DBMS, có thể xem xét hai phương pháp chia tỷ lệ - dọc và ngang (Hình 2).

Với việc chia tỷ lệ theo chiều ngang, số lượng máy chủ DBMS tăng lên, có thể tương tác với nhau ở chế độ trong suốt, do đó tách biệt tổng tải hệ thống. Giải pháp này có thể sẽ ngày càng trở nên phổ biến khi sự hỗ trợ cho các kiến ​​trúc liên kết lỏng lẻo ngày càng tăng và cơ sở dữ liệu phân tán dữ liệu, nhưng thường được đặc trưng bởi quản lý phức tạp.

Chia tỷ lệ theo chiều dọc liên quan đến việc tăng sức mạnh của một máy chủ DBMS riêng biệt và đạt được bằng cách thay thế phần cứng(bộ xử lý, đĩa) sang tốc độ nhanh hơn hoặc bằng cách thêm các nút bổ sung. Một ví dụ tốt Việc tăng số lượng bộ xử lý trong nền tảng đa bộ xử lý đối xứng (SMP) có thể đóng vai trò là động lực khuyến khích. Trong trường hợp này, không nên thay đổi phần mềm máy chủ (đặc biệt, bạn không thể yêu cầu mua mô-đun bổ sung), vì điều này sẽ làm tăng sự phức tạp trong quản trị và giảm khả năng dự đoán hành vi của hệ thống. Bất kể sử dụng phương pháp chia tỷ lệ nào, mức tăng được xác định bằng mức độ sử dụng đầy đủ các tài nguyên máy tính có sẵn của các chương trình máy chủ. Trong các đánh giá sâu hơn, chúng tôi sẽ xem xét mở rộng quy mô theo chiều dọc, theo các nhà phân tích, quy mô này đang có mức tăng trưởng lớn nhất trên thị trường máy tính hiện đại.

Thuộc tính khả năng mở rộng có liên quan vì hai lý do chính. Trước hết, các điều kiện kinh doanh hiện đại thay đổi nhanh đến mức họ phải lập kế hoạch dài hạn, đòi hỏi phải phân tích toàn diện và lâu dài những dữ liệu vốn đã lỗi thời, ngay cả đối với những tổ chức có đủ khả năng chi trả. Thay vào đó là chiến lược tăng cường sức mạnh dần dần, từng bước một. hệ thông thông tin. Mặt khác, những thay đổi về công nghệ dẫn đến sự xuất hiện ngày càng nhiều giải pháp mới và giá phần cứng thấp hơn, điều này có khả năng làm cho kiến ​​trúc của hệ thống thông tin trở nên linh hoạt hơn. Đồng thời, khả năng tương tác và tính mở của các sản phẩm phần mềm và phần cứng ngày càng mở rộng nhà sản xuất khác nhau, mặc dù cho đến nay nỗ lực tuân thủ của họ chỉ nhất quán trong các lĩnh vực thị trường hẹp. Nếu không tính đến những yếu tố này, người tiêu dùng sẽ không thể tận dụng các công nghệ mới nếu không đóng băng vốn đầu tư vào những công nghệ chưa đủ cởi mở hoặc đã được chứng minh là không có triển vọng. Trong lĩnh vực lưu trữ và xử lý dữ liệu, điều này đòi hỏi cả DBMS và máy chủ đều phải có khả năng mở rộng. Ngày nay, các thông số khả năng mở rộng chính là:

  • hỗ trợ đa xử lý;
  • tính linh hoạt của kiến ​​trúc.

Hệ thống đa bộ xử lý

Đối với việc chia tỷ lệ theo chiều dọc, các hệ thống đa xử lý đối xứng (SMP) đang ngày càng được sử dụng nhiều hơn, vì trong trường hợp này không cần phải thay đổi nền tảng, tức là. hệ điều hành, phần cứng và kỹ năng quản trị. Với mục đích này, cũng có thể sử dụng các hệ thống có tính song song lớn (MPP), nhưng cho đến nay việc sử dụng chúng chỉ giới hạn ở các nhiệm vụ đặc biệt, chẳng hạn như tính toán. Khi đánh giá một máy chủ DBMS có kiến ​​trúc song song, nên chú ý đến hai đặc điểm chính về khả năng mở rộng của kiến ​​trúc: tính đầy đủ và tính minh bạch.

Thuộc tính đầy đủ yêu cầu kiến ​​trúc máy chủ hỗ trợ như nhau cho một hoặc mười bộ xử lý mà không cần cài đặt lại hoặc thay đổi cấu hình đáng kể, cũng như các yêu cầu bổ sung khác. module phần mềm. Kiến trúc như vậy sẽ hữu ích và hiệu quả như nhau cả trong hệ thống bộ xử lý đơn và khi độ phức tạp của các tác vụ được giải quyết tăng lên trên một số hoặc thậm chí nhiều bộ xử lý (MPP). Nói chung, người tiêu dùng không phải mua hoặc tìm hiểu các tùy chọn phần mềm mới.

Ngược lại, việc cung cấp tính minh bạch cho kiến ​​trúc máy chủ giúp có thể ẩn các thay đổi cấu hình phần cứng khỏi các ứng dụng, tức là. đảm bảo tính di động của các ứng dụng hệ thống phần mềm. Đặc biệt, trong các kiến ​​trúc đa bộ xử lý được liên kết chặt chẽ, ứng dụng có thể giao tiếp với máy chủ thông qua một phân đoạn bộ nhớ dùng chung, trong khi ở các hệ thống (cụm) đa máy chủ được liên kết lỏng lẻo, cơ chế thông báo có thể được sử dụng cho mục đích này. Ứng dụng không nên tính đến khả năng triển khai của kiến ​​trúc phần cứng - các phương pháp thao tác dữ liệu và giao diện phần mềm để truy cập cơ sở dữ liệu phải giữ nguyên và hiệu quả như nhau.

Hỗ trợ chất lượng cao cho đa xử lý yêu cầu máy chủ cơ sở dữ liệu có thể lập lịch độc lập để thực hiện nhiều truy vấn sẽ được cung cấp, điều này sẽ đảm bảo phân chia đầy đủ nhất các tài nguyên máy tính có sẵn giữa các tác vụ của máy chủ. Các yêu cầu có thể được xử lý tuần tự bởi một số nhiệm vụ hoặc được chia thành các nhiệm vụ phụ, do đó, các nhiệm vụ này có thể được thực hiện song song (Hình 3). Cách thứ hai tối ưu hơn vì việc triển khai đúng cơ chế này mang lại những lợi ích độc lập với các loại yêu cầu và ứng dụng. Hiệu quả xử lý bị ảnh hưởng rất nhiều bởi mức độ chi tiết của các hoạt động được xem xét bởi tác vụ lập lịch trình. Ví dụ: với mức độ chi tiết thô, ở cấp độ truy vấn SQL riêng lẻ, việc phân chia tài nguyên hệ thống máy tính (bộ xử lý, bộ nhớ, đĩa) sẽ không tối ưu - tác vụ sẽ không hoạt động, chờ kết thúc các hoạt động I/O cần thiết để hoàn thành truy vấn SQL, ít nhất là trong hàng đợi. Có những truy vấn khác yêu cầu công việc tính toán đáng kể. Với mức độ chi tiết cao hơn, việc phân chia tài nguyên diễn ra ngay cả trong một truy vấn SQL, điều này thậm chí còn rõ ràng hơn khi tiến trình song song một số yêu cầu. Việc sử dụng bộ lập lịch đảm bảo rằng các tài nguyên hệ thống lớn được sử dụng để giải quyết các nhiệm vụ bảo trì cơ sở dữ liệu thực tế và giảm thiểu thời gian ngừng hoạt động.

Tính linh hoạt về kiến ​​trúc

Bất kể mức độ di động, hỗ trợ các tiêu chuẩn, tính song song và các đặc tính hữu ích khác, hiệu suất của DBMS, vốn có những hạn chế đáng kể về kiến ​​trúc tích hợp, không thể tăng lên một cách tự do. Sự hiện diện của các hạn chế bằng văn bản hoặc thực tế về số lượng và kích thước của các đối tượng cơ sở dữ liệu và bộ nhớ đệm, số lượng kết nối đồng thời, độ sâu của đệ quy trong việc gọi các thủ tục và truy vấn con hoặc kích hoạt trình kích hoạt cơ sở dữ liệu là cùng một hạn chế đối với khả năng ứng dụng của DBMS, chẳng hạn như không thể chuyển sang nhiều nền tảng điện toán. Các tham số giới hạn độ phức tạp của các truy vấn cơ sở dữ liệu, đặc biệt là kích thước của bộ đệm động và kích thước ngăn xếp cho các lệnh gọi đệ quy, phải được cấu hình động và không yêu cầu phải dừng hệ thống để cấu hình lại. Sẽ chẳng ích gì khi mua một máy chủ mới mạnh mẽ nếu không thể đáp ứng được kỳ vọng do những hạn chế bên trong của DBMS.

Thông thường, nút thắt cổ chai là không có khả năng điều chỉnh linh hoạt các đặc tính của chương trình máy chủ cơ sở dữ liệu. Khả năng xác định các tham số nhanh chóng như lượng bộ nhớ tiêu thụ, số lượng bộ xử lý bận, số lượng luồng công việc song song (cho dù là luồng thực, quy trình hệ điều hành hay bộ xử lý ảo) và số lượng phân đoạn của bảng cơ sở dữ liệu và chỉ mục, cũng như sự phân phối của chúng đĩa vật lý KHÔNG dừng và khởi động lại hệ thống là một yêu cầu nảy sinh từ bản chất của các ứng dụng hiện đại. Lý tưởng nhất là mỗi tham số này có thể được thay đổi linh hoạt trong giới hạn cụ thể của người dùng.

Khi mức độ phổ biến của một ứng dụng web ngày càng tăng, việc hỗ trợ nó chắc chắn bắt đầu đòi hỏi ngày càng nhiều tài nguyên. Lúc đầu, tải có thể (và chắc chắn là nên) được xử lý bằng cách tối ưu hóa các thuật toán và/hoặc kiến ​​trúc của chính ứng dụng. Tuy nhiên, phải làm gì nếu mọi thứ có thể tối ưu hóa đã được tối ưu hóa nhưng ứng dụng vẫn không thể đáp ứng được tải?

Tối ưu hóa

Điều đầu tiên bạn nên làm là ngồi xuống và suy nghĩ xem liệu bạn đã tối ưu hóa được mọi thứ chưa:
  • Các truy vấn cơ sở dữ liệu có tối ưu không (phân tích GIẢI THÍCH, sử dụng chỉ mục)?
  • dữ liệu có được lưu trữ chính xác (SQL vs NoSQL) không?
  • bộ nhớ đệm có được sử dụng không?
  • Có bất kỳ truy vấn không cần thiết nào tới hệ thống tập tin hoặc cơ sở dữ liệu không?
  • Các thuật toán xử lý dữ liệu có tối ưu không?
  • Cài đặt môi trường có tối ưu không: Apache/Nginx, MySQL/PostgreSQL, PHP/Python?
Một bài viết riêng có thể được viết về từng điểm này, vì vậy việc xem xét chi tiết chúng trong khuôn khổ bài viết này rõ ràng là dư thừa. Điều quan trọng là phải hiểu rằng trước khi bạn bắt đầu mở rộng quy mô một ứng dụng, bạn nên tối ưu hóa hoạt động của ứng dụng đó càng nhiều càng tốt - sau cùng, có lẽ khi đó bạn sẽ không cần phải mở rộng quy mô.

Chia tỷ lệ

Và vì vậy, giả sử rằng việc tối ưu hóa đã được thực hiện nhưng ứng dụng vẫn không thể đáp ứng được tải. Trong trường hợp này, giải pháp cho vấn đề rõ ràng có thể là phân phối nó trên một số máy chủ để tăng hiệu suất tổng thể của ứng dụng bằng cách tăng các tài nguyên sẵn có. Cách tiếp cận này có tên chính thức – “mở rộng quy mô” ứng dụng. Chính xác hơn, “khả năng mở rộng” đề cập đến khả năng hệ thống tăng hiệu suất khi số lượng tài nguyên được phân bổ cho nó tăng lên. Có hai phương pháp chia tỷ lệ: dọc và ngang. Chia tỷ lệ theo chiều dọc ngụ ý tăng hiệu suất ứng dụng khi thêm tài nguyên (bộ xử lý, bộ nhớ, đĩa) trong một nút (máy chủ). Chia tỷ lệ theo chiều ngang là điển hình cho các ứng dụng phân tán và ngụ ý tăng hiệu suất ứng dụng khi thêm một nút (máy chủ) khác.

Rõ ràng là hầu hết một cách đơn giản sẽ có một bản nâng cấp đơn giản về phần cứng (bộ xử lý, bộ nhớ, đĩa) - tức là chia tỷ lệ theo chiều dọc. Ngoài ra, phương pháp này không yêu cầu bất kỳ sửa đổi nào đối với ứng dụng. Tuy nhiên, việc chia tỷ lệ theo chiều dọc rất nhanh chóng đạt đến giới hạn, sau đó nhà phát triển và quản trị viên không còn lựa chọn nào khác ngoài việc chuyển sang chia tỷ lệ theo chiều ngang của ứng dụng.

Kiến trúc ứng dụng

Hầu hết các ứng dụng web đều được phân phối tiên nghiệm, vì có thể phân biệt ít nhất ba lớp trong kiến ​​trúc của chúng: máy chủ web, logic nghiệp vụ (ứng dụng), dữ liệu (cơ sở dữ liệu, tĩnh).

Mỗi lớp này có thể được thu nhỏ. Do đó, nếu trong hệ thống của bạn, ứng dụng và cơ sở dữ liệu nằm trên cùng một máy chủ, tất nhiên, bước đầu tiên là phân phối chúng trên các máy chủ khác nhau.

Nút cổ chai

Khi bắt đầu mở rộng quy mô hệ thống, bước đầu tiên là xác định lớp nào là “nút cổ chai” - tức là nó hoạt động chậm hơn phần còn lại của hệ thống. Để bắt đầu, bạn có thể sử dụng các tiện ích tầm thường như top (htop) để ước tính mức tiêu thụ bộ xử lý/bộ nhớ và df, iostat để ước tính mức tiêu thụ đĩa. Tuy nhiên, nên phân bổ một máy chủ riêng có tính năng mô phỏng tải chiến đấu (sử dụng hoặc JMeter), trên đó có thể lập hồ sơ hoạt động của ứng dụng bằng các tiện ích như xdebug, v.v. Để xác định các truy vấn hẹp đối với cơ sở dữ liệu, bạn có thể sử dụng các tiện ích như pgFouine (rõ ràng là tốt hơn nên thực hiện việc này dựa trên nhật ký từ máy chủ sản xuất).

Nó thường phụ thuộc vào kiến ​​trúc của ứng dụng, nhưng những ứng cử viên có nhiều khả năng gây ra nút cổ chai nói chung là cơ sở dữ liệu và mã. Nếu ứng dụng của bạn hoạt động với một lượng lớn dữ liệu người dùng thì nút thắt cổ chai rất có thể sẽ là bộ nhớ tĩnh.

Chia tỷ lệ cơ sở dữ liệu

Như đã đề cập ở trên, thường có điểm nghẽn trong ứng dụng hiện đại là một cơ sở dữ liệu. Các vấn đề với nó thường được chia thành hai loại: yêu cầu về hiệu suất và lưu trữ số lượng lớn dữ liệu.

Bạn có thể giảm tải cho cơ sở dữ liệu bằng cách trải rộng nó trên nhiều máy chủ. Đồng thời, vấn đề đồng bộ hóa giữa chúng trở nên gay gắt, có thể được giải quyết bằng cách triển khai sơ đồ chủ/phụ với bản sao đồng bộ hoặc không đồng bộ. Trong trường hợp PostgreSQL, bạn có thể triển khai sao chép đồng bộ bằng Slony-I, sao chép không đồng bộ bằng PGPool-II hoặc WAL (9.0). Vấn đề tách biệt các yêu cầu đọc và ghi, cũng như cân bằng tải giữa các Slave hiện có, có thể được giải quyết bằng cách thiết lập một lớp truy cập cơ sở dữ liệu đặc biệt (PgPool-II).

Vấn đề lưu trữ lượng lớn dữ liệu khi sử dụng DBMS quan hệ có thể được giải quyết bằng cơ chế phân vùng (“phân vùng” trong PostgreSQL) hoặc bằng cách triển khai cơ sở dữ liệu trên các hệ thống tệp phân tán như Hadoop DFS.

Tuy nhiên, để lưu trữ một lượng lớn dữ liệu giải pháp tốt nhất Sẽ có tính năng "phân mảnh" dữ liệu, đây là một lợi ích tích hợp của hầu hết các cơ sở dữ liệu NoSQL (ví dụ: MongoDB).

Ngoài ra, cơ sở dữ liệu NoSQL thường hoạt động nhanh hơn so với người anh em SQL của chúng do không cần chi phí phân tích/tối ưu hóa truy vấn, kiểm tra tính toàn vẹn của cấu trúc dữ liệu, v.v. Chủ đề so sánh cơ sở dữ liệu quan hệ và cơ sở dữ liệu NoSQL cũng khá rộng rãi và xứng đáng có một bài viết riêng.

Riêng biệt đáng chú ý trải nghiệm Facebook, được MySQL sử dụng mà không cần chọn THAM GIA. Chiến lược này cho phép họ mở rộng quy mô cơ sở dữ liệu dễ dàng hơn nhiều, đồng thời chuyển tải từ cơ sở dữ liệu sang mã, như sẽ được mô tả bên dưới, quy mô dễ dàng hơn cơ sở dữ liệu.

Chia tỷ lệ mã

Khó khăn trong việc mở rộng quy mô mã phụ thuộc vào số lượng tài nguyên được chia sẻ mà máy chủ cần để chạy ứng dụng của bạn. Nó sẽ chỉ là phiên hay sẽ yêu cầu bộ nhớ đệm và tệp dùng chung? Trong mọi trường hợp, bước đầu tiên là chạy các bản sao của ứng dụng trên một số máy chủ có cùng môi trường.

Tiếp theo, bạn cần định cấu hình cân bằng tải/yêu cầu giữa các máy chủ này. Điều này có thể được thực hiện như sau: cấp độ TCP(haproxy) và trên HTTP (nginx) hoặc DNS.

Bước tiếp theo là đảm bảo rằng các tệp tĩnh, bộ đệm và phiên ứng dụng web có sẵn trên mỗi máy chủ. Đối với các phiên, bạn có thể sử dụng máy chủ chạy qua mạng (ví dụ: memcached). Sẽ khá hợp lý khi sử dụng cùng một memcached làm máy chủ bộ đệm, nhưng tất nhiên là trên một máy chủ khác.

Các tập tin tĩnh có thể được gắn kết từ một số thông dụng lưu trữ tập tin thông qua NFS/CIFS hoặc sử dụng hệ thống tệp phân tán (HDFS, GlusterFS, Ceph).

Bạn cũng có thể lưu trữ các tệp trong cơ sở dữ liệu (ví dụ: Mongo GridFS), từ đó giải quyết các vấn đề về tính khả dụng và khả năng mở rộng (có tính đến thực tế là đối với cơ sở dữ liệu NoSQL, vấn đề về khả năng mở rộng được giải quyết nhờ phân mảnh).

Riêng biệt, cần lưu ý vấn đề triển khai trên nhiều máy chủ. Làm cách nào để người dùng không nhìn thấy khi nhấp vào “Cập nhật” phiên bản khác nhau các ứng dụng? Theo tôi, giải pháp đơn giản nhất là loại trừ các máy chủ không được cập nhật khỏi cấu hình cân bằng tải (máy chủ web) và bật chúng một cách tuần tự khi chúng được cập nhật. Bạn cũng có thể liên kết người dùng với các máy chủ cụ thể bằng cookie hoặc IP. Nếu bản cập nhật yêu cầu những thay đổi đáng kể trong cơ sở dữ liệu, cách dễ nhất là tạm thời đóng dự án hoàn toàn.

Chia tỷ lệ FS

Nếu cần lưu trữ một lượng lớn dữ liệu tĩnh, có thể xác định được hai vấn đề: thiếu dung lượng và tốc độ truy cập dữ liệu. Như đã viết ở trên, vấn đề thiếu dung lượng có thể được giải quyết theo ít nhất ba cách: hệ thống tệp phân tán, lưu trữ dữ liệu trong cơ sở dữ liệu có hỗ trợ phân đoạn và tổ chức phân đoạn “thủ công” ở cấp mã.

Đồng thời, cần hiểu rằng việc phân phối số liệu thống kê cũng không phải là tốt nhất nhiệm vụ đơn giản, khi nó đến tải cao. Vì vậy, việc có nhiều máy chủ chuyên phân phối các tệp tĩnh là khá hợp lý. Hơn nữa, nếu chúng ta có kho lưu trữ dữ liệu dùng chung (hệ thống tệp phân tán hoặc cơ sở dữ liệu), khi lưu tệp, chúng ta có thể lưu tên của nó mà không cần tính đến máy chủ và thay thế tên máy chủ. ngẫu nhiên khi tạo một trang (tôi cân bằng tải ngẫu nhiên giữa các máy chủ web phân phối tĩnh). Trong trường hợp shending được triển khai thủ công (nghĩa là logic trong mã chịu trách nhiệm chọn máy chủ mà dữ liệu sẽ được tải lên), thông tin về máy chủ tải lên phải được tính toán dựa trên chính tệp đó hoặc được tạo dựa trên trên dữ liệu thứ ba (thông tin về người dùng, dung lượng trên đĩa lưu trữ) và được lưu cùng với tên tệp trong cơ sở dữ liệu.

Giám sát

Rõ ràng là nó lớn và một hệ thống phức tạpđòi hỏi phải theo dõi liên tục. Theo tôi, giải pháp ở đây là tiêu chuẩn - zabbix, giám sát quá trình tải/hoạt động của các nút hệ thống và giám sát các daemon để sao lưu.

Phần kết luận

Phần trên thảo luận ngắn gọn về nhiều tùy chọn để giải quyết các vấn đề về mở rộng quy mô ứng dụng web. Mỗi người trong số họ đều có những ưu điểm và nhược điểm riêng. Không có công thức nào để làm tốt mọi việc cùng một lúc - đối với mỗi nhiệm vụ có nhiều giải pháp với những ưu và nhược điểm riêng. Chọn cái nào là tùy thuộc vào bạn.