[ArticleAuthor: Sun Li link: http://www.cnblogs.com/sunli/ updated by: 2010-07-27]
Last Saturday, I attended the csdn Tup event. In the last session, Tim Yang talked about Weibo cache design. I personally think it is very good and well-spoken, two of them are very similar, that is, the Intranet traffic problem and the cache key mutex problem cause a large number of requests to penetrate into the database. Then he wrote another blog 《Memcache mutex Design Mode. The key mutex problem of cache has been encountered many times during my development, so I will discuss my solution here. The problem arises as follows:
Figure 1: Key mutex
The cache I mentioned here is not limited to memcached. In fact, key mutex is required in many occasions. For example, the lock of the opportunity record set mentioned in InnoDB in MySQL can also be used as the key mutex.
Key mutex of HTTP reverse proxy server Cache
I developed a reverse proxy server icproxy (similar to squid, varnish, etc.) for a system that was not very high at the time, but was difficult to optimize in a short time, to improve the system performance. But soon the problem came,
During peak hours, such
- A hot news page, set cache for 5 minutes
- Five minutes later, a large number of requests will be marked with invalid cache at the same time.
- A large number of requests are simultaneously routed to the backend Web server for loading data to the cache, resulting in frequent backend downtime.
This is the key mutex problem. There is no lock on requests for unified resources to restrict access penetration. Because icproxy is developed in Java, It is very convenient to use the lock for control. No post here Source code I believe you know how to implement it.
Key mutex of memcached The key mutex problem of memcached has been clearly stated in Tim Yang's blog "memcache mutex design mode", and two solutions are also mentioned. The solution to the problem is as follows: We have also encountered this problem in our previous systems, So I developed a phplock project. Because we used PHP in the previous section, I will add another method for PHP. Method 3:
Code<?PHP
// Get memcached instance
$ Cache = Ifengmem :: Getinstance ( ' Bbsmemcache ' );
// Obtain cached data
$ Result = $ Cache -> Get ( $ Cachekey );
If ( $ Result === False ){
Require_once ' Class/class. phplock. php ' ;
// Initialization lock, $ cachekey must be passed in for internal hash
$ Lock = New Phplock ( ' Locks/ ' , $ Cachekey );
$ Lock -> Startlock ();
// Lock
$ Lock -> Lock ();
// After entering the lock, query the cache once to see if data already exists.
$ Result = $ Cache -> Get ( $ Cachekey );
// If there is still no data, it means you are the most advanced to go to the lock, query the database and load it to the cache
If ( $ Result === False ){
$ Query = $ DB -> Query ( $ SQL );
$ Result = $ DB -> Fetcharray ( $ Query );
$ Cache -> Set ( $ Cachekey , $ Result , $ Cachetime );
}
// Release lock
$ Lock -> Unlock ();
$ Lock -> Endlock ();
}
?>
You can get phplock at http://code.google.com/p/phplock.
In PHP applications, especially fast-CGI applications based on nginx, you should optimize your queries as much as possible so that they can be as fast as possible and shorten lock wait, otherwise, system load will rise sharply, whether it is penetrating the back-end dB or waiting for the lock. You can check whether backend threads can update the cache based on your system's business conditions.
Note:
In the above scenarios, the use of locks actually uses the separation lock, that is, to hash a large number of resources that need to be locked to a specified number of locks to avoid excessive locks, that is, instead of directly performing global lock (), this will reduce the system throughput. In phplock, there is a $ hashnum that can be set to the number of hash buckets, that is, the number of keys that can be accessed at the same time, which also avoids the penetration of a large number of different keys to the database. phplock is a single-host version and may be used by multiple machines.Max number of machinesIf there are not many web servers, there will be no problems.
Extended Application of key mutex
In many systems, we need to perform time-consuming operations on a resource, such as slice downloads, network requests, data queries, and searches. Due to the high concurrency, if a large number of requests are sent to the same resource and different resources, the key mutex scenario is applicable. When developing a nosql database, you must consider this issue.
For example, you need to develop a data accumulators similar to memcached's increment,
You may not want
Lock. Lock ();
IntNum=Storage. Get (key );
Storage. Set (Key, num+1);
Lock. Unlock ();
The following method is used to increase the throughput.
Lock. Lock (key );
IntNum=Storage. Get (key );
Storage. Set (Key, num+1);
Lock. Unlock (key );
This is similar to the concepts of mysiam and InnoDB table locks and row locks in MySQL. Obviously, the concurrency capability of row locks is much higher than that of table locks.