. Net Core Cache Component (Redis) source code parsing

Source: Internet
Author: User


The previous article has introduced the Memorycache,memorycache storage data type is object, also said Redis support v data type of storage, but Microsoft's Redis cache component only implemented hash type of storage. Before you analyze the source code, learn a few commands about Redis operations.


One, Redis command


All Redis commands are described in detail on the http://doc.redisfans.com/. Here are a few common commands for hash types.


Hset: For adding a cache


Usage: Hset key field value.



return value: Iffieldis a new domain in the hash table, and the value is set successfully, return1.


If the domain in the hash tableFieldalready exists and the old value has been overwritten by the new value, returning0。 For example: Hset user Name microheart hset user age Hmset: for adding multiple


Usage: Hmset key [field value Field1 value1 ...]



Return value: ReturnsOKif the command executes successfully.


WhenKeyis not a hash table (hash) type, an error is returned. Example: Hmset user1 Name microheart age hget: Get field value


Usage: Hget key field



Return value: The value of the given field.



ReturnsNilif the given domain does not exist or if a givenkeydoes not exist



Example: Hget user Name ( Note Redis is case sensitive )





Hmget: Get the values of multiple fields


Usage: Hmget key [Field1,field2]



Return value: A table that contains the associated values for a given field, and the table values are arranged in the same order as the request order for the given domain parameters.



Example: Hmget user Name Age





EXPIRE: Setting the cache Expiration time


Usage: EXPIRE key seconds



Return value: The setting returned successfully to1.


WhenKeyDoes not exist or cannot beKeyWhen you set the time to live (for example, in Redis under 2.1.3, you try to updateKeyTime of Life), return0。 For example: EXPIRE user TTL: Indicates the remaining time to live. 57 means 57 seconds before this cache expires. When it expires, Redis is automatically deleted. In the Redis 2.4 release, the delay in the expiration time is within 1 seconds--that is, even ifKeyhas expired, but it may be accessed within one second of expiration, and in the new Redis 2.6 release, the latency is reduced to 1 milliseconds. Ii. using Redis components in. Net Core


The Redis cache feature is added first in the Startup class. The value of the instancename set in the configured option is used as part of the key. For example, set the InstanceName to test, the code set a cache key is user, the actual key stored in Redis is testuser.


Public void ConfigureServices(IServiceCollection services)
{
       services.AddMvc();
       services.AddDistributedRedisCache(option =>
       {
            option.Configuration = "121.41.55.55:6379"; / / connection string
            option.InstanceName = "test";
       });
}


Then inject the idistributedcache where it is needed. As shown in the following:


Public class ValuesController : Controller
{
         Private readonly IDistributedCache redisCache;
         Public ValuesController(IDistributedCache redisCache)
         {
             this.redisCache = redisCache;
         }
         [HttpGet]
         Public IEnumerable<string> Get()
         {
             redisCache.SetAsync("key1", Encoding.UTF8.GetBytes("value1"), new DistributedCacheEntryOptions()
             {
                 AbsoluteExpiration = DateTime.Now.AddSeconds(10)//Set the expiration time, the time is removed as soon as the cache is removed.
             });

             redisCache.SetString("key2", "value2");//The cache expiration time is not set, indicating that it is a permanent cache.

             Return new string[] { "value1", "value2" };
         }
} 
Third, source code analysis


Source code in the Github.com/aspnet/caching,redis source is relatively simple, mainly because many are directly using the Stackexchange.redis API.


Rediscacheoptions class: Mainly Redis configuration related.


Configuration: Set up Redis configuration, such as connection string, time-out, etc., and eventually be replaced with Configurationoptions in Stackexchange.redis



InstanceName: Instance name. And the key set in the code is joined to the key in Redis.


Rediscacheservicecollectionextensions class: Associated with service injection.


For a method Adddistributedrediscache, rely on an instance of injected Idistributedcache.


public static IServiceCollection AddDistributedRedisCache(this IServiceCollection services, Action<RedisCacheOptions> setupAction)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            if (setupAction == null)
            {
                throw new ArgumentNullException(nameof(setupAction));
            }
            services.AddOptions();
            services.Configure(setupAction);
            services.Add(ServiceDescriptor.Singleton<IDistributedCache, RedisCache>());//注入一个单例
            return services;
        }
Rediscache class: The most important class, the cache operation-related class.


The method of inserting and retrieving data is more important.


3.1 The Set method, insert the data.
Public void Set(string key, byte[] value, DistributedCacheEntryOptions options)
  {
          / / Omit some logic judgment
            Connect();
            Var creationTime = DateTimeOffset.UtcNow;
/ / For a cache can be set to the absolute expiration time, relative to the current time expiration time and sliding expiration time (in the previous article has an example), in fact, the first two types of time can be converted to each other.
//The following step is if the absolute expiration time is set or the expiration time relative to the current time is set, the replacement is the absolute expiration time.
            Var absoluteExpiration = GetAbsoluteExpiration(creationTime, options);
/ / Called the StackExchange.Redis API insert cache
            Var result = _cache.ScriptEvaluate(SetScript, new RedisKey[] { _instance + key }, / / The key here is the key in the instance name +key=Redis. Of course, when we look up the cache, we don't need to manually stitch it. Just pass the key we copied, no need for instance name

                New redisValue[]
                {
                        absoluteExpiration?.Ticks ?? NotPresent,
                        options.SlidingExpiration?.Ticks ?? NotPresent,
// If the absolute expiration time and the sliding expiration time are set for a cache at the same time, the time that is about to expire, that is, the minimum time, is taken.
                        GetExpirationInSeconds(creationTime, absoluteExpiration, options) ?? NotPresent,
                        Value
                });
        } 


If both Absexp and sldexp do not have a value set, the default is-1, which means never expires, the cache time is taken from the set absolute expiration and sliding expiration time, and when the time is up, Redis automatically deletes the expired cache, which is not the same as memorycache. Memorycahe is in the cache operation, will scan the entire cache delete, there is a large delay, and Redis uses the following three strategies to clean up expired key:


    1. Passive deletion: When reading/writing a key that has expired, the lazy delete policy is triggered, and the expired key is deleted directly
    2. Active deletion: Due to the lazy deletion policy cannot guarantee that cold data is deleted in time, so Redis will periodically proactively eliminate a batch of expired key
    3. Active cleanup policy is triggered when current memory exceeds maxmemory limit


This ensures that the expiration cache is cleaned up in a timely manner. The strategy for Redis cleanup expired key can be seen in this article.



When inserting a hash type of data, open Redismanager will see the following, Absexp: Absolute Expiration time, sldexp: Sliding expiration Time, data: is the value set in our code.





In the 3.2 get method, the implementation of the main fetch function calls the following code.
In the above add cache, script insert is used.
Private const string SetScript = (@"
                 Redis.call('HMSET', KEYS[1], 'absexp', ARGV[1], 'sldexp', ARGV[2], 'data', ARGV[4])//Set key, absolute expiration time, sliding Expiration time, and value of value
                 If ARGV[3] ~= '-1' then
                   Redis.call('EXPIRE', KEYS[1], ARGV[3])//Set the cache time
                 End
                 Return 1"); 


The Remove method calls the Stackexchange API directly, which is not explained here.



Compared to MemoryCache code, the Redis code is relatively simple, mainly Microsoft developers "Jerry-building" (I feel), many important methods, such as Redis connection, add, set the expiration time, have called the Stackexchange API, Did not implement its own link pool and so on. More like a re-encapsulation of the hash type in STACKEXCHANGEAPI.


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.