Designing an efficient cache management Service

Source: Internet
Author: User
Tags require static class thread

Summary: Generally everyone do the cache is real-time update, and use the LRU algorithm to implement cache expiration strategy, but when the cache is more and more large, synchronization of the cache will cause the application of slow response. How to use the cache more effectively, how to improve the cache hit rate, how to reduce the cache lock operation, how to improve the performance of the cache, let's discuss.

1, to find active data, we use a separate way to find active data, write a separate background to extract active data from the database in the most recent one-hour lookup most of the first 1w article ID, these articles are definitely users of the most frequently visited articles, Take the data out of these articles to upload to the cache server with FTP, concurrent messages to the cache server to notify it has a new cache data available, because the extraction is active data, so such data do cache hit rate is higher.

2, the cache server after receiving the notification of active data program, read cache information from the local disk is loaded into memory and replaced to the last used cache, so that the cache is not updated in real time, but is relatively read-only, updated every 1 hours, so there is no need to lock the cache. Simply use the cache to refer to the cached object with a temporary variable to prevent it from becoming null when the old and new cache alternates.

3, with a separate DB as a data version of the database, which holds the version of each article information, version information is type int, no matter who modified an article, all in the version of the database to let the corresponding article version number plus 1, Writing a version management service provides the ability to query an article version and update an article version. Because most of the fields in the version database are int, the table should be very narrow and not very performance-poor.

4, the user requests an article, first see the cache server has no, if not, take it out directly from the database; If so, remove the cached data version number and obtain the actual version number from the version server, and if it has been, use cached data, such as not always, remove the article data from the database, and update the cache. Here, although the user's request to access the version of the database, but because the structure of the version database is simple, easy to optimize, so the likelihood of performance bottlenecks is relatively small, and if the cache hit high enough to reduce the number of requests for the article database.

Using System;
Using System.Collections.Generic;
Using System.Threading;
Using System.Diagnostics;

Namespace Datacache {

cacheable entity Classes
public class Canbecached{public int Version;}
public class Article:canbecached {}
public class cacheitem:canbecached
{
Public Article Article;
}

Each article saves the version number in the version database that provides the query version method
If an article is modified, the Updatexxversion method to invoke this interface
To update the data version so that the cached server can get the latest version of the real data
public interface VersionManager
{
int getarticleversion (int articleid);
void updatearticlevserion (int articleid);
}

This class is used to manage caching and to provide cache usage interfaces
Caching and caching services are not necessarily a process, not even a machine, through the socket
or remoting to use and update the cache you
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; The operation is thread-safe and does not require lock (_CAHCE) because the use of _cache is put into a temporary variable before being used.
}

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 (ArticleID, out item))
return item. Article;
Else
return null;
}

internal static void updatearticle (int articleid, Article Article) {
Checkcacheandarticleid (ArticleID);
Dictionary<int, cacheitem> cache = _cache;
CacheItem item;
if (cache. TryGetValue (ArticleID, out item))
Item. Article = Article; This assignment is thread safe and does not require lock on this item.
}
}

Read article information from a 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 Article Article;

public void Load ()
{
1, the cache is switching to take the data directly from DB
if (! articlecachemanager.cacheavailable)
{
Article = Dbadapter.getarticle (Articleid,false);
Return
}

VersionManager VersionManager = Articlecachemanager.getversionmanager ();

2, compare cached version and real data version to determine whether to use cached information
Datacache.article Article = articlecachemanager.getarticle (ArticleID);
if (article!= null && article. Version = = Versionmanager.getarticleversion (ArticleID))
Article = Articlecachemanager.getarticle (ArticleID); Although the version is judged, it is possible to retrieve the old data, because when you get the data version and decide to use the cached data, it may happen that the user modified the article data, this situation as long as users refresh the page next time, the user experience is not too bad.
Else
Article = Dbadapter.getarticle (ArticleID, Article!= null);/If the Article is not NULL, the cache data version is too old to update the data removed from the database into the cache

}
}
Class Program {
Static Dictionary<int, articleitem> _articles = new Dictionary<int, articleitem> ();
static void Main (string[] args)
{
Initializing cache
Articlecachemanager.initcache ();
Check to see if a new cache is available
New Thread (Checkcacheproc). Start ();

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, update the article needs to update the version of the database, but also to use a transaction to ensure consistency, need to change existing code, and reduce write performance. But I think this is more than when the user updates the data at the same time to notify the cache server or a simple, so more complex, or to ensure that the design is simple, if the version of the database can not hold the test again this scheme.

2. Because judging the data version number and using the cached data is not an atomic operation, in this intermediate data version number may be updated, so in the case of high concurrency, the user may show the older data, only to refresh the user will find the article version number changed and use the latest data, where the sacrifice of the user experience 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.