Skip to content

Caching Redis & Internal

Rocky edited this page Jan 5, 2023 · 13 revisions

What is caching?

A cache is a hardware or software component that stores data so that future requests for that data can be served faster. The data stored in a cache might be the result of an earlier computation or a copy of data stored elsewhere. In mentoring services, all the necessary data which are used frequently will be cached in Redis and the Internal cache.

What is hit and miss in caching?

A cache miss occurs when a cache does not have the requested data in its memory. Meanwhile, a hit is when a cache successfully finds the requested data, satisfying the search query.

How Caching is implemented in Elevate services?

Caching Implementation

Internal and Redis caching is implemented with the help of an npm package called elevate-node-cache. This package exports 3 modules.

  1. RedisConfig
  2. RedisCache
  3. InternalCache
Module Description
RedisConfig This module has one function which needs to be called at the start of the microservice. To initialize the global Redis client, pass the Redis URL to this function as a parameter.
RedisCache This module has three functions for caching - set, delete and read cache from memory. You need to pass Key in the read and delete functions to get cached data. In a set function, you need to pass two mandatory parameters, namely Key and Value. A third optional parameter is time, which specifies how long the data needs to be cached. If the time parameter is not specified, the cache will be stored for forever. When the memory is full, the Redis eviction policy is used to clear memory. Expiry time must be in seconds.
InternalCache This module has four functions for caching and initialization. * init function: Call this function at the start of an application and pass the Expiry time for the cache. * Set: Pass a Key and Value to set the cache. The function will use the default time, which is initialized at the start of an application.* Read: Pass the Key of cache to read the cache.* Delete: Pass the Key of cache to delete the cache.In the internal cache, you cannot modify the expiry time of a cache as it will get initialized at the start of an application. To change the expiry time of the cache, you need to update in env “INTERNAL_CACHE_EXP_TIME”. Expiry time must be specified in seconds.

In Elevate services, caching is implemented in 3 features

  1. Form version cache (Internal cache)
  2. Entity (Internal cache)
  3. Mentor Profile (Redis)

Form version cache

In Elevate services, form services are consumed by the front-end application. Each form has a version and this version will be updated once the form is updated.

The front-end application will use a cache to store form data along with its version. If the form gets updated, its version will change and an API request will be sent to backend services for the latest data. The application’s limited and frequently used data will be stored in the internal cache to serve the application faster and better.

Form data will be saved in the below format.

"formsVersion": [
           {
               "_id": "62e8bb2665320be5417a19e1",
               "type": "profile",
               "__v": 12
           },
           {
               "_id": "632844eb1b95f4e72732ab42",
               "type": "session",
               "__v": 5
           },
] 

This data will be part of the meta key in responses. Data is not updated individually when any form gets updated then it will delete the formVersion key and the new query will create cache data in the formVersion key. While creating the cache value is converted into string format using Stringify and in retrieval, it will be parsed to JSON.

Entity

In mentoring services, there are different entities like roles, categories, languages, etc. this information will be required by form services. This data has to be served faster and data will be required with the type of entities such as, roles, categories, etc. all this data will be clubbed into one key and cached this data into the internal cache.

For example

curl --location --request GET 'http://localhost:3001/user/v1/userentity/read?type=roles' \
--header 'X-auth-token: bearer token'

   "result": [
       {
           "value": "DM",
           "label": "DM"
       },
       {
           "value": "SDM",
           "label": "SDM"
       }
   ]

In the above, case data will be stored in entity_roles. While creating the cache value is converted into string format using Stringify and in retrieval, it will be parsed to JSON.

Mentor Profile

Mentoring services have mentee and mentor profile data. Mentor profile data will be used by mentees to check their upcoming sessions and the rating of a mentor. Mentor profile data will be utilized by many mentees. Mentor profile data will be used frequently to make sure data is available to all users, mentor's profile data will be cached in Redis cache. If a mentor profile is called in mentoring services then it will make a call to users services to get the profile of the mentor. If the mentor profile is found in Redis (hit) then will return profile data and if the mentor profile is not found in the cache (miss) then it will make calls to the database and store that data in the cache and returns profile data of that mentor and if someone request same profile data then it will be served from cache.

Mentors Profile data will be stored in key-value pair format

In profile data, the key will be _id of the mentor. Here is an example: 633f9b9c6cb69b6f89b4a83f

The value will be Profile data.

While creating the cache value is converted into string format using Stringify and in retrieval, it will be parsed to JSON.

How will Cache data be updated?

Internal Cache

Multiple micro-services will be running for the same service, when form data gets an update request at that time it will update its data and it will delete the current data from the cache and one message along with the key will be published in Kafka for the rest of the services to delete their internal cache and update with new form version.

Internal Cache update for Form and Entity

When backend services receive an API call to update form data it will perform an update operation. Once the update operation is completed then it before sending a response to a client it will publish one event in Kafka for another microservice of the same instance. When an event is published in Kafka it will return a response and the exact event is consumed by other microservices to delete their internal cache. After deleting the cache from other microservice when it receives any API call it will check whether a cache is present or not then it creates a cache and send the data to a client.

Redis Cache

When mentor profile API is called with updated data then data of that particular mentor will be deleted from the global cache and new data will be cached. If Redis memory is full then the least called mentor profile will be deleted and new data will be cached.

See this resource for more information: https://redis.io/docs/manual/eviction/