Bộ đệm trong Symfony là gì?

Trong bài viết này của Sohail Salehi, tác giả của cuốn sách Mastering Symfony, chúng ta sẽ thảo luận về việc cải thiện hiệu suất bằng cách sử dụng bộ đệm. Bộ nhớ đệm là một chủ đề rộng lớn và cần có cuốn sách riêng để trình bày đúng cách. Tuy nhiên, trong dự án Symfony của chúng tôi, chúng tôi chỉ quan tâm đến hai loại bộ đệm

  • bộ đệm ứng dụng
  • Bộ đệm cơ sở dữ liệu

Chúng ta sẽ xem những phương tiện lưu trữ nào được cung cấp trong Symfony theo mặc định và cách chúng ta có thể sử dụng chúng

Chúng tôi sẽ áp dụng các kỹ thuật bộ nhớ đệm trên một số phương pháp trong các dự án của mình và xem sự cải thiện hiệu suất

Đến cuối bài viết này, bạn sẽ hiểu rõ về việc sử dụng các tiêu đề bộ đệm HTTP trong lớp ứng dụng và các thư viện bộ đệm


(Để biết thêm tài nguyên liên quan đến chủ đề này, hãy xem. )

Định nghĩa bộ đệm

Bộ nhớ cache là nơi tạm thời lưu trữ nội dung có thể được phục vụ nhanh hơn khi cần. Xem xét rằng chúng tôi đã có một vị trí cố định trên đĩa để lưu trữ nội dung web của chúng tôi (mẫu, mã và bảng cơ sở dữ liệu), bộ nhớ cache giống như một bộ lưu trữ trùng lặp

Đó chính xác là những gì họ đang có. Chúng là các bản sao và chúng tôi cần chúng vì đổi lại việc tiêu tốn thêm dung lượng để lưu trữ cùng một dữ liệu, chúng cung cấp phản hồi rất nhanh cho một số yêu cầu. Vì vậy, đây là một sự đánh đổi rất tốt giữa lưu trữ và hiệu suất

Để cung cấp cho bạn một ví dụ về mức độ tốt của giao dịch này, hãy xem xét hình ảnh sau đây. Ở phía bên trái, chúng tôi có mô hình yêu cầu/phản hồi máy khách/máy chủ thông thường và giả sử độ trễ phản hồi là hai giây và chỉ có 100 người dùng truy cập cùng một nội dung mỗi giờ

Bộ đệm trong Symfony là gì?

Tuy nhiên, ở phía bên phải, chúng tôi có một lớp bộ đệm nằm giữa máy khách và máy chủ. Những gì nó làm về cơ bản là nhận cùng một yêu cầu và chuyển nó đến máy chủ. Máy chủ gửi phản hồi tới bộ đệm và vì phản hồi này là mới đối với bộ đệm nên nó sẽ lưu một bản sao (bản sao) của phản hồi rồi chuyển lại cho máy khách. Độ trễ là 2 + 0. 2 giây

Tuy nhiên, nó không cộng lại, phải không? . Nó đã thêm nhiều độ trễ hơn vào chu kỳ. Với kết quả này, làm thế nào nó có thể có lợi?

Bộ đệm trong Symfony là gì?

Bây giờ, với phản hồi được lưu vào bộ đệm, hãy tưởng tượng yêu cầu tương tự được thực hiện. (Chúng ta có khoảng 100 yêu cầu/giờ cho cùng một nội dung, bạn nhớ chứ?) Lần này, lớp bộ nhớ cache xem xét không gian của nó, tìm phản hồi và gửi lại cho máy khách mà không làm phiền máy chủ. độ trễ là 0. 2 giây

Tất nhiên, đây chỉ là những con số và tình huống tưởng tượng. Tuy nhiên, ở dạng đơn giản nhất, đây là cách bộ đệm hoạt động. Nó có thể không hữu ích lắm trên một trang web có lưu lượng truy cập thấp;

Vì vậy, theo những hình ảnh trước đó, chúng ta có thể định nghĩa một số thuật ngữ và sử dụng chúng trong bài viết này khi chúng ta tiếp tục. Trong hình ảnh đầu tiên, khi một khách hàng yêu cầu trang đó, nó không được thoát ra và lớp bộ đệm phải lưu một bản sao nội dung của nó để tham khảo trong tương lai. Cái này gọi là Cache Miss. Tuy nhiên, trong hình ảnh thứ hai, chúng tôi đã có một bản sao của nội dung được lưu trữ trong bộ đệm và chúng tôi đã được hưởng lợi từ nó. Đây được gọi là Lượt truy cập bộ đệm

Đặc điểm của một bộ đệm tốt

Nếu bạn tìm kiếm nhanh, bạn sẽ thấy rằng một bộ đệm tốt được định nghĩa là bộ đệm chỉ bỏ lỡ một lần. Nói cách khác, lỗi bộ đệm này chỉ xảy ra nếu nội dung chưa được yêu cầu trước đó. Tính năng này là cần thiết nhưng nó không đủ. Để làm rõ tình hình một chút, hãy thêm hai thuật ngữ nữa ở đây. Bộ đệm có thể ở một trong các trạng thái sau. mới (có cùng nội dung với phản hồi ban đầu) và cũ (có nội dung của phản hồi cũ hiện đã thay đổi trên máy chủ)

Câu hỏi quan trọng ở đây là bộ đệm nên được giữ trong bao lâu? . Chúng ta sẽ xem làm thế nào để làm điều này trong các phần tiếp theo. Tuy nhiên, chỉ vì chúng tôi có sức mạnh này không có nghĩa là chúng tôi đúng về độ mới của nội dung. Xem xét tình huống được hiển thị trong hình ảnh sau

Bộ đệm trong Symfony là gì?

Nếu chúng tôi lưu trữ một nội dung trong một thời gian dài, lỗi bộ nhớ cache sẽ không xảy ra nữa (thỏa mãn định nghĩa trước đó), nhưng nội dung có thể mất độ mới theo các tài nguyên động có thể thay đổi trên máy chủ. Để cho bạn một ví dụ, không ai thích đọc tin tức của ba tháng trước khi họ mở trang web BBC

Bây giờ, chúng ta có thể sửa đổi định nghĩa về bộ đệm tốt như sau

Chiến lược bộ đệm được coi là tốt nếu lỗi bộ đệm cho cùng một nội dung chỉ xảy ra một lần, trong khi nội dung được lưu trong bộ đệm vẫn còn mới

Điều này có nghĩa là việc xác định thời gian hết hạn của bộ đệm sẽ không đủ và chúng tôi cần một chiến lược khác để theo dõi độ mới của bộ đệm. Điều này xảy ra thông qua chiến lược xác thực bộ đệm. Khi máy chủ gửi phản hồi, chúng tôi có thể đặt quy tắc xác thực trên cơ sở những gì thực sự quan trọng ở phía máy chủ và bằng cách này, chúng tôi có thể giữ cho nội dung được lưu trữ trong bộ đệm luôn mới, như thể hiện trong hình ảnh sau. Chúng ta sẽ sớm xem cách thực hiện điều này trong Symfony

Bộ đệm trong Symfony là gì?

Bộ nhớ cache trong một dự án Symfony

Trong bài viết này, chúng tôi sẽ tập trung vào hai loại bộ đệm. Bộ đệm cổng (cũng được gọi là bộ đệm proxy ngược) và bộ đệm học thuyết. Như bạn có thể đoán, bộ đệm cổng xử lý tất cả các tiêu đề bộ đệm HTTP. Symfony đi kèm với bộ đệm cổng rất mạnh. Tất cả những gì bạn cần làm chỉ là kích hoạt nó trong bộ điều khiển phía trước, sau đó bắt đầu xác định các chiến lược xác thực và hết hạn bộ nhớ cache bên trong bộ điều khiển của bạn

Nói như vậy không có nghĩa là bạn bị ép buộc hoặc hạn chế chỉ sử dụng bộ đệm Symfony. Nếu bạn thích các thư viện bộ nhớ cache proxy ngược khác (nghĩa là Varnish hoặc Django), bạn có thể sử dụng chúng. Các cấu hình bộ nhớ đệm trong Symfony minh bạch đến mức bạn không cần phải thay đổi một dòng nào bên trong bộ điều khiển của mình khi bạn thay đổi thư viện bộ đệm của mình. Chỉ cần sửa đổi cấu hình của bạn. yml và bạn sẽ ổn thôi

Tuy nhiên, tất cả chúng ta đều biết rằng bộ nhớ đệm không chỉ dành cho các lớp ứng dụng và chế độ xem. Đôi khi, chúng ta cũng cần lưu trữ bất kỳ nội dung nào liên quan đến cơ sở dữ liệu. Đối với Doctrine ORM của chúng tôi, điều này bao gồm bộ đệm siêu dữ liệu, bộ đệm truy vấn và bộ đệm kết quả

Doctrine đi kèm với gói riêng để xử lý các loại bộ đệm này và nó sử dụng nhiều loại thư viện (APC, Memcached, Redis, v.v.) để thực hiện công việc. Một lần nữa, chúng tôi không cần cài đặt bất cứ thứ gì để sử dụng gói bộ đệm này. Nếu chúng tôi đã cài đặt Doctrine, tất cả những gì chúng tôi cần làm là định cấu hình một cái gì đó và sau đó tất cả sức mạnh của bộ nhớ đệm Doctrine sẽ do chúng tôi sử dụng

Đặt hai loại bộ nhớ đệm này lại với nhau, chúng ta sẽ có một bức tranh lớn để lưu trữ dự án Symfony của mình

Bộ đệm trong Symfony là gì?

Như bạn có thể thấy trong hình ảnh này, chúng tôi có thể gặp sự cố với trang được lưu trong bộ nhớ cache cuối cùng. Hãy tưởng tượng rằng chúng ta có một trang tĩnh có thể thay đổi mỗi tuần một lần và trong trang này, có một số khối có thể thay đổi hàng ngày hoặc thậm chí hàng giờ, như thể hiện trong hình ảnh sau. Bảng điều khiển người dùng trong dự án của chúng tôi là một ví dụ điển hình

Bộ đệm trong Symfony là gì?

Do đó, nếu chúng tôi đặt thời hạn hết hạn trên bộ đệm cổng thành một tuần, thì chúng tôi không thể phản ánh tất cả các bản cập nhật nhanh đó trong bộ điều khiển dự án và tác vụ của chúng tôi

Để giải quyết vấn đề này, chúng ta có thể tận dụng từ Edge Side Bao gồm (ESI) bên trong Symfony. Về cơ bản, bất kỳ phần nào của trang đã được xác định bên trong thẻ ESI đều có thể kể câu chuyện bộ đệm của chính nó cho bộ đệm cổng. Do đó, chúng ta có thể có nhiều chiến lược bộ nhớ cache tồn tại cạnh nhau trong một trang. Với giải pháp này, bức tranh lớn của chúng ta sẽ như sau

Bộ đệm trong Symfony là gì?

Do đó, chúng tôi sẽ sử dụng các tính năng bộ nhớ đệm mặc định của Symfony và Doctrine cho các lớp mô hình và ứng dụng, đồng thời bạn cũng có thể sử dụng một số gói phổ biến của bên thứ ba để có các cài đặt nâng cao hơn. Nếu bạn hoàn toàn hiểu nguyên lý bộ nhớ đệm, việc chuyển sang các gói bộ nhớ đệm khác sẽ rất dễ dàng

Trình phát chính trong tiêu đề bộ đệm HTTP

Trước khi đi sâu vào bộ nhớ cache của ứng dụng Symfony, hãy tự làm quen với các yếu tố mà chúng ta cần xử lý trong các chiến lược bộ nhớ cache của mình. Để làm như vậy, hãy mở https. //www. wikipedia. org/ trong trình duyệt của bạn và kiểm tra bất kỳ tài nguyên nào có mã phản hồi 304 và suy ngẫm về các tiêu đề yêu cầu/phản hồi bên trong tab Mạng

Bộ đệm trong Symfony là gì?

Trong số các yếu tố phản hồi, có bốn tiêu đề bộ đệm mà chúng tôi quan tâm nhất. hết hạn và kiểm soát bộ đệm, sẽ được sử dụng cho mô hình hết hạn và etag và sửa đổi lần cuối, sẽ được sử dụng cho mô hình xác thực

Ngoài các tiêu đề bộ đệm này, chúng tôi có thể có các biến thể của cùng một bộ đệm (nén/không nén) thông qua tiêu đề Vary và chúng tôi có thể xác định bộ đệm là riêng tư (người dùng cụ thể có thể truy cập) hoặc công khai (mọi người có thể truy cập)

Sử dụng bộ đệm proxy ngược Symfony

Không cần quy trình phức tạp hoặc dài dòng để kích hoạt bộ đệm cổng của Symfony. Chỉ cần mở bộ điều khiển phía trước và bỏ ghi chú các dòng sau

// web/app.php
loadClassCache();
    // and this line
    $kernel = new AppCache($kernel);
    // ...
?>

Bây giờ, kernel được bọc quanh lớp Bộ đệm ứng dụng, điều đó có nghĩa là bất kỳ yêu cầu nào đến từ máy khách sẽ đi qua lớp này trước

Đặt thời hạn cho trang tổng quan

Đăng nhập vào dự án của bạn và nhấp vào phần Yêu cầu/Phản hồi trên thanh công cụ gỡ lỗi. Sau đó, cuộn xuống Tiêu đề phản hồi và kiểm tra nội dung

Bộ đệm trong Symfony là gì?

Như bạn có thể thấy, chỉ có kiểm soát bộ đệm nằm ở đó với một số giá trị mặc định trong số các tiêu đề bộ đệm mà chúng tôi quan tâm

Khi bạn không đặt bất kỳ giá trị nào cho Cache-Control, Symfony sẽ coi nội dung trang là riêng tư để giữ chúng an toàn

Bây giờ, hãy chuyển đến bộ điều khiển Bảng điều khiển và thêm một số cài đặt bộ đệm cổng vào phương thức indexAction()

// src/AppBundle/Controller/DashboardController.php
getUser()->getId();
    $util = $this->get('mava_util');
    $userProjects = $util->getUserProjects($uId);
    $currentTasks= $util->getUserTasks($uId, 'in progress');
    
    $response = new Response();
    $date = new DateTime('+2 days');
    $response->setExpires($date);
    
    return $this->render(
      'CoreBundle:Dashboard:index.html.twig',
      array(
        'currentTasks'  => $currentTasks,
        'userProjects'  => $userProjects
      ),
      $response
    );
  }
}

Bạn có thể nhận thấy rằng chúng tôi đã không thay đổi phương thức render(). Thay vào đó, chúng tôi đã thêm cài đặt phản hồi làm tham số thứ ba của phương pháp này. Đây là một giải pháp tốt vì bây giờ chúng tôi có thể giữ cấu trúc mẫu hiện tại và việc thêm cài đặt mới sẽ không yêu cầu bất kỳ thay đổi nào khác trong mã

Tuy nhiên, bạn có thể tự hỏi chúng ta có những lựa chọn nào khác?

// src/AppBundle/Controller/DashboardController.php
render(
      'AppBundle:Dashboard:index.html.twig',
      array(
        'currentTasks'  => $currentTasks,
        'userProjects'  => $userProjects
      )
    );
    $res->setExpires($date);
    return $res;
?>

Có vẻ như vẫn còn rất nhiều công việc khó khăn cho cài đặt tiêu đề phản hồi đơn giản. Vì vậy, hãy để tôi giới thiệu một lựa chọn tốt hơn. Chúng ta có thể sử dụng chú thích @Cache như sau

//  src/AppBundle/Controller/DashboardController.php
getUser()->getId();
    $util = $this->get('mava_util');
    $userProjects = $util->getUserProjects($uId);
    $currentTasks= $util->getUserTasks($uId, 'in progress');

    return $this->render(
      'AppBundle:Dashboard:index.html.twig', array(
      'currentTasks'  => $currentTasks,
      'userProjects'  => $userProjects
    ));
  }
}

Bạn có nhận thấy rằng đối tượng phản hồi đã bị xóa hoàn toàn khỏi mã không? . Bây giờ đó là những gì tôi gọi là bảo trì không tính phí. Hãy kiểm tra các tiêu đề phản hồi của chúng tôi trong thanh công cụ gỡ lỗi của Symfony và xem nó trông như thế nào

Bộ đệm trong Symfony là gì?

Điểm hay của chú thích @Cache là chúng có thể được lồng vào nhau. Hãy tưởng tượng bạn có một bộ điều khiển đầy các hành động. Bạn muốn tất cả chúng có độ tuổi tối đa được chia sẻ là nửa giờ, ngoại trừ độ tuổi được cho là riêng tư và sẽ hết hạn sau năm phút. Điều này nghe có vẻ nhiều mã nếu bạn định sử dụng trực tiếp các đối tượng phản hồi, nhưng với một chú thích, nó sẽ đơn giản như thế này

Chú thích được xác định trước lớp trình điều khiển sẽ áp dụng cho mọi hành động đơn lẻ, trừ khi chúng ta thêm một chú thích mới cho một hành động một cách rõ ràng

chiến lược xác nhận

Trong ví dụ trước, chúng tôi đặt thời hạn rất dài. Điều này có nghĩa là nếu một tác vụ mới được gán cho người dùng, thì tác vụ đó sẽ không hiển thị trong bảng điều khiển của anh ta do chiến lược bộ nhớ đệm sai. Để khắc phục sự cố này, chúng tôi có thể xác thực bộ đệm trước khi sử dụng

Có hai cách để xác thực

  • Chúng ta có thể kiểm tra ngày của nội dung qua tiêu đề Last-Modified. Trong kỹ thuật này, chúng tôi xác nhận độ mới của nội dung thông qua thời gian nội dung được sửa đổi. Nói cách khác, nếu chúng ta theo dõi ngày và giờ của từng thay đổi trên một tài nguyên, thì chúng ta có thể chỉ cần so sánh ngày đó với ngày của bộ đệm và tìm hiểu xem nó có còn mới không
  • Chúng tôi có thể sử dụng tiêu đề ETag làm chữ ký nội dung duy nhất. Giải pháp khác là tạo một chuỗi duy nhất dựa trên nội dung và đánh giá độ mới của bộ đệm dựa trên chữ ký của nó

Chúng tôi sẽ thử cả hai trong bộ điều khiển Bảng điều khiển và xem chúng hoạt động

Việc sử dụng đúng tiêu đề xác thực hoàn toàn phụ thuộc vào mã hiện tại. Trong một số tác vụ, việc tính toán ngày sửa đổi dễ dàng hơn nhiều so với việc tạo dấu chân kỹ thuật số, trong khi ở một số tác vụ khác, việc xem qua chức năng ngày và giờ có vẻ tốn kém. Tất nhiên, có những tình huống tạo cả hai tiêu đề là rất quan trọng. Vì vậy, việc tạo ra nó hoàn toàn phụ thuộc vào cơ sở mã và những gì bạn sẽ đạt được

Như bạn có thể thấy, chúng ta có hai thực thể trong phương thức indexAction() và, xem xét mã hiện tại, việc tạo tiêu đề ETag có vẻ thực tế. Vì vậy, tiêu đề xác thực sẽ trông như sau

// src/AppBundle/Controller/DashboardController.php

Lần tiếp theo khi có yêu cầu, lớp bộ đệm sẽ xem xét giá trị ETag trong bộ điều khiển, so sánh nó với ETag của chính nó và gọi phương thức indexAction();

Cách kết hợp các chiến lược hết hạn và xác thực

Hãy tưởng tượng rằng chúng tôi muốn giữ cho bộ đệm luôn mới trong 10 phút và đồng thời theo dõi mọi thay đổi đối với các dự án của người dùng hoặc các tác vụ đã hoàn thành. Rõ ràng là các nhiệm vụ sẽ không hoàn thành sau mỗi 10 phút và việc mong đợi những thay đổi về trạng thái dự án trong giai đoạn này là điều vượt xa thực tế.

Vì vậy, những gì chúng ta có thể làm để làm cho chiến lược bộ nhớ đệm của mình hiệu quả là chúng ta có thể kết hợp Hết hạn và Xác thực lại với nhau và áp dụng chúng cho Bộ điều khiển bảng điều khiển như sau

// src/CoreBundle/Controller/DashboardController.php

Hãy nhớ rằng Hết hạn có mức độ ưu tiên cao hơn Xác thực. Nói cách khác, bộ đệm sẽ được làm mới trong 10 phút, bất kể trạng thái xác thực là gì. Vì vậy, khi bạn truy cập trang tổng quan của mình lần đầu tiên, bộ đệm mới cộng với phản hồi 302 (không được sửa đổi) sẽ được tạo tự động và bạn sẽ nhấn vào bộ đệm trong 10 phút tiếp theo

Tuy nhiên, những gì xảy ra sau 10 phút thì hơi khác một chút. Bây giờ, trạng thái hết hạn không thỏa mãn;

Tuy nhiên, nếu có bất kỳ thay đổi nào trong nhiệm vụ hoặc trạng thái dự án của bạn, thì bạn sẽ truy cập máy chủ để nhận phản hồi thực và bộ đệm mới từ nội dung của phản hồi, thời gian hết hạn mới và ETag mới được tạo và lưu trữ trong lớp bộ đệm cho

Tóm lược

Trong bài viết này, bạn đã tìm hiểu về những kiến ​​thức cơ bản về cổng và Doctrine caching. Chúng tôi đã xem cách đặt các chiến lược xác thực và hết hạn bằng cách sử dụng các tiêu đề HTTP như Kiểm soát bộ đệm, Hết hạn, Sửa đổi lần cuối và ETag. Bạn đã học cách đặt mức truy cập công khai và riêng tư cho bộ đệm và sử dụng chú thích để xác định quy tắc bộ đệm trong bộ điều khiển

Tài nguyên cho bài báo


Các tài nguyên khác về chủ đề này

  • Tương tác người dùng và tự động hóa email trong Symfony 1. 3. Phần1 [bài báo]
  • Symfony Framework – Cài đặt và Cấu hình [bài viết]
  • Tương tác người dùng và tự động hóa email trong Symfony 1. 3. Phần2 [bài viết]

Chia sẻ

Facebook

Twitter

liên kết

Bộ đệm trong Symfony là gì?

gói

ĐỂ LẠI TRẢ LỜI

Vui lòng nhập nhận xét của bạn

Vui lòng nhập tên của bạn vào đây

Bạn đã nhập sai địa chỉ email

Vui lòng nhập địa chỉ email của bạn vào đây

Lưu tên, email và trang web của tôi trong trình duyệt này cho lần bình luận tiếp theo

Δ

Bộ đệm trong Symfony là gì?

Phải đọc trong Web Dev

Bộ đệm trong Symfony là gì?

Phát triển web

Học các lệnh Linux cần thiết để điều hướng Shell một cách hiệu quả

Mạng lưới chuyên gia - Ngày 16 tháng 8 năm 2021 - 3. 45 giờ sáng

Khi chúng ta tìm hiểu cách triển khai máy chủ Ubuntu, cách quản lý người dùng và cách quản lý các gói phần mềm, chúng ta nên dành một chút thời gian