ASP.NET SessionState режим сериализации SQLServer с protobuf-net - PullRequest
3 голосов
/ 12 февраля 2011

Проблемный фон

Я думал о способах оптимизации хранения сеансов вне состояния в SQL-сервере, и вот некоторые из них, с которыми я столкнулся:

  • Отключить состояние сеанса на страницах, которые не требуют сеанса. Также используйте доступ только для чтения на страницах, которые не записываются в сеанс.
  • В ASP.NET 4.0 используйте параметр сжатия gzip.
  • Постарайтесь свести к минимуму количество данных, хранящихся в сеансе.
  • и т.д.

Прямо сейчас у меня есть один объект (класс с именем SessionObject), хранящийся в сеансе. Хорошая новость в том, что он полностью сериализуем.

Оптимизация с использованием protobuf-net

Еще один способ, который, как я думал, может быть хорошим способом оптимизации хранилища сессий, - это использование сериализации / десериализации буферов протоколов (protobuf-net) вместо стандартного BinaryFormatter. Я понимаю, что все мои объекты могли бы наследовать ISerializable, но я бы не хотел создавать DTO или загромождать мой уровень Domain с помощью логики сериализации / десериализации.

Любые предложения по использованию protobuf-net с режимом состояния сервера SQL сеанса были бы хорошими!

1 Ответ

5 голосов
/ 12 февраля 2011

Если в существующем коде состояния сеанса используется BinaryFormatter, вы можете обмануть, заставив protobuf-net выступать в качестве внутреннего прокси для BinaryFormatter, реализовав ISerializable только для вашего корневого объекта :

[ProtoContract]
class SessionObject : ISerializable {
    public SessionObject() { }
    protected SessionObject(SerializationInfo info, StreamingContext context) {
        Serializer.Merge(info, this);
    }
    void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
        Serializer.Serialize(info, this);
    }

    [ProtoMember(1)]
    public string Foo { get; set; }
    ...
}

Примечания:

  • для этого нужен только корневой объект;любые инкапсулированные объекты будут обрабатываться автоматически с помощью protobuf-net
  • , который по-прежнему будет содержать метаданные типа da small для самого внешнего объекта, но не так много
  • , которые вам понадобятсясоответственно декорировать элементы (и инкапсулированные типы) (лучше всего это делать явно для каждого члена; существует неявный режим «разберись сам», но это будет хрупко, если вы добавите новых членов)
  • это будет сломать существующее состояние ;изменение механизма сериализации является принципиально критическим изменением

Если вы хотите исключить метаданные типа из объекта root , вам придется реализовать свой собственный поставщик состояний (я думаю, что тамявляется примером для MSDN);

  • преимущество: меньший вывод
  • преимущество: не нужно реализовывать ISerializable для корневого объекта
  • недостаток: вам нужноподдержите своего собственного провайдера состояний; p

(все остальные пункты, поднятые выше, все еще применяются)

Обратите внимание также, что эффективность protobuf-net здесь будет немного зависеть от того, какие данныеэто то, что вы хранитеОн должен быть меньше, но если у вас много огромных строк, он не будет на много меньше, так как protobuf по-прежнему использует UTF-8 для строк.

Если вы у есть много строк, вы можете дополнительно рассмотреть возможность использования gzip - я написал провайдера состояний для моего последнего работодателя, который пробовал gzip, и хранил то, что было меньше (оригинальное или gzip) - очевидно, с несколькими проверками, например:

  • не используйте gzip, если оно меньше, чем [какое-либо значение]
  • закоротите сжатие gzip на ранней стадии, если gzip превысит исходное

Вышесказанное можно использовать в сочетании с protobuf-net довольно удачно - и если вы пишете провайдеру состояния в любом случае , вы можете отказаться от ISerializable и т. Д. Для максимальной производительности.

И последний вариант, , если вы действительно хотите, чтобы означало, что мне нужно добавить свойство "режима сжатия" к [ProtoContract(..., CompressionMode = ...)];который:

  • будет применяться только для использования ISerializable (по техническим причинам нет смысла менять основной макет, но этот сценарий будет приемлемым)
  • автоматически применяет gzip во время сериализации / десериализации вышеупомянутого [возможно, с теми же проверками, о которых я упоминал выше)
  • означало бы, что вам не нужно добавлять свой собственный поставщик состояний

Однако,это то, что я действительно хотел бы подать заявку на "v2" (я довольно жестоко отношусь к исправлению ошибок только в v1, так что я могу держать все в порядке).

Дайте мне знать, если это будетинтерес.

...