Memcached (18) Concurrent primitive CAs and gets operations

Source: Internet
Author: User
Tags cas memcached redis

In my own project recently, I met the demand for optimistic locking. But Redis does not have this operation, helpless, see memcache natural Support this concurrency primitive, namely: Gets and CAS operation. Therefore, the readiness to continue using Redis, the business is not so strong timing execution requirements, so you can use the algorithm without CAs to some extent to solve.
Why should we use this concurrency primitive? If it is a stand-alone version, we can solve the timing problem by locking the synchronization. But our application is distributed, stateless application servers are load balanced and deployed to multiple units. Locking also solves the sequential execution of multiple servers.

If you do not use CAs, you have the following scenario:
The first step, a takes out the data object X;
In the second step, B takes out the data object X;
In the third step, B modifies the data object X and puts it into the cache;
Fourth, a modifies the data object X and puts it into the cache.
We can see that the fourth step results in a data write conflict.

if the CAS protocol is used, it is the following scenario.
The first step, a takes out the data object X, and obtains to the CAS-ID1;
In the second step, B takes out the data object X and gets to the CAS-ID2;
In the third step, B modifies the data object X, before writing the cache, to check whether the Cas-id is consistent with the cas-id of the data in the cache space. The result is "consistent", which writes the modified X with Cas-id2 to the cache.
Fourth, a modifies the data object Y, before writing the cache, to check whether the Cas-id is consistent with the cas-id of the data in the cache space. The result is "inconsistent", the write is rejected, and the storage failure is returned.
We can resolve the failure of the fourth step setting by retrying, or by other business logic. no CAS program

Redis is generally used with this algorithm, which can be guaranteed to a certain degree of timing.
Setnx Key value
Set the value of key to value when and only if key does not exist.
return value:
Set success, return 1.
Setting failed, returns 0.

The initial solution:
Use the atomicity of the memcached add operation to control concurrency in the following ways:
1. Request a lock: Before verifying whether the activity was created, the add Operation key is key, and if the add operation fails, it means that there is another process that creates an activity for the key concurrently, and returns the creation failure. Otherwise, no concurrency is indicated
2. Execute the Create activity
3. Release Lock: After the creation activity is complete, delete the key by performing a delete operation.

    if (memcache.get (key) = = NULL) {  
        //3 min timeout to avoid mutex holder crash  
        if (Memcache.add (Key_mutex, 3 * 60 * () = = True) {  
            value = Db.get (key);  
            Memcache.set (key, value);  
            Memcache.delete (Key_mutex);  
        } else {  
            sleep ();  
            Retry ();  
        }  
    }  

Problem:
1.memcached stored in the value of the expiration date, that is, after the expiry of the automatic invalidation, such as add after M1, M1 failure, can be successful in this add
2. Even through the configuration, you can make memcached permanent effective, that is, there is no expiration date, memcached capacity limit, when the capacity is not enough will be automatically replaced, that is, it is possible to add over M1, M1 by the other key value replacement, then add can be successful.
3. In addition, the memcached is memory-based, the data will be lost after power-down, causing all MemberID to be re-add after reboot.
Solution Solutions
For the above problems, the root cause is that the add operation is timely, expired, replaced, restarted, will invalidate the original add operation. There are ways to solve this problem 1. Mitigate the effects of timeliness by using memcached CAS (check and set) mode.

The fundamentals of CAs
The basic principle is very simple, word, is the "version number." Each stored data object has more than one version number. We can understand from the following examples:

    Final getsresponse<object> response = memcachedclient.gets ("key");  
    Boolean flag = Memcachedclient.cas ("Key", new Casoperation<object> () {  
        @Override public  
        int Getmaxtries ( {  
            //Retry count  
            return 1;  
        }  

        @Override Public  
        Object Getnewvalue (Long Currentcas,  
                                   object currentvalue) {  
            Oldcas = Response.getcas (); C11/>if (Checkcas ()) {//compare cas value value  
                = Db.get (key);  
                return value;  
            } else{  
                //throws an exception, or other business logic}}  
    );  
      

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.