Design an Efficient Cache Management Service

Source: Internet
Author: User

1. Identify active data. We use a separate method to find active data, write a single background program to extract active data and collect the first articles with the most queries in the past hour from the database.
These articles must be the most frequently accessed articles by users. They can extract the data of these articles and upload them to the cache server using FTP, and send a message to the cache server to notify it that new cache data is available, because
Active Data is extracted, so the cache hit rate of such data will be higher.

2. After receiving a notification to extract active data programs, the Cache Server reads the cache information from the local disk and loads it To the memory.

And replace it with the cache used last time. In this way, the cache is not updated in real time, but is relatively read-only and updated every hour. Therefore, no locks are required to use the cache, you only need to use the cache object
A temporary variable is referenced to avoid being changed to null when the new and old caches alternate.

3. Use a separate database as the data version database, which stores the version information of each article,
Version
This information is of the int type. Whoever modifies an article must add 1 to the corresponding article version number in the version database, write a version management service to query the version of an article and update the version of an article.
Function. Because most of the fields in the version database are int type, the table should be very narrow and the performance will not be very poor.

4. When a user requests an article, check whether the Cache Server exists. If not, directly
Slave
Obtain the cached data version number from the database. If yes, obtain the actual version number from the version server. if the version number is consistent, use the cached data. if the version number is different, extract article data from the database, and

Update cache. Although each user request needs to access the version database, the architecture of the version database is simple and easy to optimize, so the possibility of performance bottlenecks is relatively small, and if the cache hit rate is high enough
This can reduce the number of requests to the document database.

Using system; using system. collections. generic; using system. threading; using system. diagnostics; namespace datacache {// public class canbecached {public int version;} public class article: canbecached {} public class cacheitem: canbecached {public article ;} // each article stores the version number in the version database. This interface provides the version query method. // If an article has been modified, call the updatexxversion method of this interface to update the data version, so that the cache server can obtain the latest version of real data public interface versi Onmanager {int getarticleversion (INT ArticleID); void updatearticlevserion (INT ArticleID);} // This class is used to manage cache, and the service that provides the cache interface // The cache and the cache is not necessarily a process or even a machine, internal static class articlecachemanager {Private Static volatile bool _ cacheavailable = false; static dictionary <int, cacheitem> _ cache = new dictionary <int, cacheitem> (); public static bool cacheavailable {get {return _ Cacheavailable ;}} public static void initcache () {_ cache = new dictionary <int, cacheitem> (); _ cacheavailable = true;} public static void loadcache () {dictionary <int, cacheitem> cache = readcachefromdisk (); _ cache = cache; // this operation is thread-safe and does not require lock (_ cahce ), because when _ cache is used, it is put into temporary variables before use.} Private Static dictionary <int, cacheitem> readcachefromdisk () {Throw new notimplementedexception ();} Private Static void checkcacheandarticleid (INT ArticleID) {If (! _ Cacheavailable) throw new invalidoperationexception ("cache not init. "); If (ArticleID <1) throw new argumentexception (" ArticleID ");} internal static versionmanager getversionmanager () {Throw new notimplementedexception ();} internal static Article getarticle (INT ArticleID) {checkcacheandarticleid (ArticleID); dictionary <int, cacheitem> cache = _ cache; cacheitem item; If (cache. trygetvalue (Artic Leid, out item) return item. article; else return NULL;} internal static void updatearticle (INT ArticleID, article) {checkcacheandarticleid (ArticleID); dictionary <int, cacheitem> cache = _ cache; cacheitem item; if (cache. trygetvalue (ArticleID, out item) item. article = article; // This assignment operation is thread-safe and does not need to lock this item.} // Read the article information from the database internal static class dbadapter {internal static Article getarticle (INT ArticleID, bool isupdatecache) {Article article = new article (); If (isupdatecache) articlecachemanager. updatearticle (ArticleID, article); throw new notimplementedexception () ;}// used to save an article public class articleitem {public int ArticleID; Public articleitem (INT ArticleID) {ArticleID = ArticleID;} public ar Ticle article; Public void load () {// 1. When the cache is being switched over, it directly retrieves data from the database if (! Articlecachemanager. cacheavailable) {Article = dbadapter. getarticle (ArticleID, false); return;} versionmanager = articlecachemanager. getversionmanager (); // 2. Compare the cached version and the actual data version to determine whether to use the cached information datacache. article article = articlecachemanager. getarticle (ArticleID); If (article! = NULL & article. version = versionmanager. getarticleversion (ArticleID) article = articlecachemanager. getarticle (ArticleID); // although the version is determined here, the old data may also be obtained, because when you get the data version and decide to use the cached data, the user may have modified the article data. In this case, the user experience is not too bad as long as the user refreshes the page next time. Else article = dbadapter. getarticle (ArticleID, article! = NULL); // if article is not null, it indicates that the cached data version is too old. In this case, update the data retrieved from the database to the cache.} class program {static dictionary <int, articleitem> _ articles = new dictionary <int, articleitem> (); static void main (string [] ARGs) {// initialize the cache articlecachemanager. initcache (); // check whether a new cache is available. New thread (checkcacheproc ). start (); // The user requests an article articleitem Article1 = new articleitem (1); article1.load () ;}public static void checkcacheproc (object state) {thread. currentthread. name = "check whether there is a new cache thread"; while (true) {try {If (newcacheavailable () articlecachemanager. loadcache (); thread. sleep (timespan. fromminutes (60);} catch (exception ex) {trace. traceerror ("Check cache occur an error:" + ex. message) ;}} Private Static bool newcacheavailable () {Throw new notimplementedexception ();}}}

Insufficient
1. When updating an article, you need to update the version database and use a transaction to ensure consistency. You need to change the existing code and reduce the write performance. However, I think it is easier to notify the Cache Server when updating data than the user. It is more complicated. Please try to make sure that the design is simple. if the version database cannot support it, try this solution again.
2. Because judging the data version number and using cached data are not an atomic operation, the intermediate data version number may be updated, so in the case of high concurrency, the old data may be displayed to the user. Only when the user refresh again will he find that the version number of the article has changed and the latest data is used. Here, the user experience is sacrificed in exchange for performance.

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.