Chiến thuật sử dụng PHP trong một trang web tải cao


242

Trước khi bạn trả lời điều này, tôi chưa bao giờ phát triển bất cứ thứ gì đủ phổ biến để đạt được tải máy chủ cao. Hãy coi tôi như (thở dài) một người ngoài hành tinh vừa hạ cánh trên hành tinh, mặc dù là người biết PHP và một vài kỹ thuật tối ưu hóa.


Tôi đang phát triển một công cụ trong PHP có thể thu hút được khá nhiều người dùng, nếu nó hoạt động tốt. Tuy nhiên, trong khi tôi hoàn toàn có khả năng phát triển chương trình, tôi không biết nhiều về việc tạo ra thứ gì đó có thể giải quyết được lưu lượng lớn. Vì vậy, đây là một vài câu hỏi về nó (hãy thoải mái biến câu hỏi này thành một luồng tài nguyên).

Cơ sở dữ liệu

Hiện tại tôi có kế hoạch sử dụng các tính năng của MySQLi trong PHP5. Tuy nhiên, làm thế nào tôi nên thiết lập cơ sở dữ liệu liên quan đến người dùng và nội dung? Tôi có thực sự cần nhiều cơ sở dữ liệu? Hiện tại, mọi thứ bị xáo trộn vào một cơ sở dữ liệu - mặc dù tôi đã xem xét việc truyền dữ liệu người dùng sang một, nội dung thực tế sang nội dung khác và cuối cùng là nội dung trang web chính (chủ bản mẫu, v.v.) sang cơ sở dữ liệu khác. Lý do của tôi đằng sau điều này là việc gửi các truy vấn đến các cơ sở dữ liệu khác nhau sẽ giảm tải cho chúng dưới dạng một cơ sở dữ liệu = 3 nguồn tải. Ngoài ra điều này sẽ vẫn hiệu quả nếu tất cả chúng đều trên cùng một máy chủ?

Bộ nhớ đệm

Tôi có một hệ thống mẫu được sử dụng để xây dựng các trang và trao đổi các biến. Các mẫu chính được lưu trữ trong cơ sở dữ liệu và mỗi khi một mẫu được gọi là bản sao lưu trong bộ nhớ cache (tài liệu html) được gọi. Hiện tại tôi có hai loại biến trong các mẫu này - một var tĩnh và một var động. Vars tĩnh thường là những thứ như tên trang, tên của trang web - những thứ không thay đổi thường xuyên; vars động là những thứ thay đổi trên mỗi tải trang.

Câu hỏi của tôi về điều này:

Nói rằng tôi có ý kiến ​​về các bài viết khác nhau. Giải pháp nào tốt hơn: lưu trữ mẫu nhận xét đơn giản và hiển thị nhận xét (từ cuộc gọi DB) mỗi khi trang được tải hoặc lưu một bản sao được lưu trong bộ nhớ cache của trang nhận xét dưới dạng trang html - mỗi lần nhận xét được thêm / chỉnh sửa / xóa trang được thu lại.

Cuối cùng

Có ai có bất kỳ mẹo / con trỏ nào để chạy một trang web tải cao trên PHP không. Tôi khá chắc chắn rằng đó là một ngôn ngữ hoàn toàn khả thi để sử dụng - Facebook và Yahoo! ưu tiên lớn - nhưng có bất kỳ kinh nghiệm nào tôi nên đề phòng không?


9
3,5 năm sau và tôi thậm chí không thể nhớ những gì mình đang làm, tôi muốn biết những gì tôi nghĩ cũng rất tuyệt :)
Ross

8
Hãy để đây là một bài học cho bạn về tối ưu hóa sớm :)
Rimu Atkinson

Câu trả lời:


89

Không có hai trang web giống nhau. Bạn thực sự cần phải có một công cụ như jmeter và điểm chuẩn để xem điểm vấn đề của bạn sẽ ở đâu. Bạn có thể dành nhiều thời gian để đoán và cải thiện, nhưng bạn sẽ không thấy kết quả thực sự cho đến khi bạn đo lường và so sánh các thay đổi của mình.

Ví dụ, trong nhiều năm, bộ đệm truy vấn MySQL là giải pháp cho tất cả các vấn đề về hiệu suất của chúng tôi. Nếu trang web của bạn chậm, các chuyên gia MySQL khuyên bạn nên bật bộ đệm truy vấn. Nó chỉ ra rằng nếu bạn có tải ghi cao, bộ đệm thực sự bị tê liệt. Nếu bạn bật nó lên mà không kiểm tra, bạn sẽ không bao giờ biết.

Và đừng quên rằng bạn không bao giờ được mở rộng quy mô. Một trang web xử lý 10req / s sẽ cần thay đổi để hỗ trợ 1000req / s. Và nếu bạn đủ may mắn để hỗ trợ 10.000req / s, kiến ​​trúc của bạn có thể sẽ trông hoàn toàn khác.

Cơ sở dữ liệu

  • Không sử dụng MySQLi - PDO là lớp truy cập cơ sở dữ liệu OO 'hiện đại'. Tính năng quan trọng nhất để sử dụng là giữ chỗ trong các truy vấn của bạn. Nó đủ thông minh để sử dụng các chuẩn bị phía máy chủ và các tối ưu hóa khác cho bạn.
  • Bạn có thể không muốn phá vỡ cơ sở dữ liệu của bạn tại thời điểm này. Nếu bạn thấy rằng một cơ sở dữ liệu không bị cắt, có một số kỹ thuật để mở rộng, tùy thuộc vào ứng dụng của bạn. Sao chép sang các máy chủ bổ sung thường hoạt động tốt nếu bạn có nhiều lần đọc hơn ghi. Shending là một kỹ thuật để phân chia dữ liệu của bạn trên nhiều máy.

Bộ nhớ đệm

  • Bạn có thể không muốn lưu trữ trong cơ sở dữ liệu của bạn. Cơ sở dữ liệu thường là nút cổ chai của bạn, vì vậy việc thêm nhiều IO vào nó thường là một điều tồi tệ. Có một số bộ đệm PHP ngoài kia thực hiện những điều tương tự như APC và Zend.
  • Đo hệ thống của bạn với bộ nhớ đệm bật và tắt. Tôi cá rằng bộ nhớ cache của bạn nặng hơn việc phục vụ các trang thẳng.
  • Nếu mất nhiều thời gian để xây dựng nhận xét và dữ liệu bài viết của bạn từ db, hãy tích hợp memcache vào hệ thống của bạn. Bạn có thể lưu trữ các kết quả truy vấn và lưu trữ chúng trong một ví dụ memcached. Điều quan trọng cần nhớ là việc truy xuất dữ liệu từ memcache phải nhanh hơn việc lắp ráp nó từ cơ sở dữ liệu để thấy bất kỳ lợi ích nào.
  • Nếu bài viết của bạn không động hoặc bạn có các thay đổi động đơn giản sau khi được tạo, hãy xem xét việc viết ra html hoặc php vào đĩa. Bạn có thể có một trang index.php trông trên đĩa cho bài viết, nếu nó ở đó, nó sẽ truyền nó đến máy khách. Nếu không, nó sẽ tạo ra bài viết, ghi nó vào đĩa và gửi nó đến máy khách. Xóa các tệp khỏi đĩa sẽ khiến các trang được viết lại. Nếu một bình luận được thêm vào một bài viết, hãy xóa bản sao được lưu trong bộ nhớ cache - nó sẽ được tạo lại.

10
@ ghi vào đĩa. Bạn thậm chí có thể bỏ index.php và để Apache thực hiện công việc cho bạn, để index.php chỉ được gọi, nếu đường dẫn không tồn tại. Bạn sẽ sử dụng mode_rewrite cho việc này.
troelskn

5
-1, PDO chậm hơn đáng kể so với MySQLi hoặc thậm chí là phần mở rộng MySQL.
Alix Axel

4
PDO chậm hơn nhiều so với mysqli và không hoạt động đúng với các truy vấn lồng nhau đối với tôi. Mysqli cũng hỗ trợ chuẩn bị phía máy chủ và các tham số ràng buộc giống như PDO.
Daren Schwenke

5
Tôi không thể tin rằng điều này đã được chấp nhận như một câu trả lời. Không được tốt lắm.
symcbean

1
về: bộ nhớ đệm - hình ảnh, css, htm và js sẽ giúp, tắt cookie trên hình ảnh quá!
Talvi Watia

61

Tôi là nhà phát triển chính trên một trang web có hơn 15 triệu người dùng. Chúng tôi đã có rất ít vấn đề mở rộng quy mô vì chúng tôi đã lên kế hoạch cho nó SỚM và thu nhỏ một cách chu đáo. Dưới đây là một số chiến lược tôi có thể đề xuất từ ​​kinh nghiệm của mình.

SCHEMA Trước hết, denormalize schemas của bạn. Điều này có nghĩa là thay vì có nhiều bảng quan hệ, thay vào đó bạn nên chọn để có một bảng lớn. Nói chung, các phép nối là một sự lãng phí tài nguyên DB quý giá vì thực hiện nhiều lần chuẩn bị và đối chiếu đốt cháy I / O của đĩa. Tránh chúng khi bạn có thể.

Sự đánh đổi ở đây là bạn sẽ lưu trữ / lấy dữ liệu dư thừa, nhưng điều này có thể chấp nhận được vì dữ liệu và băng thông trong lồng rất rẻ (đĩa lớn hơn) trong khi nhiều I / O chuẩn bị là những đơn hàng đắt hơn (nhiều máy chủ hơn) .

INDEXING Đảm bảo rằng các truy vấn của bạn sử dụng ít nhất một chỉ mục. Hãy coi chừng, các chỉ mục đó sẽ khiến bạn phải trả giá nếu bạn viết hoặc cập nhật thường xuyên. Có một số thủ thuật thử nghiệm để tránh điều này.

Bạn có thể thử thêm các cột bổ sung không được lập chỉ mục chạy song song với các cột được lập chỉ mục. Sau đó, bạn có thể có một quy trình ngoại tuyến ghi các cột không được lập chỉ mục trên các cột được lập chỉ mục theo lô. Bằng cách này, bạn có thể kiểm soát tốt hơn khi myQuery sẽ cần tính toán lại chỉ mục.

Tránh các truy vấn được tính toán như một bệnh dịch. Nếu bạn phải tính toán một truy vấn, hãy thử làm điều này một lần tại thời điểm viết.

CACHING Tôi rất khuyên bạn nên Memcached. Nó đã được chứng minh bởi những người chơi lớn nhất trên ngăn xếp PHP (Facebook) và rất linh hoạt. Có hai phương thức để thực hiện việc này, một là lưu vào bộ đệm trong lớp DB của bạn, hai là lưu vào bộ đệm trong lớp logic nghiệp vụ của bạn.

Tùy chọn lớp DB sẽ yêu cầu lưu trữ kết quả của các truy vấn được truy xuất từ ​​DB. Bạn có thể băm truy vấn SQL của mình bằng md5 () và sử dụng nó làm khóa tra cứu trước khi đến cơ sở dữ liệu. Mặt trái của điều này là nó khá dễ thực hiện. Nhược điểm (tùy thuộc vào việc triển khai) là bạn mất tính linh hoạt vì bạn đang xử lý tất cả các bộ đệm giống nhau liên quan đến hết hạn bộ đệm.

Trong cửa hàng tôi làm việc, chúng tôi sử dụng bộ đệm ẩn lớp nghiệp vụ, có nghĩa là mỗi lớp cụ thể trong hệ thống của chúng tôi kiểm soát lược đồ bộ đệm của riêng nó và thời gian chờ bộ đệm. Điều này đã làm việc khá tốt đối với chúng tôi, nhưng lưu ý rằng các mục được truy xuất từ ​​DB có thể không giống với các mục từ bộ đệm, vì vậy bạn sẽ phải cập nhật bộ đệm và DB cùng nhau.

Sao chép dữ liệu sao chép chỉ đưa bạn đến nay. Sớm hơn bạn mong đợi, bài viết của bạn sẽ trở thành nút cổ chai. Để bù lại, hãy đảm bảo hỗ trợ sắp xếp dữ liệu sớm nhất có thể. Bạn có thể muốn tự bắn mình sau này nếu không.

Nó là khá đơn giản để thực hiện. Về cơ bản, bạn muốn tách cơ quan chủ chốt khỏi bộ lưu trữ dữ liệu. Sử dụng DB toàn cầu để lưu trữ ánh xạ giữa các khóa chính và id cụm. Bạn truy vấn ánh xạ này để có được một cụm, và sau đó truy vấn cụm để lấy dữ liệu. Bạn có thể lưu trữ bộ nhớ cache của hoạt động tra cứu này sẽ làm cho nó hoạt động không đáng kể.

Nhược điểm của điều này là có thể khó ghép các dữ liệu từ nhiều phân đoạn. Nhưng, bạn có thể thiết kế theo cách của bạn xung quanh đó là tốt.

QUY TRÌNH OFFLINE Đừng bắt người dùng chờ đợi phần phụ trợ của bạn nếu họ không phải làm vậy. Xây dựng hàng đợi công việc và di chuyển mọi xử lý mà bạn có thể ngoại tuyến, thực hiện tách biệt với yêu cầu của người dùng.


9
+1 Nương tay, đây sẽ là câu trả lời được chấp nhận. Thật thú vị khi tất cả mọi thứ tôi từng đọc về việc xây dựng cơ sở dữ liệu luôn nói rằng "bình thường hóa tất cả dữ liệu càng nhiều càng tốt" mà không đề cập đến hiệu suất của việc tham gia. Tôi luôn cảm thấy bằng trực giác rằng việc tham gia (đặc biệt là nhiều người) đã thêm rất nhiều chi phí nhưng chưa nghe thấy ai nói điều đó rõ ràng cho đến bây giờ. Tôi ước tôi hiểu rõ hơn những gì bạn đang nói về việc kiểm soát khi MySQL tính toán các chỉ mục, nghe có vẻ như là một vụ hack rất thú vị.
Evan Plaice

Shending dữ liệu là điều cần thiết cho cơ sở dữ liệu phát triển quá lớn. Google (công ty không phải là công cụ tìm kiếm) có rất nhiều điều thú vị để nói về việc thực hiện các kế hoạch shending. Xử lý ngoại tuyến cũng rất lớn khi giới hạn số lần ghi cơ sở dữ liệu (và giới hạn số lần tính lại chỉ số bảng). Tôi đã thấy rất nhiều blog (và tôi nghĩ thậm chí Stack Overflow) sử dụng kỹ thuật này cho các hệ thống nhận xét / phản hồi do người dùng tạo ra.
Evan Plaice

1
Cảm ơn bạn đã cho ý kiến. Thật đáng ngạc nhiên khi một số người tranh luận về việc cấu hình mã tầng giữa khi lượng thời gian thực hiện VAST được sử dụng trong cả I / O dữ liệu hoặc I / O của máy chủ-máy chủ. Việc tối ưu hóa phức tạp giúp tiết kiệm 20% thời gian thực hiện của quy trình PHP mất 40ms là vô nghĩa so với tiết kiệm 5% đơn giản cho truy vấn cơ sở dữ liệu 1 giây.
thesmart

42

Tôi đã làm việc trên một vài trang web nhận được hàng triệu lượt truy cập / tháng được hỗ trợ bởi PHP & MySQL. Dưới đây là một số điều cơ bản:

  1. Cache, cache, cache. Bộ nhớ đệm là một trong những cách đơn giản và hiệu quả nhất để giảm tải cho máy chủ web và cơ sở dữ liệu của bạn. Nội dung trang bộ nhớ cache, truy vấn, tính toán đắt tiền, bất cứ điều gì bị ràng buộc I / O. Memcache đã chết đơn giản và hiệu quả.
  2. Sử dụng nhiều máy chủ khi bạn đã đạt được tối đa. Bạn có thể có nhiều máy chủ web và nhiều máy chủ cơ sở dữ liệu (có bản sao).
  3. Giảm tổng số yêu cầu đối với máy chủ web của bạn. Điều này đòi hỏi phải lưu bộ nhớ cache, CSS và hình ảnh bằng cách sử dụng các tiêu đề hết hạn. Bạn cũng có thể di chuyển nội dung tĩnh của mình sang CDN, điều này sẽ tăng tốc trải nghiệm của người dùng.
  4. Đo lường & điểm chuẩn. Chạy Nagios trên các máy sản xuất của bạn và tải thử nghiệm trên máy chủ dev / qa của bạn. Bạn cần biết khi nào máy chủ của bạn sẽ bốc cháy để bạn có thể ngăn chặn nó.

Tôi khuyên bạn nên đọc các trang web có thể mở rộng xây dựng , nó được viết bởi một trong những kỹ sư của Flickr và là một tài liệu tham khảo tuyệt vời.

Kiểm tra bài đăng trên blog của tôi về khả năng mở rộng, nó có rất nhiều liên kết đến các bài thuyết trình về nhân rộng với nhiều ngôn ngữ và nền tảng: http://www.ryandoherty.net/2008/07/13/unicorns-and-scalability/


1
+1 Có rất nhiều thông tin tốt ở đây. Gần đây tôi đã nghiên cứu thêm về chủ đề này và câu trả lời của bạn phù hợp với mọi thứ tôi đã đọc. Memcache, bộ nhớ đệm, CDN cho nội dung tĩnh, giảm yêu cầu; tất cả những thứ tốt. Tôi cũng sẽ thêm, tạo băm trên các tệp nội dung tĩnh (nếu phía sau máy chủ CDN / bộ đệm) của bạn để các tệp được cập nhật có chữ ký duy nhất trong bộ đệm. Ngoài ra, kết hợp các tệp nguồn tĩnh (css, javascript) một cách nhanh chóng (và lưu trữ chúng với băm tên tệp) để cắt giảm các yêu cầu. Ngoài ra, tạo ngón tay cái một cách linh hoạt (và lưu trữ chúng trong bộ nhớ cache)
Evan Plaice

Google đã tạo ra một mô-đun apache có tên mod_pagespeed có thể xử lý tất cả các cách ghép tệp, thu nhỏ, đổi tên tệp để bao gồm hàm băm, v.v. cho tất cả nội dung tĩnh. Ban đầu, bạn chỉ nên thêm một chút chi phí xử lý cho các máy chủ cho đến khi bộ đệm (và CDN) được phổ biến với hầu hết nội dung. Ngoài ra, để bảo mật, nói chung, nên đặt các bảng có thể truy cập công khai (người dùng) vào cùng một cơ sở dữ liệu với các bảng hơn là xử lý back-end (nếu vì lý do nào đó, một trong các bảng sẽ bị hack).
Evan Plaice

39

Re: PDO / MySQLi / MySQLND

@ gary

Bạn không thể chỉ nói "không sử dụng MySQLi" vì chúng có các mục tiêu khác nhau. PDO gần giống như một lớp trừu tượng (mặc dù nó không thực sự) và được thiết kế để giúp dễ dàng sử dụng nhiều sản phẩm cơ sở dữ liệu trong khi MySQLi dành riêng cho các kết hợp MySQL. Thật sai lầm khi nói rằng PDO là lớp truy cập hiện đại trong bối cảnh so sánh nó với MySQLi bởi vì tuyên bố của bạn ngụ ý rằng sự tiến triển đã được mysql -> mysqli -> PDO không phải là trường hợp.

Sự lựa chọn giữa MySQLi và PDO rất đơn giản - nếu bạn cần hỗ trợ nhiều sản phẩm cơ sở dữ liệu thì bạn sử dụng PDO. Nếu bạn chỉ đang sử dụng MySQL thì bạn có thể chọn giữa PDO và MySQLi.

Vậy tại sao bạn lại chọn MySQLi hơn PDO? Xem bên dưới...

@ross

Bạn đã đúng về MySQLnd, thư viện cấp độ ngôn ngữ cốt lõi mới nhất của MySQL, tuy nhiên nó không phải là sự thay thế cho MySQLi. MySQLi (như với PDO) vẫn là cách bạn sẽ tương tác với MySQL thông qua mã PHP của bạn. Cả hai đều sử dụng libmysql làm máy khách C đằng sau mã PHP. Vấn đề là libmysql nằm ngoài công cụ PHP cốt lõi và đó là nơi mysqlnd xuất hiện, tức là Trình điều khiển gốc sử dụng các phần tử PHP cốt lõi để tối đa hóa hiệu quả, đặc biệt là việc sử dụng bộ nhớ.

MySQLnd đang được phát triển bởi chính MySQL và gần đây đã cập bến nhánh PHP 5.3 đang thử nghiệm RC, sẵn sàng để phát hành vào cuối năm nay. Sau đó, bạn sẽ có thể sử dụng MySQLnd với MySQLi ... nhưng không phải với PDO. Điều này sẽ giúp MySQLi tăng hiệu suất trong nhiều lĩnh vực (không phải tất cả) và sẽ làm cho nó trở thành lựa chọn tốt nhất cho tương tác MySQL nếu bạn không cần sự trừu tượng như các khả năng của PDO.

Điều đó nói rằng, MySQLnd hiện có sẵn trong PHP 5.3 cho PDO và do đó bạn có thể nhận được những lợi thế của các cải tiến hiệu suất từ ​​ND thành PDO, tuy nhiên, PDO vẫn là một lớp cơ sở dữ liệu chung và do đó sẽ không thể hưởng lợi nhiều từ những cải tiến trong ND như MySQLi có thể .

Một số điểm chuẩn hữu ích có thể được tìm thấy ở đây mặc dù chúng có từ năm 2006. Bạn cũng cần lưu ý về những thứ như tùy chọn này .

Có rất nhiều cân nhắc cần phải tính đến khi quyết định giữa MySQLi và PDO. Thực tế sẽ không có vấn đề gì cho đến khi bạn nhận được số lượng yêu cầu cao một cách rõ ràng và trong trường hợp đó, sẽ hợp lý hơn khi sử dụng một tiện ích mở rộng được thiết kế riêng cho MySQL thay vì trừu tượng hóa mọi thứ và tình cờ cung cấp trình điều khiển MySQL .

Nó không phải là một vấn đề đơn giản là tốt nhất bởi vì mỗi cái đều có ưu điểm và nhược điểm. Bạn cần đọc các liên kết tôi đã cung cấp và đưa ra quyết định của riêng bạn, sau đó kiểm tra và tìm hiểu. Tôi đã sử dụng PDO trong các dự án trước đây và nó là một phần mở rộng tốt nhưng lựa chọn của tôi cho hiệu năng thuần túy sẽ là MySQLi với tùy chọn MySQLND mới được biên dịch (khi PHP 5.3 được phát hành).


6
Tôi đã chuyển từ PDO sang mysqli và các truy vấn thông thường bắt đầu thực hiện nhanh hơn chính xác 2 lần.
serg

5
@serg: quan tâm để đăng một số bài kiểm tra để xác nhận điều này?, bởi vì tôi thực sự nghi ngờ rằng chỉ cần chuyển từ PDO sang mysqli sẽ giúp bạn tăng tốc độ như vậy.
Stann

23

Chung

  • Đừng cố gắng tối ưu hóa trước khi bạn bắt đầu thấy tải thế giới thực. Bạn có thể đoán đúng, nhưng nếu bạn không, bạn đã lãng phí thời gian của mình.
  • Sử dụng jmeter , xdebug hoặc công cụ khác để đánh giá trang web.
  • Nếu tải bắt đầu là một vấn đề, có thể liên quan đến bộ nhớ đệm dữ liệu hoặc đối tượng, do đó, thường đọc các tùy chọn bộ đệm (memcached, tùy chọn bộ đệm của MySQL)

  • Hồ sơ mã của bạn để bạn biết nút cổ chai ở đâu và liệu đó là mã hay cơ sở dữ liệu

Cơ sở dữ liệu

  • Sử dụng MYSQLi nếu tính di động đối với các cơ sở dữ liệu khác không quan trọng, nếu không thì PDO
  • Nếu điểm chuẩn tiết lộ cơ sở dữ liệu là vấn đề, hãy kiểm tra các truy vấn trước khi bạn bắt đầu lưu vào bộ đệm. Sử dụng GIẢI THÍCH để xem các truy vấn của bạn đang chậm lại.
  • Sau khi các truy vấn được tối ưu hóa và cơ sở dữ liệu được lưu trữ theo cách nào đó, bạn có thể muốn sử dụng nhiều cơ sở dữ liệu. Có thể sao chép vào nhiều máy chủ hoặc shending (chia dữ liệu trên nhiều cơ sở dữ liệu / máy chủ) có thể phù hợp, tùy thuộc vào dữ liệu, truy vấn và loại hành vi đọc / ghi.

Bộ nhớ đệm

  • Rất nhiều văn bản đã được thực hiện trên bộ đệm, đối tượng và dữ liệu. Tra cứu các bài viết về APC , Trình tối ưu hóa Zend , memcached , QuickCache , JPCache . Thực hiện một số điều này trước khi bạn thực sự cần, và bạn sẽ ít quan tâm hơn về việc bắt đầu không được tối ưu hóa.
  • APC và Trình tối ưu hóa Zend là bộ đệm opcode, chúng tăng tốc mã PHP bằng cách tránh việc biên dịch lại và biên dịch lại mã. Nói chung đơn giản để cài đặt, đáng làm sớm.
  • Memcached là một bộ đệm chung, mà bạn có thể sử dụng để truy vấn bộ đệm, các hàm hoặc đối tượng PHP hoặc toàn bộ trang. Mã phải được viết riêng để sử dụng nó, có thể là một quá trình liên quan nếu không có điểm trung tâm để xử lý việc tạo, cập nhật và xóa các đối tượng được lưu trữ.
  • QuickCache và JPCache là bộ đệm tệp, nếu không thì tương tự như Memcached. Khái niệm cơ bản là đơn giản, nhưng cũng yêu cầu mã và dễ dàng hơn với các điểm trung tâm của việc tạo, cập nhật và xóa.

Điều khoản khác

  • Xem xét các máy chủ web thay thế cho tải cao. Các máy chủ như lighthttpnginx có thể xử lý lưu lượng lớn trong bộ nhớ ít hơn nhiều so với Apache , nếu bạn có thể hy sinh sức mạnh và tính linh hoạt của Apache (hoặc nếu bạn không cần những thứ đó, thường thì bạn không cần).
  • Hãy nhớ rằng phần cứng ngày nay rẻ đến mức đáng ngạc nhiên, vì vậy hãy chắc chắn bỏ ra công sức để tối ưu hóa một khối mã lớn so với "hãy mua một máy chủ quái vật".
  • Xem xét thêm các thẻ "MySQL" và "chia tỷ lệ" cho câu hỏi này

9

APC là phải tuyệt đối. Nó không chỉ làm cho một hệ thống bộ nhớ đệm tuyệt vời, mà thu được từ các tệp PHP được lưu trữ tự động là một ưu đãi. Đối với ý tưởng nhiều cơ sở dữ liệu, tôi không nghĩ bạn sẽ nhận được nhiều từ việc có các cơ sở dữ liệu khác nhau trên cùng một máy chủ. Nó có thể giúp bạn tăng một chút tốc độ trong thời gian truy vấn, nhưng tôi nghi ngờ nỗ lực cần có để triển khai và duy trì mã cho cả ba trong khi đảm bảo rằng chúng đồng bộ hóa sẽ có giá trị.

Tôi cũng khuyên bạn nên chạy Xdebug để tìm các tắc nghẽn trong chương trình của bạn. Nó làm cho tối ưu hóa một làn gió cho tôi.


9

Thứ nhất, như tôi nghĩ Knuth đã nói, "Tối ưu hóa sớm là gốc rễ của mọi tội lỗi". Nếu bạn không phải đối phó với những vấn đề này ngay bây giờ thì đừng, hãy tập trung vào việc cung cấp một cái gì đó hoạt động chính xác trước. Điều đó đang được nói, nếu tối ưu hóa không thể chờ đợi.

Hãy thử cấu hình các truy vấn cơ sở dữ liệu của bạn, tìm ra những gì chậm và những gì xảy ra rất nhiều và đưa ra một chiến lược tối ưu hóa từ đó.

Tôi sẽ điều tra Memcached vì đây là thứ mà nhiều trang web tải cao hơn sử dụng để lưu trữ hiệu quả nội dung của tất cả các loại và giao diện đối tượng PHP với nó khá đẹp.

Chia tách cơ sở dữ liệu giữa các máy chủ và sử dụng một số loại kỹ thuật cân bằng tải (ví dụ: tạo một số ngẫu nhiên giữa 1 và # cơ sở dữ liệu dự phòng với dữ liệu cần thiết - và sử dụng số đó để xác định máy chủ cơ sở dữ liệu nào sẽ kết nối) cũng có thể là một cách tuyệt vời để tăng hiệu quả.

Những điều này đã làm việc khá tốt trong quá khứ cho một số trang web tải khá cao. Hy vọng điều này sẽ giúp bạn bắt đầu :-)


1
RequestFullQuote: "Chúng ta nên quên đi những hiệu quả nhỏ, nói khoảng 97% thời gian: tối ưu hóa sớm là gốc rễ của mọi tội lỗi"
Alister Bulman

RequestReallyFullQuote: "Các lập trình viên lãng phí rất nhiều thời gian để suy nghĩ hoặc lo lắng về tốc độ của các phần không văn bản trong chương trình của họ và những nỗ lực này có hiệu quả thực sự có tác động tiêu cực mạnh khi gỡ lỗi và bảo trì. Chúng ta nên quên đi những hiệu quả nhỏ, nói khoảng 97% thời gian: tối ưu hóa sớm là gốc rễ của mọi tội lỗi. Tuy nhiên, chúng ta không nên bỏ qua cơ hội của mình trong 3% quan trọng đó. "
cHao

6

Cấu hình ứng dụng của bạn với một cái gì đó như Xdebug (như khuyến nghị tj9991) chắc chắn sẽ là điều bắt buộc. Sẽ không có ý nghĩa gì nhiều khi chỉ đi xung quanh tối ưu hóa mọi thứ một cách mù quáng. Xdebug sẽ giúp bạn tìm ra các nút thắt thực sự trong mã của bạn để bạn có thể sử dụng thời gian tối ưu hóa của mình một cách khôn ngoan và khắc phục các đoạn mã thực sự gây chậm.

Nếu bạn đang sử dụng Apache, một tiện ích khác có thể giúp kiểm tra là Siege . Nó sẽ giúp bạn dự đoán cách máy chủ và ứng dụng của bạn sẽ phản ứng với tải cao bằng cách thực sự đưa nó qua các bước đi của nó.

Bất kỳ loại bộ đệm opcode nào cho PHP (như APC hoặc một trong nhiều bộ đệm khác) cũng sẽ giúp ích rất nhiều.


6

Tôi điều hành một trang web với 7-8 triệu lượt xem trang mỗi tháng. Không quá nhiều, nhưng đủ để máy chủ của chúng tôi cảm thấy tải. Giải pháp chúng tôi chọn rất đơn giản: Memcache ở cấp cơ sở dữ liệu. Giải pháp này hoạt động tốt nếu tải cơ sở dữ liệu là vấn đề chính của bạn.

Chúng tôi bắt đầu sử dụng Memcache để lưu trữ toàn bộ các đối tượng và kết quả cơ sở dữ liệu được sử dụng thường xuyên nhất. Nó đã làm việc, nhưng nó cũng giới thiệu các lỗi (chúng tôi có thể đã tránh được một số lỗi nếu chúng tôi cẩn thận hơn).

Vì vậy, chúng tôi đã thay đổi cách tiếp cận của chúng tôi. Chúng tôi đã xây dựng một trình bao bọc cơ sở dữ liệu (với các phương thức chính xác giống như cơ sở dữ liệu cũ của chúng tôi, để dễ dàng chuyển đổi), và sau đó chúng tôi đã phân lớp nó để cung cấp các phương thức truy cập cơ sở dữ liệu memcached.

Bây giờ tất cả những gì bạn phải làm là quyết định xem một truy vấn có thể sử dụng kết quả được lưu trong bộ nhớ cache (và có thể đã lỗi thời) hay không. Hầu hết các truy vấn được chạy bởi người dùng hiện được lấy trực tiếp từ Memcache. Các ngoại lệ là cập nhật và chèn, mà đối với trang web chính chỉ xảy ra do đăng nhập. Biện pháp khá đơn giản này đã giảm tải máy chủ của chúng tôi khoảng 80%.


6

Đối với những gì đáng giá, bộ nhớ đệm là DIRT SIMPLE trong PHP ngay cả khi không có gói mở rộng / trình trợ giúp như memcached.

Tất cả bạn cần làm là tạo một bộ đệm đầu ra bằng cách sử dụng ob_start().

Tạo một chức năng bộ đệm toàn cầu. Gọi ob_start, chuyển chức năng như một cuộc gọi lại. Trong chức năng, tìm kiếm một phiên bản lưu trữ của trang. Nếu tồn tại, phục vụ nó và kết thúc.

Nếu nó không tồn tại, tập lệnh sẽ tiếp tục xử lý. Khi nó đạt đến ob_end () phù hợp, nó sẽ gọi hàm bạn đã chỉ định. Tại thời điểm đó, bạn chỉ cần lấy nội dung của bộ đệm đầu ra, thả chúng vào một tệp, lưu tệp và kết thúc.

Thêm vào một số bộ sưu tập hết hạn / rác.

Và nhiều người không nhận ra bạn có thể lồng ob_start()/ ob_end()gọi. Vì vậy, nếu bạn đã sử dụng bộ đệm đầu ra để phân tích các quảng cáo hoặc làm nổi bật cú pháp hoặc bất cứ điều gì, bạn chỉ có thể lồng một ob_start/ob_endcuộc gọi khác .


+1 vì có vẻ như đó là một ý tưởng thú vị. Tôi không biết nó hoạt động hiệu quả như thế nào
Sylverdrag

+1 vì đây là một ý tưởng thú vị. Những cuộc gọi lại có thể gọi lớp bộ nhớ đệm của tôi cho tôi!
Xeoncross

5

Cảm ơn lời khuyên về các phần mở rộng bộ nhớ đệm của PHP - bạn có thể giải thích lý do sử dụng cái này không? Tôi đã nghe những điều tuyệt vời về memcached thông qua IRC nhưng chưa bao giờ nghe về APC - ý kiến ​​của bạn về chúng là gì? Tôi giả sử sử dụng nhiều hệ thống bộ nhớ đệm là khá hiệu quả.

Trên thực tế, nhiều người sử dụng APC và memcached cùng nhau ...


4

Có vẻ như tôi đã sai . MySQLi vẫn đang được phát triển. Nhưng theo bài báo, PDO_MySQL hiện đang được đóng góp bởi nhóm MySQL. Từ bài viết:

Phần mở rộng được cải tiến của MySQL - mysqli - là hàng đầu. Nó hỗ trợ tất cả các tính năng của Máy chủ MySQL bao gồm Bộ ký tự, Báo cáo đã chuẩn bị và Thủ tục lưu trữ. Trình điều khiển cung cấp API lai: bạn có thể sử dụng kiểu lập trình hướng đối tượng hoặc hướng đối tượng dựa trên sở thích của bạn. mysqli đi kèm với PHP 5 trở lên. Lưu ý rằng Kết thúc cuộc đời cho PHP 4 là 2008-08-08.

Các đối tượng dữ liệu PHP (PDO) là một lớp trừu tượng truy cập cơ sở dữ liệu. PDO cho phép bạn sử dụng cùng các lệnh gọi API cho các cơ sở dữ liệu khác nhau. PDO không cung cấp bất kỳ mức độ trừu tượng SQL nào. PDO_MYSQL là trình điều khiển MySQL cho PDO. PDO_MYSQL đi kèm với PHP 5. Kể từ PHP 5.3 Các nhà phát triển MySQL tích cực đóng góp cho nó. Lợi ích PDO của API hợp nhất có giá mà các tính năng cụ thể của MySQL, ví dụ như nhiều câu lệnh, không được hỗ trợ đầy đủ thông qua API hợp nhất.

Hãy ngừng sử dụng trình điều khiển MySQL đầu tiên cho PHP từng được xuất bản: ext / mysql. Kể từ khi giới thiệu phần mở rộng cải tiến MySQL - mysqli - vào năm 2004 với PHP 5, không có lý do gì để vẫn sử dụng trình điều khiển lâu đời nhất xung quanh. ext / mysql không hỗ trợ Bộ ký tự, Báo cáo đã chuẩn bị và Thủ tục lưu trữ. Nó được giới hạn trong bộ tính năng của MySQL 4.0. Lưu ý rằng Hỗ trợ mở rộng cho MySQL 4.0 kết thúc vào 2008-12-31. Đừng giới hạn bản thân trong bộ tính năng của phần mềm cũ như vậy! Nâng cấp lên mysqli, xem thêm Converting_to_MySQLi. mysql chỉ ở chế độ bảo trì theo quan điểm của chúng tôi.

Đối với tôi, có vẻ như bài viết thiên về MySQLi. Tôi cho rằng tôi thiên vị về PDO. Tôi thực sự thích PDO hơn MySQLi. Nó thẳng tiến về phía tôi. API gần với các ngôn ngữ khác mà tôi đã lập trình. Các giao diện cơ sở dữ liệu OO dường như hoạt động tốt hơn.

Tôi chưa bắt gặp bất kỳ tính năng MySQL cụ thể nào không có sẵn thông qua PDO. Tôi sẽ ngạc nhiên nếu tôi đã từng làm.


3

PDO cũng rất chậm và API của nó khá phức tạp. Không ai trong tâm trí lành mạnh của họ nên sử dụng nó nếu tính di động không phải là một mối quan tâm. Và hãy đối mặt với nó, trong 99% tất cả các ứng dụng web thì không. Bạn chỉ cần gắn bó với MySQL hoặc PostrgreSQL hoặc bất cứ thứ gì bạn đang làm việc với.

Đối với câu hỏi PHP và những gì cần tính đến. Tôi nghĩ tối ưu hóa sớm là gốc rễ của mọi tội lỗi. ;) Làm cho ứng dụng của bạn được thực hiện trước, cố gắng giữ sạch sẽ khi lập trình, làm một ít tài liệu và viết các bài kiểm tra đơn vị. Với tất cả những điều trên, bạn sẽ không gặp vấn đề gì khi tái cấu trúc mã khi đến lúc. Nhưng trước tiên bạn muốn được thực hiện và đẩy nó ra để xem mọi người phản ứng với nó như thế nào.


2

Chắc chắn PDO là tốt đẹp, nhưng có đã được một số tranh cãi về nó của hiệu suất so với mysql và mysqli, mặc dù nó dường như cố định ngay bây giờ.

Bạn nên sử dụng pdo nếu bạn hình dung tính di động, nhưng nếu không, mysqli sẽ là cách. Nó có giao diện OO, các câu lệnh được chuẩn bị và hầu hết những gì pdo cung cấp (ngoại trừ, tính di động).

Ngoài ra, nếu hiệu suất thực sự cần thiết, hãy chuẩn bị trình điều khiển MysqLnd (mys mys ) gốc trong PHP 5.3, người sẽ tích hợp chặt chẽ hơn với php, với hiệu suất tốt hơn và sử dụng bộ nhớ được cải thiện (và thống kê để điều chỉnh hiệu suất).

Memcache rất tuyệt nếu bạn có các máy chủ phân cụm (và tải giống như YouTube), nhưng trước tiên tôi cũng sẽ thử APC .


2

Rất nhiều câu trả lời hay đã được đưa ra, nhưng tôi muốn chỉ cho bạn một bộ đệm opcode thay thế có tên là XCache . Nó được tạo ra bởi một người đóng góp nhẹ nhàng.

Ngoài ra, nếu bạn có thể cần tải cân bằng máy chủ cơ sở dữ liệu của mình trong tương lai, MySQL Proxy rất có thể giúp bạn đạt được điều này.

Cả hai công cụ này nên cắm vào một ứng dụng hiện có khá dễ dàng, vì vậy việc tối ưu hóa này có thể được thực hiện khi bạn cần, mà không gặp quá nhiều rắc rối.


2

Câu hỏi đầu tiên là bạn thực sự mong đợi nó lớn đến mức nào? Và bạn dự định đầu tư bao nhiêu vào cơ sở hạ tầng của mình. Vì bạn cảm thấy cần phải đặt câu hỏi ở đây, tôi đoán rằng bạn sẽ bắt đầu nhỏ với ngân sách hạn chế.

Hiệu suất là không liên quan nếu trang web không có sẵn. Và để sẵn sàng, bạn cần mở rộng theo chiều ngang. Tối thiểu bạn có thể thoát khỏi một cách hợp lý là 2 máy chủ, cả chạy apache, php và mysql. Thiết lập một DBMS làm nô lệ cho cái kia. Thực hiện tất cả các ghi trên bản gốc và tất cả các lần đọc trên cơ sở dữ liệu cục bộ (bất kể đó là gì) - trừ khi vì lý do nào đó bạn cần đọc lại dữ liệu bạn vừa đọc (sử dụng chính). Hãy chắc chắn rằng bạn đã có máy móc tại chỗ để tự động quảng bá nô lệ và rào chắn cho chủ. Sử dụng DNS vòng tròn cho các địa chỉ máy chủ web để cung cấp thêm mối quan hệ cho nút nô lệ.

Phân vùng dữ liệu của bạn trên các nút cơ sở dữ liệu khác nhau trong giai đoạn này là một ý tưởng rất tồi - tuy nhiên bạn có thể muốn xem xét phân chia dữ liệu trên các cơ sở dữ liệu khác nhau trên cùng một máy chủ (điều này sẽ tạo điều kiện phân vùng giữa các nút khi bạn vượt qua facebook).

Hãy chắc chắn rằng bạn đã có các công cụ giám sát và phân tích dữ liệu để đo hiệu suất trang web của bạn và xác định các tắc nghẽn. Hầu hết các vấn đề về hiệu năng có thể được khắc phục bằng cách viết SQL tốt hơn / sửa lược đồ cơ sở dữ liệu.

Giữ bộ đệm mẫu của bạn trên cơ sở dữ liệu là một ý tưởng ngu ngốc - cơ sở dữ liệu nên là một kho lưu trữ chung cho dữ liệu có cấu trúc. Giữ bộ đệm mẫu của bạn trên hệ thống tệp cục bộ của máy chủ web - nó sẽ khả dụng nhanh hơn và sẽ không làm chậm truy cập cơ sở dữ liệu của bạn.

Sử dụng bộ đệm op-code.

Dành nhiều thời gian nghiên cứu trang web của bạn và nhật ký của nó để hiểu tại sao nó lại chậm như vậy.

Đẩy càng nhiều bộ nhớ đệm càng tốt lên máy khách.

Sử dụng mod_gzip để nén mọi thứ bạn có thể.

C.


2

Lời khuyên đầu tiên của tôi là suy nghĩ về vấn đề này và ghi nhớ nó khi thiết kế trang web nhưng đừng quá nhiệt tình . Thường rất khó để dự đoán sự thành công của một trang web mới và tôi sẽ dành thời gian tốt hơn để hoàn thành sớm và tối ưu hóa nó sau này.

Nói chung, Đơn giản là nhanh chóng . Mẫu làm bạn chậm lại. Cơ sở dữ liệu làm bạn chậm lại. Thư viện phức tạp làm bạn chậm lại. Các lớp xếp chồng lên nhau lấy ra từ cơ sở dữ liệu và phân tích cú pháp trong một thư viện phức tạp -> độ trễ thời gian nhân với nhau.

Khi bạn có trang web cơ bản và chạy, hãy thực hiện các bài kiểm tra để cho bạn biết nơi dành nỗ lực của mình. Thật khó để xem mục tiêu ở đâu. Thông thường để tăng tốc mọi thứ, bạn sẽ phải làm sáng tỏ sự phức tạp của mã, điều này làm cho nó lớn hơn và khó bảo trì hơn, vì vậy bạn chỉ muốn làm điều đó khi cần thiết.

Theo kinh nghiệm của tôi, việc thiết lập kết nối cơ sở dữ liệu là tương đối tốn kém. Nếu bạn có thể thoát khỏi nó, đừng kết nối với cơ sở dữ liệu dành cho khách truy cập chung trên các trang có lưu lượng truy cập nhiều nhất như trang đầu vào trang web. Tạo nhiều kết nối cơ sở dữ liệu là điên rồ với rất ít lợi ích.


1

@ Gary

Không sử dụng MySQLi - PDO là lớp truy cập cơ sở dữ liệu OO 'hiện đại'. Tính năng quan trọng nhất để sử dụng là giữ chỗ trong các truy vấn của bạn. Nó đủ thông minh để sử dụng các chuẩn bị phía máy chủ và các tối ưu hóa khác cho bạn.

Hiện tại tôi đang nói về PDO và có vẻ như bạn đúng - tuy nhiên tôi biết rằng MySQL đang phát triển phần mở rộng MySQLd cho PHP - Tôi nghĩ để thành công cả MySQL hay MySQLi - bạn nghĩ gì về điều đó?


@ Ryan , Eric , tj9991

Cảm ơn lời khuyên về các phần mở rộng bộ nhớ đệm của PHP - bạn có thể giải thích lý do sử dụng cái này không? Tôi đã nghe những điều tuyệt vời về memcached thông qua IRC nhưng chưa bao giờ nghe về APC - ý kiến ​​của bạn về chúng là gì? Tôi giả sử sử dụng nhiều hệ thống bộ nhớ đệm là khá hiệu quả.

Tôi chắc chắn sẽ phân loại một số người kiểm tra hồ sơ - cảm ơn bạn rất nhiều vì những đề xuất của bạn về những người đó.


1

Tôi không thấy mình chuyển đổi từ MySQL bất cứ lúc nào sớm - vì vậy tôi đoán tôi không cần khả năng trừu tượng hóa của PDO. Cảm ơn những bài viết đó DavidM, họ đã giúp tôi rất nhiều.


1

Nhìn vào mod_cache , bộ đệm đầu ra cho máy chủ web Apache, tương tự với bộ đệm ẩn đầu ra trong ASP.NET.

Vâng, tôi có thể thấy rằng nó vẫn còn thử nghiệm nhưng nó sẽ là cuối cùng vào một ngày nào đó.


1

Tôi không thể tin rằng không ai đã đề cập đến điều này: Modularisation và Trừu tượng. Nếu bạn nghĩ rằng trang web của bạn sẽ phải phát triển thành nhiều máy móc, bạn phải thiết kế nó để nó có thể! Điều đó có nghĩa là những điều ngu ngốc như không cho rằng cơ sở dữ liệu là trên localhost. Điều đó cũng có nghĩa là những thứ sẽ gây phiền toái lúc đầu, như viết một lớp trừu tượng hóa cơ sở dữ liệu (như PDO, nhưng nhẹ hơn nhiều vì nó chỉ làm những gì bạn cần nó làm).

Và nó có nghĩa là những thứ như làm việc với một khuôn khổ. Bạn sẽ cần các lớp cho mã của mình để sau này bạn có thể đạt được hiệu suất bằng cách cấu trúc lại lớp trừu tượng dữ liệu, bằng cách dạy nó rằng một số đối tượng nằm trong một cơ sở dữ liệu khác - và mã không cần phải biết hoặc quan tâm .

Cuối cùng, hãy cẩn thận với các hoạt động cần nhiều bộ nhớ, ví dụ, sao chép chuỗi không cần thiết. Nếu bạn có thể giảm mức sử dụng bộ nhớ của PHP, thì bạn sẽ nhận được nhiều hiệu suất hơn từ máy chủ web của mình và đây là thứ sẽ mở rộng khi bạn đi đến một giải pháp cân bằng tải.


1

Nếu bạn đang làm việc với một lượng lớn dữ liệu và bộ nhớ đệm không bị cắt, hãy xem Sphinx. Chúng tôi đã có kết quả tuyệt vời khi sử dụng SphinxSearch không chỉ để tìm kiếm văn bản tốt hơn mà còn là sự thay thế truy xuất dữ liệu cho MySQL khi xử lý các bảng lớn hơn. Nếu bạn sử dụng SphinxSE (plugin MySQL), nó đã vượt qua mức tăng hiệu suất của chúng tôi, chúng tôi đã có từ bộ nhớ cache nhiều lần và việc triển khai ứng dụng là một điều chắc chắn.


1

Các điểm được thực hiện về bộ nhớ cache là tại chỗ; nó là phần ít phức tạp nhất và quan trọng nhất trong việc xây dựng một ứng dụng hiệu quả. Tôi muốn nói thêm rằng trong khi memcached rất tuyệt, APC sẽ nhanh hơn khoảng năm lần nếu ứng dụng của bạn sống trên một máy chủ.

Bài đăng "So sánh hiệu suất bộ đệm" tại blog hiệu suất MySQL có một số điểm chuẩn thú vị về chủ đề này - http://www.mysqlperformanceblog.com/2006/08/09/cache-performance-comparison/ .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.