Tôi nên sử dụng API tạm thời để lưu trữ Chuỗi HTML hoặc Đối tượng?


18

Giả sử rằng có một plugin hiển thị 20 bài đăng liên quan (cho mỗi bài đăng) với một truy vấn rất phức tạp. Và sau đó sử dụng dữ liệu từ truy vấn này, nó xây dựng bố cục HTML phức tạp. Ngoài ra, cần lưu ý rằng plugin là công khai và có thể được cài đặt trên bất kỳ máy chủ nào với bất kỳ cấu hình nào.

Cái gì đó như:

/* complex and large query */
$related_posts = get_posts( ... );

$html_output = '';
foreach($related_posts as $key => $item) {
     /* complex layout rendering logic (but not as slow as the previous query) */   
     $html_output .= ...;
}

Vì vậy, câu hỏi của tôi là:

  • Cách an toàn nhất và đúng đắn nhất để lưu trữ dữ liệu đó là gì?
  • Tôi nên sử dụng API tạm thời để lưu trữ $related_postsmảng hoặc $html_outputchuỗi? Nếu tôi lưu trữ $html_ouputchuỗi, nó có đạt giới hạn kích thước tối đa không? Tôi có nên gzip nó, trước khi lưu?
  • Tôi có nên sử dụng API tạm thời ở đây không?

Câu trả lời:


18

Tôi có nên sử dụng API tạm thời ở đây không?

Không.

Trong kho, các bản cài đặt WordPress được lưu trữ trong bảng wp_options và chỉ được dọn sạch trong quá trình nâng cấp cốt lõi. Giả sử bạn có 50.000 bài đăng, đó là 50.000 hàng bổ sung trong bảng tùy chọn. Rõ ràng là chúng được đặt thành tự động tải = không, vì vậy nó sẽ không tiêu tốn hết bộ nhớ của bạn, nhưng có một cảnh báo khác.

Trường tự động tải trong bảng tùy chọn không có chỉ mục, điều đó có nghĩa là lệnh gọi wp_load_alloptions()sẽ thực hiện quét toàn bộ bảng. Bạn càng có nhiều hàng, nó sẽ mất nhiều thời gian hơn. Bạn càng viết thường xuyên vào bảng tùy chọn, bộ nhớ trong của MySQL càng kém hiệu quả.

Nếu dữ liệu được lưu trong bộ nhớ cache có liên quan trực tiếp đến bài đăng, tốt hơn hết bạn nên lưu trữ nó trong meta bài đăng. Điều này cũng sẽ giúp bạn tiết kiệm một truy vấn mỗi khi bạn cần hiển thị nội dung được lưu trong bộ nhớ cache, bởi vì bộ đệm meta bài đăng (thường) được mồi trong quá trình truy xuất bài đăng trong WP_Query.

Cấu trúc dữ liệu của bạn cho giá trị meta có thể thay đổi, bạn có thể có dấu thời gian và thực hiện truy vấn đắt tiền của mình nếu giá trị được lưu trong bộ nhớ cache, giống như một hành động thoáng qua.

Một suy nghĩ quan trọng khác cần ghi nhớ là các transitor WordPress có thể biến động trong môi trường với bộ nhớ đệm đối tượng liên tục. Điều này có nghĩa là nếu bạn lưu trữ dữ liệu được lưu trong bộ nhớ cache trong 24 giờ thoáng qua, hoàn toàn không có gì đảm bảo nó sẽ khả dụng trong 23 giờ, hoặc 12 hoặc thậm chí 5 phút. Phần cuối bộ đệm bộ đệm đối tượng cho nhiều cài đặt là kho lưu trữ khóa-giá trị trong bộ nhớ như Redis hoặc Memcached và nếu không đủ bộ nhớ được phân bổ để phù hợp với các đối tượng mới hơn, các mục cũ hơn sẽ bị đuổi. Đây là một chiến thắng lớn cho phương pháp lưu trữ meta.

Việc vô hiệu hóa cũng có thể thông minh hơn, tức là tại sao bạn lại vô hiệu hóa các bài đăng liên quan đến bộ nhớ cache trong X giờ? Có phải vì một số nội dung đã thay đổi? Một bài viết mới đã được thêm vào? Một thẻ mới đã được chỉ định? Tùy thuộc vào "truy vấn phức tạp và lớn" của bạn, bạn có thể chọn vô hiệu hóa CHỈ nếu có điều gì đó xảy ra sẽ làm thay đổi kết quả truy vấn của bạn.

Tôi có nên sử dụng API tạm thời để lưu trữ mảng $ liên quan_posts hoặc chuỗi $ htmlDefput không? Nếu tôi lưu trữ chuỗi $ html_ouput, nó có đạt giới hạn kích thước tối đa không? Tôi có nên gzip nó, trước khi lưu?

Nó phụ thuộc rất nhiều vào kích thước chuỗi của bạn, vì đó là dữ liệu sẽ được chuyển giữa PHP, MySQL, v.v. Bạn sẽ cần rất cố gắng để đạt đến giới hạn của MySQL, nhưng ví dụ giới hạn cho mỗi đối tượng mặc định của Memcached là chỉ 1 mb.

"Logic kết xuất bố cục phức tạp" của bạn thực sự mất bao lâu? Chạy nó thông qua một hồ sơ để tìm hiểu. Rất có thể là nó sẽ rất nhanh sẽ không bao giờ trở thành nút cổ chai.

Nếu đó là trường hợp, tôi sẽ đề nghị lưu trữ ID bài đăng. Không phải các đối tượng WP_Post, bởi vì các đối tượng sẽ chứa toàn bộ nội dung bài đăng, mà chỉ là một mảng ID bài đăng. Sau đó, chỉ cần sử dụng một WP_Queryvới một post__inmà sẽ cho kết quả trong một truy vấn MySQL rất nhanh theo khóa chính.

Điều đó nói rằng, nếu dữ liệu cần thiết cho mỗi mục khá đơn giản, có thể là tiêu đề, url hình thu nhỏ và permalink, thì bạn chỉ có thể lưu trữ ba mục đó mà không cần thêm một chuyến đi khứ hồi cho MySQL và không có chi phí lưu trữ bộ nhớ cache HTML rất dài dây.

Wow đó là rất nhiều từ, hy vọng rằng sẽ giúp.


12

Không phải tất cả mã WP là mã công cộng

Nếu bạn định phát hành một cái gì đó công khai, thì tất cả những điều kovshenin nói là hoàn toàn hợp lệ.

Mọi thứ sẽ khác nếu bạn định viết mã riêng cho bản thân hoặc công ty.

Cache đối tượng bên ngoài là một lợi ích lớn, trong mọi trường hợp

Để thiết lập một bộ đệm đối tượng liên tục bên ngoài là rất nên , khi bạn có thể.

Tất cả những điều được nói trong câu trả lời của kovshenin về transents và MySQL là rất đúng, và xem xét rằng chính WP và một loạt các plugin sử dụng bộ đệm đối tượng ... sau đó cải thiện hiệu suất mà bạn có, hoàn toàn xứng đáng với nỗ lực (nhỏ) để thiết lập một hệ thống bộ đệm hiện đại như Redis hoặc Memcached.

Các giá trị được lưu trong bộ nhớ cache có thể không ở đó: Điều đó tốt

Hơn nữa, có, bộ đệm đối tượng bên ngoài không đáng tin cậy. Bạn không bao giờ nên dựa vào thực tế là một thoáng qua ở đó. Bạn cần chắc chắn rằng nó hoạt động nếu bộ nhớ cache không phải là nơi chúng nên được.

Bộ nhớ cache không lưu trữ, bộ nhớ cache là bộ nhớ cache.

Sử dụng bộ nhớ cache có chọn lọc

Xem ví dụ này:

function my_get_some_value($key) {
   // by default no cache when debug and if no external object_cache
   $defUse = ! (defined('WP_DEBUG') && WP_DEBUG) && wp_using_ext_object_cache();
   // make the usage of cache filterable
   $useCache = apply_filters('my_use_cache', $defUse);
   // return cached value if any
   if ($useCache && ($cached = get_transient($key))) {
     return $cached;
   }
   // no cached value, make sure your code works with no cache
   $value = my_get_some_value_in_some_expensive_way();
   // set cache, if allowed
   $useCache and set_transient($key, $value, HOUR_IN_SECONDS);

   return $value;
}

Sử dụng một mã như thế này, trong trang web riêng tư của bạn, hiệu suất trang web có thể cải thiện rất nhiều , đặc biệt là nếu bạn có nhiều người dùng.

Lưu ý rằng:

  • Theo mặc định, bộ đệm không được sử dụng khi gỡ lỗi, vì vậy hy vọng vào môi trường phát triển của bạn. Tin tôi đi, bộ nhớ cache có thể biến việc gỡ lỗi thành một địa ngục
  • Theo mặc định, bộ đệm cũng không được sử dụng khi WP không được đặt để sử dụng bộ đệm đối tượng bên ngoài. Điều đó có nghĩa là tất cả các vấn đề được kết nối với MySQL không tồn tại, bởi vì bạn không sử dụng tạm thời khi họ sử dụng MySQL. Một sự thay thế có lẽ dễ dàng hơn là sử dụng các wp_cache_*chức năng , vì vậy nếu không có bộ đệm ngoài được thiết lập, thì bộ đệm sẽ xảy ra trong bộ nhớ và cơ sở dữ liệu không bao giờ liên quan.
  • Việc sử dụng bộ đệm có thể lọc được, để xử lý một số trường hợp cạnh bạn có thể gặp phải

Không có webscale nếu không có bộ nhớ cache

Bạn không nên cố gắng giải quyết vấn đề tốc độ với bộ đệm. Nếu bạn có vấn đề về tốc độ, thì bạn nên nghĩ lại mã của mình.

Nhưng để mở rộng một trang web tại webscale, bộ nhớ cache là khá bắt buộc .

Và rất nhiều lần (nhưng không phải luôn luôn), bộ đệm nhận biết ngữ cảnh linh hoạt và phù hợp hơn nhiều so với bộ nhớ đệm toàn trang tích cực.

Những câu hỏi của bạn:

Tôi có nên sử dụng API tạm thời ở đây không?

Nó phụ thuộc .

Là mã của bạn tiêu thụ rất nhiều tài nguyên? Nếu không, có lẽ không cần cache. Như đã nói, không chỉ là vấn đề tốc độ. Nếu mã của bạn chạy nhanh nhưng nó đòi hỏi một loạt CPU và bộ nhớ cho một vài người dùng ... điều gì xảy ra khi bạn có 100 hoặc 1000 người dùng đồng thời?

Nếu bạn nhận ra bộ nhớ cache sẽ là một ý tưởng tốt ..

... Và là mã công khai: có thể là không . Bạn có thể xem xét để lưu trữ có chọn lọc, như trong ví dụ của tôi ở trên trong mã công khai, nhưng thường sẽ tốt hơn nếu bạn để các quyết định đó cho người thực hiện.

... Và là mã riêng: rất có thể là có . Nhưng ngay cả đối với mã riêng tư, để bộ nhớ cache chọn lọc vẫn là một điều tốt, ví dụ để gỡ lỗi.

Dù sao, hãy nhớ rằng các wp_cache_*chức năng đó có thể cung cấp cho bạn quyền truy cập vào bộ đệm mà không có nguy cơ gây ô nhiễm cơ sở dữ liệu.

Tôi có nên sử dụng API tạm thời để lưu trữ mảng $ liên quan_posts hoặc chuỗi $ htmlDefput không?

Nó phụ thuộc vào rất nhiều thứ. Làm thế nào lớn là chuỗi? Bạn đang sử dụng bộ đệm ngoài nào? Nếu bạn định lưu các bài đăng vào bộ đệm, lưu trữ ID dưới dạng mảng có thể là một ý tưởng hay, truy vấn số lượng bài đăng kha khá bằng ID của họ khá nhanh.

Ghi chú cuối cùng

API thoáng qua có lẽ là một trong những điều tốt nhất của WordPress. Nhờ các plugin bạn có thể tìm thấy cho bất kỳ loại hệ thống bộ đệm nào, nó trở thành một API đơn giản ngu ngốc cho một số lượng lớn phần mềm có thể hoạt động dưới mui xe.

Bên ngoài WordPress, sự trừu tượng như vậy hoạt động vượt trội với một loạt các hệ thống bộ nhớ đệm khác nhau và cho phép bạn chuyển đổi từ hệ thống này sang hệ thống khác mà không cần nỗ lực là rất khó tìm.

Bạn hiếm khi có thể nghe tôi nói rằng WordPress tốt hơn những thứ hiện đại khác, nhưng API tạm thời là một trong số ít những điều tôi bỏ lỡ khi tôi không làm việc với WordPress.

Chắc chắn bộ nhớ cache rất khó, không giải quyết được các vấn đề về mã và không phải là viên đạn bạc, nhưng đó là thứ bạn cần để xây dựng một trang web có lưu lượng truy cập cao hoạt động.

Ý tưởng WordPress sử dụng bảng MySQL được tối ưu hóa để làm bộ đệm là khá điên rồ, nhưng tốt hơn hết là bạn nên tránh xa bộ đệm chỉ vì WordPress, theo mặc định, thực hiện nó.

Bạn chỉ cần hiểu cách mọi thứ hoạt động, sau đó đưa ra lựa chọn của bạn.


2

Các câu trả lời trước đã nhấn mạnh " Nó phụ thuộc " bắt buộc , mà tôi hoàn toàn đồng ý.

Tuy nhiên, tôi muốn thêm một đề xuất, dựa trên cách tôi " giả sử " điều này sẽ được thực hiện tốt nhất trong kịch bản bạn đang mô tả ở trên.

Tôi sẽ không sử dụng Transents trong trường hợp đó, mà là Post Meta , vì một ưu điểm mà cái sau có: Kiểm soát .

Vì bạn cần lưu trữ dữ liệu trên cơ sở mỗi bài đăng, lượng dữ liệu bạn sẽ lưu vào bộ nhớ cache tùy thuộc vào số lượng bài đăng và sẽ tăng lên theo thời gian. Khi bạn vượt qua một số bài đăng nhất định, bạn có thể đạt đến giới hạn bộ nhớ mà bộ đệm đối tượng của bạn được phép sử dụng và nó sẽ bắt đầu xóa dữ liệu được lưu trong bộ nhớ cache trước đó khỏi bộ nhớ trước khi hết hạn. Điều này có thể dẫn đến một tình huống, trong đó bạn có một lượng lớn khách truy cập, trong đó mỗi khách truy cập sẽ kích hoạt "SQL quá phức tạp" theo từng yêu cầu trang và trang web của bạn sẽ hoàn toàn bị sa lầy.

Nếu bạn lưu trữ dữ liệu trong Post Meta của mình, bạn không chỉ có thể kiểm soát cách lưu trữ và truy xuất mà còn có thể kiểm soát chính xác cách cập nhật. Bạn sẽ thêm một công việc định kỳ cho công việc này chỉ chạy trong khoảng thời gian có ít lưu lượng truy cập đến trang web. Vì vậy, "truy vấn chậm" không bao giờ gặp phải bởi người dùng thực của trang web và bạn thậm chí có thể tải trước nó, để công việc đã được thực hiện khi khách truy cập đầu tiên truy cập.

Hãy nhớ rằng tất cả các bộ nhớ đệm là một sự đánh đổi! Đó là lý do tại sao câu trả lời thông thường là "Nó phụ thuộc." và tại sao không có "chén thánh lưu trữ".

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.