我一直在考虑如何优化SQL服务器中会话的状态外存储,以及我遇到的一些会话:
现在,我在会话中存储了一个对象(一个名为SessionObject的类)。好消息是,它是完全可序列化的。
我认为可能是优化会话存储的一种好方法是使用协议缓冲区(protobuf-net)序列化/反序列化而不是标准的BinaryFormatter。我知道我的所有对象都可以继承ISerializable,但我不想创建DTO,或者使用序列化/反序列化逻辑来混乱我的Domain层。
使用带有会话状态SQL服务器模式的protobuf-net的任何建议都会很棒!
答案 0 :(得分:5)
如果现有会话状态代码使用BinaryFormatter
,那么您可以通过实施BinaryFormatter
来使protobuf-net充当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; }
...
}
注意:
如果您想从 root 对象中删除类型元数据,则必须实现自己的状态提供程序(我认为MSDN上有一个示例);
ISerializable
(上述所有其他要点仍然适用)
另请注意,protobuf-net的有效性将取决于您存储的数据。它应该更小,但是如果你有很多非常大的字符串,它将不会太多更小,因为protobuf仍然使用UTF-8作为字符串。
如果你做有很多字符串,你可以考虑另外使用gzip - 我为我上一个试过gzip的雇主写了一个状态提供者,并且存储了最小的(原始或gzip) - 显然有一些检查,例如:
以上可以非常愉快地与protobuf-net一起使用组合 - 如果你正在编写状态提供者 ,你可以删除ISerializable
等,以获得最佳性能。
最后一个选项,如果你真的想要,我将向[ProtoContract(..., CompressionMode = ...)]
添加“压缩模式”属性;其中:
ISerializable
用法(由于技术原因,更改主要布局没有意义,但这种情况会没问题)然而,这是我只想申请“v2”的东西(我只是在v1中对bugfix非常野蛮,所以我可以保持理智)。
如果有兴趣,请告诉我。