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.
Czy jesteś pewien, że nie czekają na połączeniach do basenu? Czy próbowałeś zwiększyć rozmiar puli połączeń? – Maess
@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. –
@Maess: Perfmon pokazuje tylko 11 połączeń logicznych i 11 połączeń użytkownika z instancją SQL, znacznie poniżej limitu puli połączeń. –