14

TłoEntity Framework i Równoległość

Mam aplikacji, która odbiera okresowe wysypisk dane (pliki XML) i importuje je do istniejącej bazy danych przy użyciu Entity Framework 5 (Code First). Import odbywa się za pośrednictwem EF5, a nie w BULK INSERT lub BCP, ponieważ reguły biznesowe, które już istnieją w jednostkach, muszą zostać zastosowane.

Przetwarzanie wydaje się być związane z procesorem w samej aplikacji (bardzo szybki, włączony podsystem dysku IO z włączonym dyskiem wyświetla prawie zerowy czas oczekiwania na dysk w całym procesie, a SQL Server pokazuje nie więcej niż 8% -10% czasu procesora).

Aby poprawić wydajność, zbudowałem pipeline using TPL Dataflow z komponentów:

Read & Parse XML file 
     | 
     V 
Create entities from XML Node 
     | 
     V 
Batch entities (BatchBlock, currently n=200) 
     | 
     V 
Create new DbContext/insert batched entities/ctx.SaveChanges() 

widzę znaczny wzrost wydajności w ten sposób, ale nie może dostać CPU powyżej około 60%.

Analiza

Podejrzewając pewnego rodzaju rywalizacji zasobów, wpadłem proces używając dane rywalizacją Resource VS2012 Profiler'S (współbieżności) Tryb.

Profilator pokazuje 52% rywalizacji o zasoby oznaczone jako Uchwyt 2. Wiercenia, widzę, że metoda tworzenia najwięcej twierdzenie dla Uchwyt 2 jest

System.Data.Entity.Internal.InternalContext.SaveChanges() 

Drugie miejsce, w około 40%, jak wiele twierdzeń jak SaveChanges(), jest

System.Data.Entity.DbSet`1.Add(!0) 

pytania

  • Jak mogę dowiedzieć się, co Uchwyt 2 naprawdę jest (e .sol. część TPL, część EF)?
  • Czy EF zatrzymuje połączenia, aby oddzielić wystąpienia DbContext od oddzielnych wątków? Wygląda na to, że istnieje wspólny zasób, o który walczą.
  • Czy jest coś, co mogę zrobić, aby poprawić równoległość w tym przypadku?

UPDATE

Dla biegu w pytaniu maksymalnego stopnia równoległości dla zadania, które nazywa SaveChanges jest ustawiona na 12 (próbowałem różne wartości w tym nieokreślonej długości w poprzednich seriach).

UPDATE 2

zespół Microsoftu EF dostarczył informacji zwrotnych. Zobacz moją odpowiedź na podsumowanie.

+1

Czy jesteś pewien, że nie czekają na połączeniach do basenu? Czy próbowałeś zwiększyć rozmiar puli połączeń? – Maess

+0

@Moess: Dla danego biegu ustawiłem maksymalny stopień równoległości na 12. Jeśli dobrze rozumiem, domyślny maksymalny rozmiar puli połączeń to 100. Mimo to spróbuję jawnie ustawić ją wyżej. –

+0

@Maess: Perfmon pokazuje tylko 11 połączeń logicznych i 11 połączeń użytkownika z instancją SQL, znacznie poniżej limitu puli połączeń. –

Odpowiedz

5

Poniżej znajduje się podsumowanie mojej interakcji z zespołem Entity Framework w tym zakresie.Zaktualizuję odpowiedź, jeśli pojawi się więcej informacji:

  • Problem można odtworzyć w firmie Microsoft.
  • Twierdzenie o uchwytach jest powiązane z operacjami wejścia/wyjścia sieci (nawet z serwerem SQL na lokalnym hoście). Konkretnie, istnieje spór o bufor odczytu dla operacji we/wy sieci w pliku System.Data.dll.
  • Zespół EF pracuje obecnie z zespołem komunikacji SQL, aby lepiej zrozumieć problem.
  • Nie ma jak dotąd wskazówek od Microsoft dotyczących tego, jak zminimalizować wpływ tego sporu.

UPDATE

Kwestia ta jest obecnie śledzone na CodePlex:

http://entityframework.codeplex.com/workitem/636?PendingVoteId=636

+0

Wielkie dzięki Eric. Jestem dość zainteresowany tym, że mam podobny scenariusz. Czy mamy na to problem w serwisie connect.microsoft.com, abyśmy mogli prześledzić jego postęp? – Dodd

+0

@Dodd: Jest śledzony na Codeplex, ponieważ EF jest teraz open source (ale wciąż pracował przez zespół w Microsoft). Dodano link. –