Best Practices

Development Considerations

DEV-1: Break up large objects for best update performance

If you are storing large, complex objects (e.g., complex datasets) over about 500 KB, heavy update access to these objects can create both substantial networking overhead and significant CPU load to serialize and deserialize the objects. In addition, updates to any portion of these objects require that the entire object be rewritten. Consider breaking large objects up into multiple, smaller objects to increase performance and to allow concurrent access to different portions of the larger objects. This will maximize overall application performance and scalability.

DEV-2: Guidelines for using the deserialized client cache

The deserialized client cache, which is enabled by default, is a collection of object references retained by the SOSS client library to accelerate multiple retrieve accesses to an object stored in the SOSS service. Changes made by client code to an object held in the deserialized cache may cause the deserialized cache to return the changed object on a subsequent retrieve instead of the version that is stored in the SOSS service.

The deserialized cache is only intended to be used with either read-only access or in a locked retrieve/update usage pattern. In the retrieve/update usage pattern, an object stored in the SOSS service is retrieved and locked, optionally updated, and then unlocked (either by the update or by an explicit unlock access). This pattern enables multiple processes on the same or different servers to reliably update a shared object. No changes should be made to the retrieved object outside of the retrieve/update pair because these changes would not be propagated to the distributed cache.

Sometimes a client application may want to retrieve an object from SOSS, make some changes to the object, and then discard it after using it without persisting the changes to the SOSS service. This usage model can cause the deserialized cache to get out of sync with SOSS. If an application requires that changes be made to a retrieved object outside of the above read/update usage pattern, steps should be taken to avoid corrupting the deserialized cache. Either the cache should be disabled by setting the AllowDeserializedCaching property to false, or a deep copy of the retrieved object should be made with changes made only to this copy. Doing this will keep the locally cached object from getting out of sync with the authoritative object that is kept in the SOSS service.

DEV-3: Set ASPX pages to use "ReadOnly" session state whenever possible

When using session state in your ASP.NET application, setting the @Page directive’s EnableSessionState attribute to ReadOnly wherever possible can offer significant performance benefits, regardless of whether you’re using ScaleOut StateServer’s session state provider or one of ASP.NET’s built in providers.

The default value for the EnableSessionState attribute is true, which means that the entire session dictionary is read from the backing store at the beginning of every web request and then updated at the end of each request, regardless of whether session values were changed during the request. If you know that a page will never update session state, set the attribute to ReadOnly to prevent the updates from occurring. This will cut the number of round trips to the backing store in half and eliminate unnecessary updates.

Reducing unnecessary updates is useful when using any session provider, but it is especially effective when using ScaleOut StateServer’s provider because of ScaleOut StateServer’s client-side caching feature. If the session data isn’t constantly being updated in the ScaleOut StateServer’s distributed cache then the client-side cache will keep the most recently accessed session data inside of your ASP.NET process. This gives you a huge performance benefit by speeding up accesses and reducing network and deserialization overhead when sessions are being read from the distributed cache.

DEV-4: Set DataSet/DataTable’s RemotingFormat property to Binary

ADO.NET DataSets and DataTables should have their RemotingFormat property set to SerializationFormat.Binary prior to inserting or updating these ADO.NET objects in the ScaleOut StateServer cache. This will cause the serialization performed by ScaleOut StateServer’s APIs to be faster, and the result will often consume less memory in the ScaleOut StateServer service.