As a developer, you must have struggled to accelerate the communication between the client and server at some point. Network overheads, delays and latency have always been of major concerns and it all comes down to one single question – How can we speed up the requests? Tons of solutions are found over the time but the answer we are focusing on here is Compression and Compact Serialization. Lucky for you, NCache provides efficient compression and dynamic compact serialization techniques (FYI, they are both different things). In this blog, we will see the need of both and how they can be used.
Dynamic Compact Serialization
NCache provides support for native .NET serialization format, however, it also provides its own serialization framework called compact serialization. Compact serialization is also binary serialization but NCache provides a lot more flexibility with this serialization framework. Compact serialization does not reduce the size of the entire data, it instead only reduces the size of the data that is travelled over the network. It helps you achieve better functionality as the network trips are faster and the cost is decreased.
Now let us look at the benefits of dynamic compact serialization and how it is more flexible than the native .NET Serialization:
Compact Data Size
In NCache, binary serialized data is compact in size. When serialized, these objects sometimes become ten times smaller than their actual data sizes. The smaller the size, the faster the data travels over the network, hence amplified performance. Besides, when data is more compact, it takes up lesser space on the cache server making it memory efficient too.
Requires no Code change
To make your data compact serialized, there is no change in code required. All you have to do is, select the serializable data using management tools (NCache Web Manager or NCache PowerShell tools). NCache internally handles all the serialization of the data hence, no change in code is required.
Selective Serialization
Selective serialization means that the user has all the control over which data needs to be serialized and which data needs to be marked non-serialized. Within a class, you can select attributes to be serialized, for example, let us suppose that you want to keep the data base connection objects as non-serialized. You can simply serialize other attributes and keep the desired data non-serialized.
In order to get a fine-grained control over which data to serialize, ICompactSerializable interface is implemented. This gives you a major control on the data and selective serialization. The custom class needs the serialize/deserialize methods that are called by NCache to serialize/deserialize the objects. Look at the code example below to see how ICompactSerializable interface is implemented:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
public class Customers : ICompactSerializable { private string _name; private int _id; private string _company; public Customers() { } public Customers(string customerName, int customerID, string companyName) { _name = customerName; _id = customerID; _company = companyName; } #region ICompactSerializable Members public void Deserialize(CompactReader reader) { _name = reader.ReadObject() as string; _id = reader.ReadInt32(); _company = reader.ReadObject() as string; } public void Serialize(CompactWriter writer){ writer.WriteObject(_name); writer.Write(_id); writer.Write(_company); } #endregion } |
NCache also allows registering generic classes for compact serialization. There are two ways to register generic classes i.e. either through the NCache Web Manager or through the IGenericTypeProvider interface.
Step 1: Through NCache Web Manager
You can register generic classes using NCache Web Manager as shown below:
Step 2: Through IGenericTypeProvider
To implement this, the user needs to implement GetGenericTypes method and return the desired generic types as an array.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public class CustomerPurchaseDetails<T, K, V> { // implement logic } public class CustomerPurchaseImpl : IGenericTypeProvider { Type[] types = new Type[6]; Type[] IGenericTypeProvider.GetGenericTypes() { types[0] = typeof(Dictionary<string, Customer>); types[1] = typeof(List); types[2] = typeof(CustomerPurchaseDetails<Order, Product, Customer>); types[3] = typeof(CustomerPurchaseDetails<Order, Product, int>); types[4] = typeof(CustomerPurchaseDetails<Order, string, byte>); types[5] = typeof(CustomerPurchaseDetails<string, Customer, bool>); return types; } public bool CheckIfSerializable(Type type, FieldInfo fieldInfo) { // implement logic } } |
After this, deploy this class assembly to NCache Web Manager. NCache Web Manager will register all types populated in Type array.
Compact Serialization Docs Register Generic Classes Register Non-Generic Classes
Compression
Another effective technique provided by NCache is data compression where data in compressed form is added in the cache. The greatest advantage is that compressed data takes up lesser space than the uncompressed data and saves you a lot of memory. It reduces the network cost of your read/write operations. So, what you save is network cost, time and memory efficiently by simply using compression.
NCache uses the GZip compression to compress the data. You decide a certain threshold value and for enabled compression, all the items exceeding the threshold are compressed. We compared the compressed and uncompressed data and the memory usage by each. You can see the results in the graph below. The blue line shows the memory consumption with compressed data and the orange one shows the size of the cache with uncompressed data:
Compression usually occurs on the client side as well as the server side given that compression is enabled on both the server and the client side.
- Client-side compression is applied on all the items that are requested by the client from the server. The server compresses the data and sends it to the client and the client decompresses it on receiving the compressed data. Similarly, for items crossing the threshold, sent by the client to the remote server, the data is sent in the compressed form.
- Server-side compression occurs for all the items exceeding the threshold and are loaded from the data source by the server-side features such as cache startup loader. These items are then compressed at NCache servers after receiving them from the data source.
Compression in NCache Docs Enable/Disable Compression
In order to use compression, all you have to do is enable compression and there are two effective ways to do so.
Method 1: Using NCahe Web Manager
The gif below shows you how to enable compression using NCache Web Manager:
Method 2: Using Configuration
A configuration file installed in NCache install directory, named config.ncconf contains a tag which enables and disables compression for you. Let me show you how:
1 |
<compression enabled="true" threshold="500kb"/> |
The enabled tag is set true for enabling compression and false in case you want to disable compression. It also provides you the threshold tag and the data above the provided value is compressed only.
Conclusion
In conclusion, compression and compact serialization are very effective techniques for enhanced performance of your application. It is also very easy to enable these features using NCache management tools. NCache helps you achieve all this with just no code change. Please refer to NCache documentation to check out other cool NCache features.