In a distributed cache environment, there can be scenarios where certain data should be present in the cache for the application to use immediately after it begins execution. Initially, when a cache starts, it does not contain any data which can cause expensive data source trips to obtain data, impacting the performance of the application. Therefore, it becomes important that the cache used to store data is preloaded with some reference data before the application starts using it.
For this purpose, NCache provides a Cache Startup Loader feature which allows the users to implement an interface to preload desired reference data in the cache as soon as the cache starts up. As a result, the user application will not have cache misses and lesser data source trips, hence achieving faster performance.
Components of Cache Startup Loader
Every time the cache starts up, Cache Startup Loader automatically fetches data from the data source for the user to use beforehand. Therefore, before moving onto how Cache Loader works, the user should know about some of its characteristics which are explained below.
- Datasets: A dataset is a way for user to group different types of data so that they can load or refresh them separately at different intervals or events to achieve parallelism.
- Loader Service: It is responsible to manage the tasks and load data from the data source into the cache on startup.
- Cache Loader Retries: In case, an operation fails while loading the cache, those failed operations can be performed again before moving onto the next one through the number of retries option which is configured through NCache Web Manager.
NCache Details Cache Loader and Refresher Docs NCache Docs
How to Implement Cache Startup Loader?
To enable Cache Startup Loader, the user, first of all, needs to implement the ICacheLoader interface. NCache uses this interface with the methods explained below to load data from the data source in the cache on cache startup.
Initialize Cache Startup Loader
Init method is called on Cache Startup to pass the configured parameters so that the user can use it accordingly to initialize their cache and the data source. Just configure the connection by opening a database connection like SQL and initialize a cache with the given name like the below sample implementation for .NET and Java.
1 2 3 4 5 6 7 8 9 |
public void Init(IDictionary<string, string> parameters, string cacheName) { cache = CacheManager.GetCache(cacheName); connectionString = parameters.ContainsKey("ConnectionString") ? parameters["ConnectionString"] : null; if (connectionString != null) { connection = new SqlConnection(connectionString); } } |
1 2 3 4 5 6 7 8 |
public void init(Map<String, String> parameters, String cacheName) { cache = CacheManager.getCache(cacheName); connectionString = parameters.containsKey("ConnectionString") ? parameters.get("ConnectionString") : null; if (connectionString != null) { connection = DriverManager.getConnection(connectionString); } } |
Load Data on Cache Startup
The following sample implementation for .NET and Java, of the method LoadDatasetOnStartup of ICacheLoader
interface fetches the data from the data source and adds it into the cache on cache startup to preload the cache. It returns a user context that holds the information about the data loaded in the cache.
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 |
public object LoadDatasetOnStartup(string dataset) { // Create a list of datasets to load at cache startup IList<object> datasetToLoad; switch (dataSet.ToLower()) { // If dataset is "products", fetch products from data source to load in cache case "products": datasetToLoad = FetchProductsFromDataSource(); // Insert fetched product in the cache foreach (var product in datasetToLoad) { string key = $"ProductID:{product.Id}"; cache.Insert(key, product); } break; // You can add more cases for different datasets as per requirement and fetch them from the data source default: // Invalid dataset } // User context is the time at which datasets were loaded in the cache object userContext = DateTime.Now; return userContext; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public Object loadDatasetsOnStartup(String dataset) { // Create a list of datasets to load at cache startup List<Object> datasetToLoad; switch (dataset.toLowerCase()) { // If dataset is "products", fetch products from data source and add in cache case "products": datasetToLoad = fetchProductsFromDataSource(); // Insert fetched product in the cache for (var product : datasetToLoad) { string key = "ProductID:" + product.productID; cache.insert(key, product); } break; // You can add more cases for different datasets as per the requirement and fetch them from data source default: // Invalid dataset } // User context is the time at which datasets were loaded in the cache Object userContext = LocalDateTime.now(); return userContext; } |
Just like the preloading of data is an important thing to do, there can be a huge chance that the loaded data becomes outdated. The already loaded data in the cache might be altered due to any change occurring in the data source, which is why the preloaded might become stale. To keep this loaded data fresh, NCache provides a feature of Cache Refresher that uses Cache Loader implementation to keep the loaded data fresh and synced with the data source.
NCache Details Configure Cache Loader and Refresher Cache Refresher Docs
Configure Cache Loader through NCache Web Manager
Once the user has implemented Cache Startup Loader, they can configure it through NCache Web Manager. Below is how it can be done.
Conclusion!
As you can see, NCache provides its users a powerful feature Cache Startup Loader to preload data into the cache instead of manual follow-up. So, grab hold of NCache and acquire all its amazing features for faster application performance and scalability!