[asp.net] Entity Framework를 “워밍업”하는 방법은 무엇입니까? 언제“추위”가됩니까?
아니요, 두 번째 질문에 대한 답은 겨울이 아닙니다.
머리말:
최근에 Entity Framework에 대해 많은 연구를 해왔고 계속해서 신경 쓰이는 것은 쿼리가 워밍업되지 않았을 때의 성능, 이른바 콜드 쿼리입니다.
나는 통해 갔다 성능 고려 사항 엔티티 프레임 워크 5.0에 대한 기사. 저자들은 웜 쿼리 와 콜드 쿼리 의 개념 과 그 차이점을 소개했는데, 그 존재를 알지 못한 채 저도 알아 차 렸습니다. 여기에서 내가 6 개월의 경험을 가지고 있다는 것을 언급 할 가치가있을 것입니다.
이제 성능 측면에서 프레임 워크를 더 잘 이해하려면 추가로 조사 할 수있는 주제가 무엇인지 알고 있습니다. 안타깝게도 인터넷에있는 대부분의 정보는 구식이거나 주관성이 너무 많아서 Warm vs Cold 쿼리 주제 에 대한 추가 정보를 찾을 수 없습니다 .
기본적으로 지금까지 제가 알아 차린 것은 재 컴파일하거나 히트를 재활용해야 할 때마다 초기 쿼리가 매우 느려진다는 것입니다. 후속 데이터 읽기는 예상대로 빠릅니다 ( 주관적 ).
우리는 Windows Server 2012, IIS8 및 SQL Server 2012로 마이그레이션 할 예정이며 주니어로서 실제로 나머지 전에 테스트 할 기회를 얻었습니다. 첫 번째 요청에 대해 내 애플리케이션을 준비 할 준비 모듈을 도입 한 것이 매우 기쁩니다. 그러나 Entity Framework를 워밍업하는 방법을 잘 모르겠습니다.
내가 이미 알고있는 것은 가치가 있습니다.
- 제안 된대로 미리 내보기를 생성하십시오.
- 결국 내 모델을 별도의 어셈블리로 옮깁니다.
내가 생각하는 것은 상식적으로 진행함으로써 아마도 잘못된 접근 방식 일 것입니다 .
- 모델을 워밍업, 생성 및 검증하기 위해 애플리케이션 시작시 더미 데이터 읽기를 수행합니다.
질문 :
- 언제든지 내 Entity Framework에서 고 가용성을 유지하는 가장 좋은 방법은 무엇입니까?
- 어떤 경우에 Entity Framework가 다시 “콜드”됩니까? (재 컴파일, 재활용, IIS 재시작 등)
답변
- 언제든지 내 Entity Framework에서 고 가용성을 유지하는 가장 좋은 방법은 무엇입니까?
미리 생성 된 뷰와 정적 컴파일 쿼리를 혼합하여 사용할 수 있습니다.
정적 CompiledQuery 는 빠르고 쉽게 작성할 수 있으며 성능 향상에 도움이되기 때문에 좋습니다. 그러나 EF5에서는 EF가 쿼리 자체를 자동 컴파일하므로 모든 쿼리를 컴파일 할 필요가 없습니다. 유일한 문제는 캐시가 스윕 될 때 이러한 쿼리가 손실 될 수 있다는 것입니다. 따라서 매우 드물지만 비용이 많이 드는 쿼리에 대한 자체 컴파일 된 쿼리에 대한 참조를 유지하려고합니다. 이러한 쿼리를 정적 클래스에 넣으면 처음 필요할 때 컴파일됩니다. 일부 쿼리에는 너무 늦을 수 있으므로 응용 프로그램 시작 중에 이러한 쿼리를 강제로 컴파일 할 수 있습니다.
뷰를 미리 생성하는 것도 언급했듯이 다른 가능성입니다. 특히 컴파일하는 데 매우 오래 걸리고 변경되지 않는 쿼리의 경우. 이렇게하면 런타임에서 컴파일 시간으로 성능 오버 헤드를 이동할 수 있습니다. 또한 이로 인해 지연이 발생하지 않습니다. 그러나 물론이 변경 사항은 데이터베이스로 전달되므로 처리하기가 쉽지 않습니다. 코드가 더 유연합니다.
TPT 상속을 많이 사용하지 마십시오 (EF의 일반적인 성능 문제). 상속 계층을 너무 깊거나 너무 넓게 구축하지 마십시오. 일부 클래스에 고유 한 2-3 개의 속성 만 자체 유형을 요구하기에 충분하지 않을 수 있지만 기존 유형에 대한 선택적 (널 가능) 속성으로 처리 할 수 있습니다.
오랫동안 단일 컨텍스트를 유지하지 마십시오. 각 컨텍스트 인스턴스에는 자체의 첫 번째 레벨 캐시가있어 더 커질수록 성능이 저하됩니다. 컨텍스트 생성은 저렴하지만 컨텍스트의 캐시 된 엔티티 내부의 상태 관리는 비용이 많이들 수 있습니다. 다른 캐시 (쿼리 계획 및 메타 데이터)는 컨텍스트간에 공유되며 AppDomain과 함께 죽습니다.
대체로 컨텍스트를 자주 할당하고 짧은 시간 동안 만 사용하고, 애플리케이션을 빠르게 시작하고, 거의 사용하지 않는 쿼리를 컴파일하고, 성능이 중요하고 자주 사용되는 쿼리에 대해 미리 생성 된 뷰를 제공하도록해야합니다.
- 어떤 경우에 Entity Framework가 다시 “콜드”됩니까? (재 컴파일, 재활용, IIS 재시작 등)
기본적으로 AppDomain을 잃을 때마다. IIS는 29 시간 마다 다시 시작 하므로 인스턴스가 있다는 것을 보장 할 수 없습니다. 또한 활동이 없으면 AppDomain도 종료됩니다. 다시 빨리 올라와야합니다. 비동기 적으로 일부 초기화를 수행 할 수 있습니다 (다중 스레딩 문제에주의하십시오). AppDomain이 죽지 않도록 요청이 없을 때 애플리케이션에서 더미 페이지를 호출하는 예약 된 작업을 사용할 수 있지만 결국 그렇게 될 것입니다.
또한 구성 파일을 변경하거나 어셈블리를 변경할 때 다시 시작될 것이라고 가정합니다.
답변
모든 호출에서 최대 성능을 찾고 있다면 아키텍처를 신중하게 고려해야합니다. 예를 들어, 모든 요청에 데이터베이스 호출을 사용하는 대신 애플리케이션이로드 될 때 자주 사용되는 조회를 서버 RAM에 사전 캐시하는 것이 합리적 일 수 있습니다. 이 기술은 일반적으로 사용되는 데이터에 대한 최소 애플리케이션 응답 시간을 보장합니다. 그러나 동시성 문제를 방지하려면 캐시 된 데이터에 영향을주는 변경 사항이있을 때마다 제대로 작동하는 만료 정책을 사용하거나 항상 캐시를 지워야합니다.
일반적으로 로컬에 캐시 된 정보가 오래되거나 트랜잭션이 필요한 경우에만 IO 기반 데이터 요청을 요구하도록 분산 아키텍처를 설계해야합니다. 모든 “유선”데이터 요청은 일반적으로 로컬 메모리 캐시 검색보다 검색하는 데 10 ~ 1000 배 더 오래 걸립니다. 이 한 가지 사실만으로도 “콜드 vs. 웜 데이터”에 대한 논의가 “로컬 vs. 원격”데이터 문제에 비해 중요하지 않게 만드는 경우가 많습니다.
답변
일반적인 팁.
- 액세스 된 항목 및 요청 시간을 포함하여 엄격한 로깅을 수행 합니다 .
- 애플리케이션을 초기화 할 때 더미 요청을 수행 하여 이전 단계에서 선택한 매우 느린 요청 을 웜 부팅 합니다.
- 실제 문제가 아니라면 최적화에 신경 쓰지 말고 애플리케이션 소비자와 소통하고 물어보십시오. 최적화가 필요한 항목 을 파악하는 경우에만 지속적인 피드백 루프를 편안하게 사용하십시오 .
이제 더미 요청이 잘못된 접근 방식 이 아닌 이유를 설명하겠습니다 .
- 덜 복잡함 -프레임 워크의 변경에 관계없이 작동하는 방식으로 애플리케이션을 워밍업하고 있으며 올바른 방식으로 수행하기 위해 펑키 한 API / 프레임 워크 내부를 파악할 필요가 없습니다 .
- 더 넓은 범위 -느린 요청과 관련된 모든 캐싱 계층을 한 번에 워밍업합니다.
캐시가 “콜드”되는시기를 설명합니다.
이는 캐시를 적용하는 프레임 워크의 모든 계층에서 발생하며 성능 페이지 상단에 좋은 설명이 있습니다.
- 캐시를 부실하게 만드는 잠재적 인 변경 후 캐시의 유효성을 검사해야하는 경우 이는 시간 초과이거나보다 지능적 일 수 있습니다 (즉, 캐시 된 항목의 변경).
- 캐시 항목이 제거 될 때이를 수행하는 알고리즘은 링크 한 성능 문서의 “캐시 제거 알고리즘”섹션에 설명되어 있지만 간단히 설명합니다.
- LFRU (가장 자주 사용되지 않음-최근에 사용됨)는 적중 횟수 및 수명에 대해 800 개 항목으로 제한됩니다.
언급 한 다른 사항, 특히 IIS를 다시 컴파일하고 다시 시작하면 메모리 캐시의 일부 또는 전체가 지워집니다.
답변
이미 언급했듯이 “미리 생성 된 뷰”를 사용하는 것이 정말 필요한 모든 것입니다.
링크 에서 추출 : “보기가 생성되면 유효성도 확인됩니다. 성능 관점에서보기 생성 비용의 대부분은 실제로보기의 유효성 확인입니다.”
즉, 모델 어셈블리를 만들 때 성능 저하가 발생합니다. 그러면 컨텍스트 개체가 “콜드 쿼리”를 건너 뛰고 컨텍스트 개체 수명주기 및 후속 새 개체 컨텍스트 동안 응답을 유지합니다.
관련없는 쿼리를 실행하는 것은 시스템 리소스를 소비하는 것 외에 다른 용도로 사용되지 않습니다.
바로 가기 …
- 미리 생성 된 뷰의 모든 추가 작업을 건너 뜁니다.
- 개체 컨텍스트 만들기
- 그 달콤한 무관 한 쿼리를 실행
- 그런 다음 프로세스 기간 동안 개체 컨텍스트에 대한 참조를 유지하십시오 (권장되지 않음).
답변
이 프레임 워크에 대한 경험이 없습니다. 그러나 Solr과 같은 다른 컨텍스트에서는 전체 DB (또는 인덱스)를 캐시 할 수없는 경우 완전 더미 읽기는 그다지 유용하지 않습니다.
더 나은 접근 방법은 쿼리를 기록하고 로그에서 가장 일반적인 쿼리를 추출하여 워밍업하는 데 사용하는 것입니다. 계속하기 전에 워밍업 쿼리를 기록하거나 로그에서 제거하지 않도록하십시오.