Синхронизация таблицы с записью 2 Мб с MS Sync Framework и IIS-сервисом WCF занимает 10 минут - PullRequest
1 голос
/ 08 декабря 2011

У меня служба WCF, размещенная на IIS, работает на одном сервере, а служба Windows работает на другом.Служба Windows действует как ведомое устройство и синхронизирует базы данных на каждом из серверов, подключаясь к службе WCF, размещенной на IIS, с использованием MS Sync Framework.

Я храню содержимое файлов в одном изтаблицы, которые синхронизируются, и записи могут стать немного большими (~ 10 МБ на запись).Моя проблема в том, что когда я пытаюсь синхронизировать эти записи, требуется много времени для синхронизации.

Синхронизируемая таблица:

[Id] [int] IDENTITY(1,1) NOT NULL,
[Client] [uniqueidentifier] NOT NULL,
[Date] [datetime] NOT NULL,
[Content] [nvarchar](max) NOT NULL,

Я синхронизировал синхронизацию с 1 записью с разнымиРазмеры содержимого следующие:

  • 500 КБ - 1 мин 20 с
  • 1 МБ - 3 мин
  • 1,5 МБ - 6 мин 30 с
  • 2 МБ - 9 мин 50 с

(Время было приблизительно одинаковым при отладке в Visual Studio с обоими службами и обеими базами данных локально)

У кого-нибудь есть объяснение, почему это занимает так много времени?

Конфигурация службы WCF:

<configuration>
  <system.web>
    <httpRuntime maxRequestLength="2147483647" />
    <compilation debug="true" targetFramework="4.0"/>
  </system.web>

  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding closeTimeout="00:20:00" openTimeout="00:20:00" receiveTimeout="00:20:00" sendTimeout="00:20:00"
        allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
        maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
        messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
        useDefaultWebProxy="true">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None"
            realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>

    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true" httpHelpPageEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
  </system.serviceModel>

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

</configuration>

Конфигурация службы Windows:

<configuration>

  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_ISyncServiceContract" closeTimeout="00:20:00" openTimeout="00:20:00" receiveTimeout="00:20:00" sendTimeout="00:20:00"
             allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
             maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
             messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
            <message clientCredentialType="UserName" algorithmSuite="Default"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>

    <client>
      <endpoint address="http://localhost:60000/SyncService.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ISyncServiceContract" contract="SyncServiceReference.ISyncServiceContract" name="BasicHttpBinding_ISyncServiceContract"/>
    </client>
  </system.serviceModel>

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>

</configuration>

Ответы [ 2 ]

1 голос
/ 15 декабря 2011

Кажется, проблема в поле nvarchar(max), когда оно содержит слишком много данных.Я изменил поле на varbinary(max), и теперь синхронизация тех же данных заканчивается за долю времени, использованного ранее.

0 голосов
/ 09 декабря 2011

Если вы используете клиент / серверные библиотеки, то связь в конечном итоге становится набором данных, который сериализуется в XML (технически не «сериализуется», но в итоге получается примерно одинаковым). Итак, вы начинаете с набора данных, который имеет репутацию раздутого. Кроме того, набор данных будет хранить данные до и после каждой изменяемой строки, что удваивает объем данных. Затем добавьте сериализацию в XML, которая добавляет дополнительные издержки. Затем эта полезная нагрузка включается в вызовы веб-служб, что добавляет дополнительные накладные расходы. В общем, вы смотрите на передачу очень большого объема данных по проводам. Промежуток времени, который вы видите, это просто количество времени, которое требуется для передачи всех этих данных.

Это выходит за рамки вашего вопроса, но некоторые рекомендации для решения этой проблемы:

  • Посмотрите на сжатие данных при их передаче по проводам. Есть несколько проектов wcf + gzip.
  • Возможно, вы захотите переместить файлы из базы данных в файловую систему и использовать отдельный сервис WCF для обработки передачи файлов.
...