Memcached and Redis distributed lock scheme

Source: Internet
Author: User

Distributed cache can solve the bottleneck that the memory of single server cannot expand indefinitely. In distributed cache applications, you encounter multiple client contention issues. At this time, a distributed lock is required, and the client with the lock has permission to operate.

Memcached and Redis are common distributed cache building schemes, and the following are examples of implementation methods based on Memcached and Redis distributed locks.

Memcached Distributed lock

Memcached can use the Add command, which is added only if the key does not exist , or is not processed. Memcached all commands are atomic and add the same key concurrently, only one will succeed.

Using this principle, a lock lockkey can be defined first, and add succeeds in thinking that it is getting the lock. and set the [ Expiration timeout ] Time to ensure that there is no deadlock after the outage .

After the specific operation, determine whether this operation has timed out. If the timeout is not removed, the lock is removed if it does not time out.

Pseudo code:

1          if(MC. ADD ("Lockkey","Value", ExpiredTime))2             {3                 //Get the lock4                 Try5                 {6                     //Do business function7 8                     //Check Timeout9                     if(!checkedtimeout ())Ten                     { OneMc. Delete ("Lockkey"); A                     } -                 } -                 Catch(Exception e) the                 { -Mc. Delete ("Lockkey"); -                 } -                 +}

Redis Distributed Locks

Redis does not have an add command, but there is setnx(SET if not eXists) if the given key already exists, then SETNX does not do any action. Set success, return 1 . Setting failed, returns 0 .

The SETNX command cannot set the expiration time, and you need to use the EXPIRE command to set the expiration time.

Pseudo code:

            int lockresult = Rd. Setnx ("Lockkey", "Value");            if (Lockresult = = 1)            {                //[1] get lock                //[2] Set timeout expiration Time                Rd. EXPIRE ("Lockkey", expiredtime);                Try                {                    //do business  function                    //Check timeout                    if (! Checkedtimeout ())                    {                        Rd. DEL ("Lockkey");                    }                }                catch (Exception e)                {                    Rd. DEL ("Lockkey");                }            }

There is a great potential risk to this approach. [1] After the lock is taken, then [2] is set to expire. If the outage occurs during this period, the expiration time is not set. The default cache expiration policy for Redis, this lock will not be released, resulting in deadlocks.

Therefore, it is not recommended to use this method to implement the lock timeout expiration policy in other ways:

1:setnx value = Current time + expiration timeout, return 1 get lock, return 0 does not get lock. Ext. 2.

2: get gets the value. Determines whether the lock has expired timeout. If timed out, turn 3.

3:getset ( The value of the given key is set to value and the old value of key is returned ),getset value = Current time + The expiration time-out period, the value of which is determined if it is still timed out, that means to get the lock, otherwise did not get the lock.

From 2 to 3, the timeout will be overwritten multiple times, but this will not have any effect.

Pseudo code:

            String expiredtime = DateTime.Now.AddMinutes (locktimeoutminutes).            ToString (); int lockresult = Rd.            Setnx ("Lockkey", ExpiredTime);            BOOL Getlock = false;            if (Lockresult = = 1) {//Get lock Getlock = true; } else {string curexpiredtime = Rd.                GET ("Lockkey"); Check lock Timeout if (Checkedlocktimeout (ExpiredTime)) {ExpiredTime = DateTime.Now . AddMinutes (locktimeoutminutes).                    ToString ();                    String newexpiredtime = Getset (ExpiredTime);  if (Checkedlocktimeout (newexpiredtime)) {//get lock Getlock =                    True                    }}} if (Getlock) {try { Do business function//Check timeout if (! CheckedtiMeout ()) {Rd.                    DEL ("Lockkey"); }} catch (Exception e) {Rd.                DEL ("Lockkey"); }            }

Personally, the practice is still imperfect.

Zookeeper distributed lock, the next chapter to study.

Reference:

Zheng, e-commerce topic V: Distributed lock jeffkit with Redis for distributed locks

Memcached and Redis distributed lock scheme

Related Article

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.