The use of NCache spans a variety of use cases, starting from a simple key-value store to advanced SQL searching and Pub/Sub. Client applications include, but are not limited to, console applications, windows services, web applications, and web services. Client libraries (SDK) include .NET, Java, and NodeJS. Moreover, support for Python and Scala is also provided. Using the relevant SDK, client applications can connect with one or more caches.
Google Protobuf as a data exchange format: The client communicates with the cache over a persistent TCP socket. NCache client uses Google Protocol buffer (Protobuf) as a protocol to communicate with the cache server. The use of Protobuf provides flexibility to older client versions of NCache, to communicate with new cache server versions.
Request-Response based parallel request execution: NCache client supports multi-threading. Those applications can make parallel requests to the cache. NCache follows the RequestId-based request-response protocol in client-server communications, where every request is assigned a unique RequestId. Despite having a single TCP connection between the cache client and a cache server, the client can send multiple requests with their unique RequestIds to the cache server without waiting for the response of already sent requests. So, each request is truly independent. NCache server also supports parallel request execution. This architecture enables applications to execute multiple parallel operations from the client to cache servers without operations waiting for each other, thus, providing maximum performance and scalability.
Request Pipelining: Pipelining refers to combining and sending multiple requests in a single socket (I/O) operation. Whenever applications perform I/O operations, user-to-kernel mode switching occurs, which is a costly operation. Pipelining avoids this cost by performing the same task in a reduced number of I/O operations. Pipelining increases application performance manyfold. NCache supports pipelining on both the client and server end.
Cache topology awareness: NCache client is cache topology-aware. When a cache client connects to the first cache server, it retrieves the cache metadata, including its topology. How a client should establish connectivity with cache servers and how client operations should be executed, depends on the underlying topology of the cache. For example, data is distributed among different cache servers in Partitioned and Partition-Replica topologies. Therefore, the client establishes a TCP connection with each server in the cache cluster and fetches the latest data distribution maps. The client directly performs read and write operations against the partition containing the concerned data. Similarly, each server in the Replicated topology contains the same set of data. Thus, the client only connects with a single cache server.
Handling connection failures in a seamless fashion: The NCache client maintains a persistent connection with the cache server(s). If this connection breaks due to network glitches, the NCache client is equipped with a background connection re-establishment mechanism. This mechanism automatically establishes connectivity with the failed server, as soon as network connectivity is resumed between the client and server. And all of this happens seamlessly, without client application intervention.
Data Serialization: Application data goes through the serialization process before going to the cache server. NCache supports both Binary and JSON serialization. You can choose either of the serialization formats at the time of configuring the cache. The cache client fetches the serialization format from the cache server upon connecting to the cache. Then it serializes the application data according to the serialization format.
Data Encryption: Encrypting of application data is an optional feature that you can enable. If encryption is configured, the client encrypts application data after it has been serialized. The client fetches the encryption-related configuration from the cache server upon connecting to the cache.
Data Compression: Compression of the application data can help reduce cache size if the data is really large. Data is first serialized, then encrypted (if encryption is enabled), and finally compressed by the cache client before being dispatched to the cache. The cache client fetches the compression-related configuration from the cache server upon connecting to the cache.
Connecting With the Cache
The cache client needs the server information to connect with the cache. Server information can be either provided through the client configuration file (client.ncconf ) or through CacheConnectionOptions. The client iterates through the provided cache server list and tries to connect with the cache running on the server. If the cache instance is not running on a given server, it moves to the next server provided in the list. Client connection usually goes through the following steps:
The client first establishes a TCP connection with NCache service over port 9800.
The client then makes a request for the complete list of configured cache servers. This way, it has an updated list of the cache servers.
The client then sends the cache an initialization request to the server, which includes the cache name and security credentials in case cache security is enabled. Every cache runs in a separate process. If you have .NET Framework based installation of NCache on the server end, then the service seamlessly hands over client connection to the cache process, and the client successfully connects with the cache. In .NET Core or .NET 6 and higher installations, the service shares the port information with the client on which the cache is listening for connections. The client then establishes a direct connection with the cache process and sends an initialization request.
NCache automatically configures the Firewall to open all the required ports on Windows. However, you need to open NCache ports on Linux by Configuring Firewall.
If the client is connecting with a Replicated cache and client load balancing is enabled, then the client asks for a server that has the least number of clients connected to it. It then connects with the least loaded server.
If the client is connecting with a Partitioned or a Partition-Replica cache, then it requests the distribution maps for the servers. Upon receiving the map(s), it establishes connections with the cache servers present in the distribution map.
The client also requests different cache configurations like