Làm thế nào để "khởi động" Khung thực thể? Khi nào nó trở nên "lạnh"?


118

Không, câu trả lời cho câu hỏi thứ hai của tôi không phải là mùa đông.

Lời nói đầu:

Tôi đã thực hiện rất nhiều nghiên cứu về Entity Framework gần đây và điều khiến tôi bận tâm là hiệu suất của nó khi các truy vấn không được khởi động, được gọi là truy vấn nguội.

Tôi đã xem qua bài viết cân nhắc về hiệu suất cho Entity Framework 5.0. Các tác giả đã đưa ra khái niệm truy vấn ẤmLạnh và chúng khác nhau như thế nào, mà bản thân tôi cũng nhận thấy mà không biết về sự tồn tại của chúng. Ở đây có lẽ đáng nói là tôi chỉ có sáu tháng kinh nghiệm sau lưng.

Bây giờ tôi biết những chủ đề nào tôi có thể nghiên cứu thêm nếu tôi muốn hiểu rõ hơn về khung công tác về mặt hiệu suất. Thật không may, hầu hết thông tin trên Internet đã lỗi thời hoặc bị thổi phồng do chủ quan, do đó tôi không thể tìm thấy bất kỳ thông tin bổ sung nào về chủ đề truy vấn Warm vs Cold .

Về cơ bản những gì tôi nhận thấy cho đến nay là bất cứ khi nào tôi phải biên dịch lại hoặc lần tái chế xảy ra, các truy vấn ban đầu của tôi đang trở nên rất chậm. Mọi lần đọc dữ liệu tiếp theo đều nhanh ( chủ quan ), như mong đợi.

Chúng tôi sẽ chuyển sang Windows Server 2012, IIS8 và SQL Server 2012 và với tư cách là một Junior, tôi thực sự đã giành cho mình cơ hội để kiểm tra chúng trước phần còn lại. Tôi rất vui vì họ đã giới thiệu một mô-đun khởi động sẽ giúp ứng dụng của tôi sẵn sàng cho yêu cầu đầu tiên đó. Tuy nhiên, tôi không chắc chắn cách tiếp tục khởi động Khung thực thể của mình.

Những gì tôi đã biết là đáng làm:

  • Tạo Chế độ xem của tôi trước theo đề xuất.
  • Cuối cùng chuyển các mô hình của tôi vào một bộ phận riêng biệt.

Những gì tôi cho là đang làm, theo lẽ thường, có thể là cách tiếp cận sai :

  • Thực hiện đọc dữ liệu giả tại Khởi động ứng dụng để làm nóng mọi thứ, tạo và xác thực các mô hình.

Câu hỏi:

  • Cách tiếp cận tốt nhất để có tính khả dụng cao trên Khung thực thể của tôi bất cứ lúc nào sẽ là gì?
  • Trong những trường hợp nào thì Entity Framework lại bị "nguội"? (Biên dịch, Tái chế, Khởi động lại IIS, v.v.)

Tìm hiểu xem đây là cách tạo chế độ xem hay biên dịch truy vấn khiến bạn thích thú nhất. Nếu đây là chế độ xem gen thì hãy sử dụng các chế độ xem được biên dịch trước. Nếu đây là các truy vấn - bạn có một hệ thống phân cấp phức tạp lớn không? Lưu ý rằng những điều tốn kém thường xảy ra một lần trên mỗi miền ứng dụng và được lưu vào bộ nhớ đệm, do đó bạn sẽ thấy loại sự cố này khi miền ứng dụng được tải xuống và một miền mới được tạo.
Pawel

Tôi đã đề cập đến chế độ xem @Pawel, hệ thống phân cấp không phức tạp, thậm chí không có một chút nào. Nhưng vấn đề là hiệu trưởng. Sau những gì bạn đã nói, tôi sẽ nghiên cứu xem khi nào miền ứng dụng được dỡ bỏ. Tuy nhiên, điều đó vẫn không giải quyết được vấn đề khác đang làm nóng Khung thực thể trong trường hợp, như bạn đã nói, miền ứng dụng bị dỡ bỏ. Tại thời điểm này, có vẻ như lĩnh vực ứng dụng đang được bốc dỡ hơn nó nên được và tôi không chắc chắn lý do tại sao, tái chế chỉ trong đêm, chạy không tải được đặt thành 0.
Peter

4
Tại sao bạn nghĩ đọc dữ liệu giả là cách tiếp cận sai?
Josh Heitzman,

5
Nó chỉ cảm thấy không ổn, tôi nghĩ rằng có thể có một cái gì đó thanh lịch hơn mà tôi không biết. Nhưng nếu đó là giải pháp duy nhất và ai đó có kiến ​​thức tốt có thể xác nhận không có cách nào khác, tôi sẽ chỉ làm với nó.
Peter

1
Một vấn đề mà tôi gặp phải khi nhóm ứng dụng ngừng hoạt động sau một khoảng thời gian không hoạt động (do lưu lượng truy cập thấp) là tạo một dịch vụ đưa ra yêu cầu trong một khoảng thời gian nhất định cho một trong các trang của bạn. Điều này ngăn chặn sự chậm trễ lâu trước khi nhóm ứng dụng được khởi động lại theo yêu cầu đầu tiên. Hoặc bạn có thể sử dụng một dịch vụ miễn phí như www.pingalive.com để ping tên miền / ip của bạn. Điều này cũng giúp ngăn các đối tượng được lưu trong bộ nhớ cache của bạn bị xóa trước khi chúng hết hạn.
hatrumandcode

Câu trả lời:


55
  • Cách tiếp cận tốt nhất để có tính khả dụng cao trên Khung thực thể của tôi bất cứ lúc nào sẽ là gì?

Bạn có thể kết hợp các chế độ xem được tạo trước và các truy vấn được biên dịch tĩnh.

Static CompiledQuerys tốt vì chúng nhanh chóng, dễ viết và giúp tăng hiệu suất. Tuy nhiên với EF5, không cần thiết phải biên dịch tất cả các truy vấn của bạn vì EF sẽ tự động biên dịch các truy vấn. Vấn đề duy nhất là những truy vấn này có thể bị mất khi bộ nhớ cache bị quét. Vì vậy, bạn vẫn muốn giữ các tham chiếu đến các truy vấn đã biên dịch của riêng mình cho những truy vấn chỉ xảy ra rất hiếm, nhưng đắt tiền. Nếu bạn đặt các truy vấn đó vào các lớp tĩnh, chúng sẽ được biên dịch khi chúng được yêu cầu lần đầu tiên. Điều này có thể là quá muộn đối với một số truy vấn, vì vậy bạn có thể muốn buộc biên dịch các truy vấn này trong khi khởi động ứng dụng.

Tạo trước lượt xem là khả năng khác như bạn đề cập. Đặc biệt, đối với những truy vấn mất rất nhiều thời gian để biên dịch và điều đó không thay đổi. Bằng cách đó, bạn chuyển chi phí hiệu suất từ ​​thời gian chạy sang thời gian biên dịch. Ngoài ra, điều này sẽ không gây ra bất kỳ độ trễ nào. Nhưng tất nhiên sự thay đổi này sẽ đi vào cơ sở dữ liệu, vì vậy nó không dễ dàng để xử lý. Mã linh hoạt hơn.

Không sử dụng nhiều TPT kế thừa (đó là vấn đề hiệu suất chung trong EF). Không xây dựng hệ thống phân cấp kế thừa của bạn quá sâu hoặc quá rộng. Chỉ 2-3 thuộc tính cụ thể cho một số lớp có thể không đủ để yêu cầu một kiểu riêng, nhưng có thể được xử lý như các thuộc tính tùy chọn (có thể vô hiệu) cho một kiểu hiện có.

Đừng giữ chặt một ngữ cảnh trong một thời gian dài. Mỗi phiên bản ngữ cảnh có bộ đệm ẩn cấp đầu tiên của riêng nó, làm chậm hiệu suất khi nó phát triển lớn hơn. Việc tạo ngữ cảnh rất rẻ, nhưng việc quản lý nhà nước bên trong các thực thể được lưu trong bộ nhớ cache của ngữ cảnh có thể trở nên tốn kém. Các bộ đệm khác (kế hoạch truy vấn và siêu dữ liệu) được chia sẻ giữa các ngữ cảnh và sẽ chết cùng với AppDomain.

Nói chung, bạn nên đảm bảo phân bổ các ngữ cảnh thường xuyên và chỉ sử dụng chúng trong thời gian ngắn, để bạn có thể khởi động ứng dụng của mình một cách nhanh chóng, biên dịch các truy vấn hiếm khi được sử dụng và cung cấp các dạng xem được tạo trước cho các truy vấn quan trọng về hiệu suất và thường được sử dụng.

  • Trong những trường hợp nào thì Entity Framework lại bị "nguội"? (Biên dịch, Tái chế, Khởi động lại IIS, v.v.)

Về cơ bản, mỗi khi bạn mất AppDomain. IIS thực hiện khởi động lại sau mỗi 29 giờ , vì vậy bạn không bao giờ có thể đảm bảo rằng bạn sẽ có các phiên bản của mình. Ngoài ra, sau một thời gian không có hoạt động, AppDomain cũng bị tắt. Bạn nên cố gắng đến nhanh chóng một lần nữa. Có thể bạn có thể thực hiện một số quá trình khởi tạo không đồng bộ (nhưng hãy cẩn thận với các vấn đề đa luồng). Bạn có thể sử dụng các tác vụ đã lên lịch để gọi các trang giả trong ứng dụng của mình trong những thời điểm không có yêu cầu nào để ngăn AppDomain chết, nhưng cuối cùng thì nó sẽ như vậy.

Tôi cũng giả sử rằng khi bạn thay đổi tệp cấu hình của mình hoặc thay đổi các hợp ngữ, sẽ có khởi động lại.


Cảm ơn Andre, đó là những gì tôi cần.
Peter

@Andreas Trên thực tế, ngay cả với các truy vấn được biên dịch tĩnh, lần chạy đầu tiên là quá dài. Có cách nào để làm nóng những thứ đó ngoài việc: Thực hiện đọc dữ liệu giả khi Khởi động ứng dụng để làm ấm mọi thứ, tạo và xác thực các mô hình.
manishKungwani

@Andreas Vậy Entity framework5 có cần hay không? những gì là khác nhau nếu sử dụng nó trên ef5 (Tôi có nghĩa là vẫn còn chậm hoặc ít bột hay không khác nhau?)
qakmak

"Static CompiledQuerys tốt vì chúng nhanh chóng, dễ viết và giúp giảm hiệu suất." Giảm hiệu suất?
Mathemats

9

Nếu bạn đang tìm kiếm hiệu suất tối đa trên tất cả các cuộc gọi, bạn nên xem xét kỹ kiến ​​trúc của mình. Ví dụ: có thể có ý nghĩa khi lưu trước bộ nhớ cache thường được sử dụng tìm kiếm trong RAM máy chủ khi ứng dụng tải lên thay vì sử dụng lệnh gọi cơ sở dữ liệu theo mọi yêu cầu. Kỹ thuật này sẽ đảm bảo thời gian phản hồi ứng dụng tối thiểu cho dữ liệu thường được sử dụng. Tuy nhiên, bạn phải đảm bảo có chính sách hết hạn hoạt động tốt hoặc luôn xóa bộ nhớ cache của mình bất cứ khi nào thực hiện các thay đổi ảnh hưởng đến dữ liệu được lưu trong bộ nhớ cache để tránh các vấn đề với đồng thời.

Nói chung, bạn nên cố gắng thiết kế các kiến ​​trúc phân tán để chỉ yêu cầu các yêu cầu dữ liệu dựa trên IO khi thông tin được lưu trữ cục bộ trở nên cũ hoặc cần được giao dịch. Mọi yêu cầu dữ liệu "qua dây" thông thường sẽ mất thời gian truy xuất lâu hơn 10-1000 lần so với truy xuất cục bộ trong bộ nhớ đệm. Chỉ một thực tế này thường làm cho các cuộc thảo luận về "dữ liệu lạnh so với ấm" trở nên không quan trọng so với vấn đề dữ liệu "cục bộ so với từ xa".


Đây là một điểm tốt mà tôi thường bỏ qua, trong khi bị thổi phồng về hiệu suất thô của khung thực thể. Tôi sẽ xem xét thêm vấn đề này và nghiên cứu thêm về các nguyên tắc của bộ nhớ đệm. Tuy nhiên, "lạnh so với ấm" theo EF vẫn là điều tôi muốn hiểu rõ hơn.
Peter

2
"Chỉ một thực tế này thường khiến các cuộc thảo luận về" dữ liệu lạnh so với dữ liệu ấm "trở nên không quan trọng so với vấn đề dữ liệu" cục bộ so với từ xa "." Không hẳn vậy. Nếu bạn không có nó được lưu trong bộ nhớ cache cục bộ (mà ban đầu bạn sẽ không làm như vậy), bạn sẽ vẫn cần phải nhấn EF và chịu đựng sự cố khởi tạo để tạo bộ nhớ cache của bạn. Cũng những nơi mà bộ nhớ cache của bạn chưa được khởi tạo, EF sẽ không được khởi tạo. Vì vậy, thêm một lớp bộ nhớ đệm có thể không giúp đỡ nếu vấn đề chỉ là thời gian EF khởi, nhưng nó sẽ thêm một lớp phức tạp ...
MikeJansen

8

Mẹo chung.

  • Thực hiện ghi nhật ký nghiêm ngặt bao gồm những gì được truy cậpyêu cầu thời gian .
  • Thực hiện các yêu cầu giả khi khởi tạo ứng dụng của bạn để làm ấm các yêu cầu khởi động rất chậm mà bạn nhận được từ bước trước.
  • Đừng bận tâm đến việc tối ưu hóa trừ khi đó là một vấn đề thực sự, hãy giao tiếp với người tiêu dùng ứng dụng và hỏi. Cảm thấy thoải mái khi có một vòng phản hồi liên tục nếu chỉ để tìm ra những gì cần tối ưu hóa .

Bây giờ để giải thích tại sao yêu cầu giả không phải là cách tiếp cận sai .

  • Ít phức tạp hơn - Bạn đang khởi động ứng dụng theo cách sẽ hoạt động bất kể những thay đổi trong khuôn khổ và bạn không cần phải tìm ra các API / nội bộ khung có thể phức tạp để làm điều đó theo đúng cách .
  • Phạm vi bảo hiểm lớn hơn - Bạn đang khởi động tất cả các lớp bộ nhớ đệm cùng một lúc liên quan đến yêu cầu chậm.

Để giải thích khi bộ nhớ cache bị "Lạnh".

Điều này xảy ra ở bất kỳ lớp nào trong khuôn khổ của bạn có áp dụng bộ nhớ cache, có một mô tả tốt ở đầu trang hiệu suất .

  • Khi nào bộ nhớ cache phải được xác thực sau một thay đổi tiềm ẩn khiến bộ nhớ cache cũ, thì đây có thể là thời gian chờ hoặc thông minh hơn (tức là thay đổi trong mục được lưu trong bộ nhớ cache).
  • Khi một mục trong bộ nhớ cache bị loại bỏ, thuật toán thực hiện việc này được mô tả trong phần "Thuật toán loại bỏ bộ nhớ cache" trong bài viết về hiệu suất mà bạn đã liên kết , nhưng trong ngắn hạn.
    • Bộ nhớ đệm LFRU (Ít thường xuyên nhất - được sử dụng gần đây) về số lần truy cập và độ tuổi với giới hạn 800 mục.

Những điều khác mà bạn đã đề cập, đặc biệt là biên dịch lại và khởi động lại IIS xóa một trong hai phần hoặc tất cả các bộ nhớ đệm trong bộ nhớ.


Đây là một câu trả lời hữu ích khác, được đánh giá cao.
Peter

3

Như bạn đã nêu, hãy sử dụng "lượt xem được tạo trước", đó thực sự là tất cả những gì bạn cần làm.

Trích từ liên kết của bạn : "Khi các lượt xem được tạo, chúng cũng được xác thực. Từ quan điểm hiệu suất, phần lớn chi phí tạo lượt xem thực sự là việc xác nhận các lượt xem"

Điều này có nghĩa là hiệu suất sẽ xảy ra khi bạn xây dựng cụm mô hình của mình. Sau đó, đối tượng ngữ cảnh của bạn sẽ bỏ qua "truy vấn nguội" và luôn phản hồi trong khoảng thời gian của vòng đời đối tượng ngữ cảnh cũng như các ngữ cảnh đối tượng mới tiếp theo.

Việc thực thi các truy vấn không liên quan sẽ không phục vụ mục đích nào khác ngoài việc tiêu tốn tài nguyên hệ thống.

Lối tắt ...

  1. Bỏ qua tất cả công việc bổ sung đó của các chế độ xem được tạo trước
  2. Tạo bối cảnh đối tượng của bạn
  3. Loại bỏ truy vấn không liên quan ngọt ngào đó
  4. Sau đó, chỉ cần giữ một tham chiếu đến ngữ cảnh đối tượng của bạn trong suốt quá trình của bạn (không được khuyến nghị).


2

Tôi không có kinh nghiệm trong khuôn khổ này. Nhưng trong các ngữ cảnh khác, ví dụ như Solr, các lần đọc hoàn toàn giả sẽ không được sử dụng nhiều trừ khi bạn có thể lưu vào bộ đệm toàn bộ DB (hoặc chỉ mục).

Một cách tiếp cận tốt hơn sẽ là ghi lại các truy vấn, trích xuất những truy vấn phổ biến nhất ra khỏi nhật ký và sử dụng chúng để làm nóng. Chỉ cần đảm bảo không ghi các truy vấn khởi động hoặc xóa chúng khỏi nhật ký trước khi tiếp tục.

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.