Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Problem Background

I have been thinking of ways to optimize the out of state storage of sessions within SQL server and a few I ran across are:

  • Disable session state on pages that do not require the session. Also, use read-only on pages that are not writing to the session.
  • In ASP.NET 4.0 use gzip compression option.
  • Try to keep the amount of data stored in the session to a minimum.
  • etc.

Right now, I have a single object (a class called SessionObject) stored in the session. The good news is, is that it is completely serializable.

Optimizing using protobuf-net

An additional way I thought might be a good way to optimize the storage of sessions would be to use protocol buffers (protobuf-net) serialization/deserialization instead of the standard BinaryFormatter. I understand I could have all of my objects inherit ISerializable, but I'd like to not create DTO's or clutter up my Domain layer with serialize/deserialize logic.

Any suggestions using protobuf-net with session state SQL server mode would be great!

share|improve this question
    
FYI, Gzip compression has nothing to do with sessions and session storage. If you're using SQL server for session state, then there should be almost no reason to use sessions for state since what you're storing in session is for the most part information that's in your database. So if you've still got state to save to session and you're following your point #3, what are you saving to session? So are SessionObject's properties? –  Shiv Kumar Feb 12 '11 at 6:37
    
Also, I'd didable session state at the application level (in the web.config file) and then turn it on or readonly for specific pages, that way you don't have to remember to turn it off. –  Shiv Kumar Feb 12 '11 at 6:41
    
@Shiv - I disagree strongly with both your points in the first comment; in the past I've seen many examples of using session-state for the transient data that cannot necessarily be constructed from the DB until formally saved, and I have personally written a gzip-based sesion-state provider, to help reduce network IO. It worked great, and significantly improved performance. –  Marc Gravell Feb 12 '11 at 8:17
    
@Marc, from the way he talked about gzip it (at least to me) didn't seem to imply use gzip to compress session state but rather use gzip for response compression and so I said it has nothing to do with Session state (something he's trying to optimize). Sure compressing session state should help with I/O bandwidth usage. As regards your other point. I did say, "for the most part" and I did ask for clarification. –  Shiv Kumar Feb 13 '11 at 3:49
    
Personally, I stay away from session state as far as possible. When I look at hung requests in IIS on extremely busy sites (300 requests/sec and more), I've found that all hung requests are hung is the "Acquire Session state" state. Doing away with session state (and using cookies and/or hidden fields) leaves no hung requests. Personally, I've never had the need to save (in session state) anything that can't be got from the database. Again, I'm not saying there is no need, but maybe re-thinking things could lead to having no need? Which was the point of my initial comment. –  Shiv Kumar Feb 13 '11 at 3:53

1 Answer 1

up vote 3 down vote accepted

If the existing session-state code uses BinaryFormatter, then you can cheat by getting protobuf-net to act as an internal proxy for BinaryFormatter, by implementing ISerializable on your root object only:

[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; }
    ...
}

Notes:

  • only the root object needs to do this; the any encapsulated objects will be handled automatically by protobuf-net
  • it will still ad d a little type metadata for the outermost object, but not much
  • you will need to decorate the members (and encapsulated types) accordingly (this is best done explicit per member; there is an implicit "figure it out yourself" mode, but this is brittle if you add new members)
  • this will break existing state; changing the serialization mechanism is fundamentally a breaking change

If you want to ditch the type metadata from the root object, you would have to implement your own state provider (I think there is an example on MSDN);

  • advantage: smaller output
  • advantage: no need to implement ISerializable on the root object
  • disadvantage: you need to maintain your own state provider ;p

(all the other points raised above still apply)

Note also that the effectiveness of protobuf-net here will depend a bit on what the data is that you are storing. It should be smaller, but if you have a lot of overwhelmingly large strings it won't be much smaller, as protobuf still uses UTF-8 for strings.

If you do have lots of strings, you might consider additionally using gzip - I wrote a state provider for my last employer that tried gzip, and stored whichever (original or gzip) was the smallest - obviously with a few checks, for example:

  • don't gzip if it is smaller than [some value]
  • short-circuit the gzip compression early if the gzip ever exceeds the original

The above can be used in combination with protobuf-net quite happily - and if you are writing a state-provider anyway you can drop the ISerializable etc for maximum performance.

A final option, if you really want would be fore me to add a "compression mode" property to [ProtoContract(..., CompressionMode = ...)]; which:

  • would only apply for the ISerializable usage (for technical reasons, it doesn't make sense to change the primary layout, but this scenario would be fine)
  • automatically applies gzip during serialization/deserialization of the above [perhaps with the same checks I mention above]
  • would mean you don't need to add your own state provider

However, this is something I'd only really want to apply for "v2" (I'm being pretty brutal about bugfix only in v1, so that I can keep things sane).

Let me know if that would be of interest.

share|improve this answer
    
I think this would be a great feature for v2! –  Nick Craver May 18 '11 at 19:18
    
@Nick - which specifically? –  Marc Gravell May 18 '11 at 19:39
    
the CompressionMode would handy when using ProtoBuf right next to the transport, since it would allow more control over which objects would get compression in the tree vs blindly doing many smaller value types and getting a lot less net-grain. –  Nick Craver May 18 '11 at 19:59

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.