Entity Framework и параллелизм
фон
у меня есть приложение, которое получает периодические дампы данных (XML-файлы) и импортирует их в существующую базу данных с помощью Entity Framework 5 (Сначала код). Импорт происходит через EF5, а не через BULK INSERT или BCP, потому что должны применяться бизнес-правила, которые уже существуют в сущностях.
обработка, похоже, связана с процессором в самом приложении (чрезвычайно быстрая подсистема ввода-вывода с поддержкой кэша записи показывает почти ноль время ожидания диска на протяжении всего процесса, а SQL Server показывает не более 8% -10% времени процессора).
для повышения эффективности я построил конвейер с использованием потока данных TPL С компонентов на:
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()
Я вижу существенное увеличение производительности, делая это, но не могу получить процессор выше 60%.
анализ
подозревая какой-то конфликт ресурсов, я запустил процесс с помощью профилировщика VS2012 данные о конкуренции ресурсов (параллелизм) режим.
профилировщик показывает мне 52% конкуренции за ресурс с надписью ручки 2. Сверля, я вижу, что метод создания наибольшей конкуренции для ручки 2 is
System.Data.Entity.Internal.InternalContext.SaveChanges()
второе место, примерно на 40% больше споров, чем SaveChanges (), это
System.Data.Entity.DbSet`1.Add(!0)
вопросы
- как я могу понять, что ручки 2 действительно (например, часть TPL, часть EF)?
- вызывает ли EF дроссель для разделения экземпляров DbContext из отдельных потоков? Кажется, есть общий ресурс, за который они борются.
- есть ли что-нибудь, что я могу сделать, чтобы улучшить параллелизм в этом случае?
обновление
для рассматриваемого запуска максимальная степень параллелизма для задачи, вызывающей SaveChanges, установлена в 12 (я пробовал различные значения, включая Unbounded в предыдущих запусках).
обновление 2
команда EF Microsoft предоставила обратную связь. См. мой ответ для резюме.
1 ответов
ниже резюмируется мое взаимодействие с командой Entity Framework по этой проблеме. Я обновлю ответ, если будет доступна дополнительная информация
- проблема может быть воспроизведена в Microsoft.
- конфликт дескриптора связан с сетевым вводом-выводом (даже с SQL Server на localhost). В частности, существует конкуренция за буфер чтения для сетевого ввода-вывода в системе.Данные.файл DLL.
- команда EF теперь работает с командой SQL Connectivity для лучше понять проблему.
- пока нет указаний от Microsoft о том, как минимизировать влияние этого утверждения.
обновление
эта проблема теперь отслеживается на CodePlex:
http://entityframework.codeplex.com/workitem/636?PendingVoteId=636