In many of the distributed projects we develop (such as WCF-based services, WEB API services), because the data provide related operations of the database, if the number of concurrent clients exceeds a certain number, then the database request processing in an explosive growth, If the database server is unable to process these concurrent requests quickly, it will increase the client's request time, which could cause the database service or application service to be directly paralyzed. The caching scheme is the birth of this, with the introduction of the cache, the database can be time-consuming operation of the IO, converted into memory data of the rapid response operation, or the entire page cache into the cache system. The caching framework has many implementations in each platform, mostly using distributed cache Redis and memcached. This series of articles is presented in the. NET platform, using the Open source cache framework CacheManager to achieve the entire process of data caching, this article mainly introduces the use of CacheManager and related testing.
1, the introduction of CacheManager
CacheManager is an open source developed in the C # language. NET Cache Framework Abstraction layer. It is not a specific cache implementation, but it supports a variety of cache providers (such as Redis, memcached, etc.) and provides many advanced features.
CacheManager's main purpose is to make it easier for developers to handle complex caching scenarios, using CacheManager to implement multi-tiered caches that are cached in-process before the distributed cache and require only a few lines of code to handle.
CacheManager is not just an interface to unify the programming model of different cache providers, it makes it very easy to change the caching strategy in a project, but also provides more features: Cache synchronization, concurrency update, serial number, event handling, performance calculation, etc. Developers can select these features when they are needed.
CacheManager GitHub Source address is: Https://github.com/MichaCo/CacheManager, if you need specific demo and instructions, you can visit their official website: http://cachemanager.net/.
Use NuGet to add CacheManager package references to your project. CacheManager contains a lot of package. Where Cachemanager.core is required, there are different packages for different cache platforms, and the entire NuGet package contains the contents of the following sections.
The CacheManager caching framework supports application development such as WinForm and Web, and supports a variety of popular cache implementations such as MemoryCache, Redis, Memcached, Couchbase, System.Web.Caching, and more.
Throughout the cache framework, it is very specific, in support of a variety of cache implementations, itself mainly in memory cache (in-process) mainly, other distributed cache as a supplement to the multi-tier cache architecture, to achieve a fast hit and processing mechanism, they have related message processing, so that even the distributed cache, It is also possible to implement concurrent synchronization cache processing in time.
This more abstract layer, as well as a caching framework that provides more advanced features on the Web, is flooded with implementations and applications based on some sort of individual cache, and it also achieves very strong compatibility on the basis of providing a unified programming model, so that when I come into contact with this framework, I love it.
On GitHub, the top few of the cache framework, in addition to the caching framework, are still some, but the caching framework is well worth it in terms of the richness of the document.
The CacheManager cache framework is very convenient in terms of configuration, support for code-mode configuration, XML configuration, and configuration processing in JSON format.
The CacheManager cache framework defaults to serialization of cached data in a binary manner, and also supports a variety of custom serialization methods, such as JSON serialization based on Josn.net or custom serialization.
CacheManager Cache framework can record the increase, deletion, update and other related events of the cache record.
The cached data of the CacheManager cache framework is strongly typed and can support various general types of processing, such as int, String, list type, and various types of objects and list objects that can be serial numbers.
The CacheManager cache framework supports multi-layered cache implementations, and a good internal mechanism allows for efficient and timely synchronization of cached data from each layer.
The CacheManager cache framework supports logging of various operations.
The CacheManager cache framework supports the locking and transaction of updates in the distributed cache implementation, keeping the cache better synchronized, and the internal mechanism implementing version conflict processing.
The CacheManager cache framework supports two kinds of cache expiration processing, such as the expiration of absolute time, and the expiration of fixed periods, which is more convenient for us to handle cache expiration.
....
Many features basically cover the general nature of the cache, and the interface provided is basically our usual add, Put, Update, remove and other interfaces, it is also very convenient to use.
2. Application of CacheManager Cache frame
With a simple understanding of the CacheManager caching framework above, we probably understand some of the features it applies to, but actually how we use it, we need to do some learning and understanding, and first we need to know the role of the caching framework throughout the application framework.
In general, for a stand-alone version of the scenario, there is basically no need to introduce this caching framework, because the client's concurrency is very small, and data requests are very few, the performance of the convenience of no problem.
If for a distributed application system, as I introduced in many essays to my "hybrid development Framework", "Web development Framework", because the data request is the concurrency increase with the growth of the user, especially for some Internet applications, in extreme cases at some point in time may be reached the peak of the entire application concurrency. So this distributed system architecture, the introduction of data cache to reduce the concurrency of IO, time-consuming requests into memory of high-speed requests, can greatly reduce the risk of system downtime.
As an example of building an application framework based on a regular web API layer, the entire data cache layer should be a layer above the Web API layer, above the business implementation layer, as shown below.
In this data cache layer, we introduce the CacheManager cache framework to implement distributed cache processing, so that our cache data can be processed on the Redis server, while the system can be restarted without losing data and can quickly recover cached data.
In order to make use of this CacheManager caching framework, we need to conduct a usage test to understand its various conveniences before it can be widely used in our data middle tier.
We build a project and open the Manage NuGet package in the referenced place, then search for the relevant module application of CacheManager and add it to the project reference, this is the first step to work.
We create a Customer object class to simulate the storage and display of data, as shown in the following code.
/// <summary>///Customer object classes for simulated data storage/// </summary> Public classcustomer{Private StaticCustomer M_customer =NULL; Private Staticicachemanager<Object> Manager =NULL; //Initializing list values Private Staticlist<string> list =Newlist<string> () {"123","456","789" }; /// <summary> ///One-piece instance of a Customer object/// </summary> Public StaticCustomer Instance {Get { if(M_customer = =NULL) {M_customer=NewCustomer (); } if(Manager = =NULL) {Manager= Cachefactory.build ("Getstartedcache", settings ={settings. Withsystemruntimecachehandle ("Handlename"); }); } returnM_customer; } }
This class first makes a singleton implementation, initializes the cache of the customer class object, and caches the management class Icachemanager<object> manager, which is the primary reference object that we use to manipulate the cached data behind.
We write a few functions to achieve the data acquisition, data increase, data deletion of related operations, and in the data increment, delete, trigger the cache update, so that the next time we get data, is the latest data.
/// <summary>///get all customer information/// </summary>/// <returns></returns> Publiclist<string>GetAll () {varValue = Manager. Get ("GetAll") aslist<string>; if(Value = =NULL) {Value= list;//initializing and joining the cacheManager. ADD ("GetAll", value); Debug.WriteLine ("Initialize and join the list"); } Else{Debug.WriteLine ("Access Cache fetch: {0}", DateTime.Now); } returnvalue;}/// <summary>///insert a new record/// </summary>/// <param name= "Customer" ></param>/// <returns></returns> Public BOOLInsert (stringcustomer) { //get all the records first, then add the records if(!list. Contains (Customer)) {list. ADD (customer); } //Reset CacheManager. Update ("GetAll", V =list); return true;}/// <summary>///Delete a specified record/// </summary>/// <param name= "Customer" ></param>/// <returns></returns> Public BOOLDelete (stringcustomer) { if(list. Contains (Customer)) {list. Remove (customer); } manager. Update ("GetAll", v=>list); return true;}
We write a WinForm program to test this cache to make it easier to understand the mechanism.
When we test the read, we process the getall, and the insertions and deletions are primarily to test the processing of cache updates. The code is shown below.
Private voidBtntestsimple_click (Objectsender, EventArgs e) { varList =Customer.Instance.GetAll (); Debug.WriteLine ("client gets record count: {0}", List! =NULL? List. Count:0);}Private voidBtninsert_click (Objectsender, EventArgs e) { varName ="ABC"; Customer.Instance.Insert (name); Debug.WriteLine (string. Format ("Insert record: {0}", name));}Private voidBtndelete_click (Objectsender, EventArgs e) { varName ="ABC"; Customer.Instance.Delete (name); Debug.WriteLine (string. Format ("Delete record: {0}", name));}
We track records and can see the following log information.
As we can see, the first time the cache is initialized without a case, the number of initialized records is 3, then after the record is inserted, the number of cached updates becomes 4 when the data is fetched again.
We described the background code for inserting a record, which also updates the cached data.
/// <summary>///insert a new record/// </summary>/// <param name= "Customer" ></param>/// <returns></returns> Public BOOLInsert (stringcustomer) { //get all the records first, then add the records if(!list. Contains (Customer)) {list. ADD (customer); } //Reset Cache Manager. Update ("GetAll", v = = list); return true;}
As we described earlier in the cache initialization configuration, the default is to use the memory cache, and does not use the distributed cache configuration, its initialization code is as follows:
Manager = Cachefactory.build ("getstartedcache", settings = ={ settings. Withsystemruntimecachehandle ("handlename"
Under normal circumstances, we still need to use this powerful distributed cache, for example, we can use the Redis cache processing, about Redis installation and use, please refer to my essay, "C #-based MONGODB Database development application (4)--redis installation and use."
With the introduction of a distributed Redis cache implementation, our configuration code requires only a certain amount of change, as shown below.
Manager = Cachefactory.build ("getstartedcache", settings = ={ settings. Withsystemruntimecachehandle ("handlename") . and . Withredisconfiguration ("Redis", config = = { config. Withallowadmin () . Withdatabase (0) . Withendpoint ("localhost", 6379); }) . Withmaxretries (+) . Withretrytimeout (a) . Withredisbackplane ("Redis") . Withrediscachehandle ("Redis", True)
Other uses do not change, we also add some test data to facilitate our access to the corresponding cache data.
/// <summary>///test to add several different data/// </summary>/// <returns></returns> Public voidTestcache () {Manager. Put ("string","ABCDEFG"); Manager. Put ("int", .); Manager. Put ("decimal",2016.9M); Manager. Put ("Date", DateTime.Now); Manager. Put ("Object",NewUserInfo {ID ="123", Name ="Test", age = * });}
Private void Btntestsimple_click (object sender, EventArgs e) { var list = Customer.Instance.GetAll (); Debug.WriteLine (" client gets record number: {0}"null0); // test to add some values Customer.Instance.TestCache ();}
We test, everything and original no difference, the program's record information is normal.
However, we configured the use of Redis cache processing, so we can use the "Redis Desktop Manager" software to view the corresponding cache data, open the software we can see the corresponding cache record is as follows.
From what we can see, all of the cache key values we've added can be viewed by this Redis customer because we have a redis cache implementation in our cache, so if we configure other cache implementations, such as Memcache, we can also look at the corresponding management interface.
After we have completed these processing, we can find that the cached data can achieve multi-tier cache, the most efficient is the memory cache (also its main cache), it will automatically cooperate with the various distributed cache data version conflict problem.
The advantage of introducing a distributed cache such as Redis is that our data can be recovered when the program restarts, and if it is not found in the memory cache (without hitting the target), then the distributed cache is looked for and loaded, so even if the program restarts, our previous cache data remains intact.
The above is my introduction based on the overall understanding of the cache framework and its role-playing, as well as the introduction of the use of CacheManager and some scenarios, through the above simple case study, we can gradually introduce to the more practical value of the Web API framework level for use, With the hope that the caching framework will play its true and powerful value, but also for our various different caches need to carry on a higher level of exploration, hoping that we continue to support.
. NET Cache framework CacheManager application in hybrid development Framework (1) Introduction and use of-cachemanager