AppFabric caching migration guide to Memurai

The Memurai team on MigrationJune 15, 2020 12 min read

Golden Gate Bridge

Caching and in-memory databases are essential for serving high-performance applications and services. If you’re currently running Microsoft AppFabric Caching 1.1 for Windows Server, you’re now well into the extended support period, which means you can no longer receive new features or get non-security fixes without an extended support agreement. And even extended support will come to an end in 2022. What are your options?

1. Introduction

Microsoft AppFabric Caching is no longer being developed. For developers running AppFabric Caching in production environments that need to guarantee reliability and stability for their users, you should consider migrating to an alternative that provides on-going support.

Memurai is an alternative in-memory cache and datastore that runs natively on Windows and integrates seamlessly into Windows best practices, tools, and workflows. Which means you can make the most of your existing investment in Windows infrastructure and know-how. Memurai is fully compatible with Redis 5, and supports all the features that make Redis the most popular NoSQL datastore. And you can safely deploy Memurai in enterprise environments because it’s a fully-supported platform.

No matter how you’re currently running AppFabric Caching, pretty much every use case is supported by Memurai and many scenarios actually work better thanks to Memurai’s stellar performance and scalability.

The intended audience for this guide is enterprise users who will soon need to migrate from Windows AppFabric Caching to Memurai. We’ll cover the key differences between the two products and explain the best practices for performing the migration.

2. Overview of key architectural differences

Both Memurai and AppFabric Caching support a client/server model of communication and all of the semantics and features of AppFabric Caching are supported by Memurai. However, Memurai goes further and extends those features with far more functionality than is available with the legacy AppFabric Caching. This section provides an overview of the key architectural differences between AppFabric Caching and Memurai.

2.1 Data Types

AppFabric Caching only allows you to store serializable Common Language Runtime (CLR) objects into the in-memory cache. In contrast, Memurai is a general-purpose datastore which means you can store a variety of data types including strings, lists, and hashes. Each of the data types supported by Memurai offers improvements over the simple object mechanism used by AppFabric Caching. For one, while AppFabric Caching only supports SET and GET commands, Memurai supports a far wider range of commands, specially created to make operations faster and more convenient. As an example, Memurai’s lists are highly performant and support ordering elements based on their insertion order (useful for maintaining a timeline of events) with the LPUSH (prepend element) and RPUSH (append element) commands.

Searching with Tags

AppFabric Caching supports tags for assigning metadata to objects in the cache, and you can use an API to search the cache and find objects with the tags. Tags only work within a region, and the caveat is that providing the tag-search functionality requires objects in a region to be confined to a single cache host. Alternatively, if you do not specify a region, objects can be cached across all hosts in a cluster. In this way, developers are faced with a trade-off: better searchability with tags or improved scalability using multiple cache hosts.

Conversely, you can use tags with Memurai by embedding descriptive strings in key names or by using the set data type to group related keys together. Using sets in this way allows you to quickly and efficiently retrieve all of the associated data with the MGET command. Unlike AppFabric Caching, no restrictions are placed on where data is stored.

Eviction and Expiration Policies

While AppFabric Caching only supports the Least Recently Used (LRU) cache eviction policy when eviction is enabled, Memurai supports multiple LRU and random eviction policies along with an expiration-based policy — for evicting keys with the shortest time to live (TTL) first — and a Least Frequently Used (LFU) eviction mode.

With Memurai, you can monitor the number of cache hits and reconfigure the eviction policy at runtime to tune Memurai’s behavior to match the access pattern of your application.

Server Configuration and Deployment

Each host running Windows AppFabric Caching in a cluster requires access to a centralized location that contains the cluster configuration file. The three options available are:

  • An XML configuration file on a shared network folder
  • A SQL Server database
  • A custom store

Nodes in a Memurai cluster are configured with individual configuration files, stored on the nodes themselves rather than in a central location. The Memurai configuration file is fully compatible with the Redis 5 syntax.

You can also configure Memurai clusters over the network using the memura-cli.exe utility. For example, to create a new cluster with three masters and three slaves type:

memurai-cli.exe --cluster create 127.0.0.1:7000 127.0.0.1:7001 \
127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
--cluster-replicas 1

memurai-cli.exe will then give you the option of accepting a pre-generated configuration file. Once you’ve typed “yes” to accept the proposal, each node will be automatically bootstrapped into talking with each other and they will join the cluster.

High Availability

AppFabric Caching supports a High Availability (HA) mode. When enabled, HA mode stores a copy of every cache object or region on a separate cache host. High availability is achieved because the cache cluster will supply any clients with a copy of the data even if one of the cache hosts is unavailable. The static assignment of Lead hosts for Windows AppFabric Caching clusters leads to inflexible cluster management and unnecessary overhead for administrators. HA mode requires that all cache hosts in a cache cluster are running the Enterprise Edition (or higher) of Windows Server 2008 or Window Server 2008 R2.

Memurai also supports high availability by using leader-follower (master-replica) replication across Memurai instances. Every replica tries to be an exact copy of the master at all times, and if the link between a replica and master goes down, the replica will automatically try to reconnect. If the master instance is unavailable, the replicas can still service read requests and, if you’re running one or more Memurai instances in sentinel mode, a new master can be elected from one of the replicas so that failover is handled automatically and downtime is minimized.

Cluster Management

AppFabric Caching servers can only be managed using a PowerShell-based administration tool. Various PowerShell scripts are available to configure cache hosts after they’ve been installed and initially configured.

Managing Memurai clusters is done using the memurai-cli.exe application, or by sending commands directly the cluster node with one of the many client libraries. There are client libraries available for pretty much every programming language and runtime.

Session state

AppFabric Caching offers an ASP.NET session state provider which enables session state to be cached on a cache server or across a cluster. Also ASP.NET page output caching allows you to cache full HTTP responses.

If you’re currently using ASP.NET session state providers, you can easily migrate to Memurai by replacing your ASP.NET providers with the Redis ASP.NET session state providers.

Consistency Model

AppFabric Caching supports a strong consistency model, and any cache operation that returns successfully guarantees that the data is replicated in the cache.

Memurai clusters use asynchronous replication which greatly improves its performance. Because Memurai doesn’t wait for writes to be replicated before replying to the client, the write performance of Memurai is much better than AppFabric Caching.

If you want to guarantee strong consistency at the expense of performance, you can force Memurai to flush data to disk before replying to the client. Note that Memurai’s consistency guarantees are stronger than AppFabric Caching consistency because Memurai actually ensures that data has safely been written to disk, whereas AppFabric Caching only guarantees that it has been replicated.

Locking

AppFabric Caching supports both optimistic version-based updates and pessimistic locking, otherwise known as exclusive locking. Memurai doesn’t support any locking out of the box and you need to implement your own distributed locks.

Client APIs

For AppFabric, caches are accessed and modified with instances of the DataCache class in the Microsoft.ApplicationServer.Caching namespace. Items can be added and removed from a cache using the Add() and Remove() methods, and existing objects can be updated using the Put() method. To retrieve an object, use the Get() method.

Here’s a simple example of a cache client:

using Microsoft.ApplicationServer.Caching;

DataCacheFactory factory = new DataCacheFactory();
DataCache myCache = factory.GetCache(“cache1”);

object item1 = new Object();
object item2 = new Object();

string key = “itemKey”;

myCache.Add(key, item1);
myCache.Put(key, item2);

object obj = myCache.Get(key);

myCache.Remove(key);

A variety of client libraries are available to use with Memurai. The following code implements the above cache client example using the StackExchange.Redis C# Redis client library:

RedisClient redis = new RedisClient();

public class User
{
public long Id { get; set; }
public string Name { get; set; }
}

var redisUsers = redis.As<User>();

var userId = redisUsers.GetNextSequence();
var user1 = new User { Id = userId, Name = "Jane Doe" };
redisUsers.Store(user1);

var user2 = new User { Id = userId, Name = “Joan Doe” };
redisUsers.Store(user2);

var user = redisUsers.GetById(userId);
redisUsers.Delete(user1);

Local Cache

AppFabric Caching supports a local cache feature, allowing you to store objects client-side, and it’s mostly used for objects that change infrequently which can help eliminate the roundtrip latency associated with fetching the data from the remote cache server.

While Memurai does not support a local cache design directly, there are some alternative methods for locally caching data. For one, client applications can implement their own in-process dictionary to store recently accessed data. Alternatively, because Memurai can run on any Windows machine, a much better way to implement a local cache is to run a Memurai instance on the client machine itself.

Object Versioning

AppFabric Caching supports object versioning, meaning you can have multiple versions of an object stored in-memory at once. Using the GetNewerIf API, you can save bandwidth by only retrieving an object if a newer version exists.

Memurai doesn’t support object versioning directly, but it’s easy to get the same benefits by carefully selecting data types in your application. For example, you can add a version field for your data using the hash data type and use the HGET command with the desired version field value to retrieve a specific version of the data.

Persistence

AppFabric Caching doesn’t support persistence, and consequently, all in-memory data is lost whenever an AppFabric Caching cluster is restarted.

Memurai supports a range of persistence options to write your in-memory data to disk. You can use the RDB persistence, which takes a snapshot of your data at a specified interval and writes it out to disk. The AOF persistence logs every write operation, allowing the full list of writes to be replayed by Memurai when it restarts.

Memurai can persist the in-memory datastore to disk using RDB persistence (take periodic snapshots), AOF persistence (log every write), or both.

To configure Memurai to persist data to disk, you can either update the memurai.conf configuration file or use memurai-cli.exe with the CONFIG command.

If you want to enable RDB persistence, add the SAVE option to your configuration file with the snapshot interval and the minimum number of writes required for a snapshot, e.g.

save 900 1    # write snapshot every 15 mins if at least 1 key has changed

Alternatively, you can use memurai-cli.exe to dynamically update the configuration file:

memurai-cli.exe config set save 900 1

Note: you may also want to customize to set the dbfilename and dir settings which control where the database is written on disk.

To enable AOF persistence you need to configure the appendonly setting, which you can do by modifying memurai.conf:

appendonly yes

Or by usingmemurai-cli.exe:

memurai-cli.exe config set appendonly yes

Disaster Recovery

Disaster recovery is an important part of every administrator’s role. Planning for and recovering from disasters with AppFabric Caching involves backing up settings, files, and databases through Windows, IIS, and SQL Server. The list of assets that require backing up include:

  • Configuration settings and files
  • Windows service settings for Event Collection, Workflow Management, and Caching Service
  • Windows security settings for modifications to AppFabric-specific user groups
  • Registry settings
  • Web application files
  • Databases used by AppFabric

In comparison to AppFabric Caching, Memurai’s disaster recovery support is much more solid thanks to its ability to persist in-memory data. To prepare for disaster recovery, you should ensure that your database file is safely stored to redundant storage to guard against data loss. It’s also advisable to store your database file to a remote location by copying the Memurai RDB file while Memurai is running. It’s safe to copy RDB files while Memurai is running because these files are never modified once they’re written.

It’s also possible to create backups if you run Memurai with AOF persistence by copying database files to your chosen backup location.

3. In conclusion

Thank you for reading all the way to the end. What questions come to your mind as you read this blog? Please let us know and download Memurai for free and start migrating today.

Golden Gate Bridge