前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用Memcache实现分布式的锁服务

用Memcache实现分布式的锁服务

作者头像
joshua317
发布2018-04-16 11:19:05
6470
发布2018-04-16 11:19:05
举报
文章被收录于专栏:技术博文技术博文

一般情况下我们都用Memcache作为一个分布式的key/value缓存服务器,其实Memcache也可以实一些外门邪道的功能比如作为分布式锁来用。

原理其实非常简单就是memecach_add的时候,如果添加的key已经存在那么后面的添加就会失败。设想在高并发的场景下,如果存在被竞争的资源,我们就可以利用这个小trick来对资源加锁。知道了原理实现起来非常简单,下面是我初步实现的代码。

代码语言:javascript
复制
<?php

/**
 * 锁服务(用Memcache模拟锁)
 * Author: tomheng<zhm20070928@gmail.com>
 * gist: https://gist.github.com/tomheng/6149779
 */

class Lock{

    private $mc = null;
    private $key_prefix = "memcache_lock_service_key_";
    private $all_lock_names = array();
    private $expiration = 60; //one min
    private $max_block_time = 15; //最长的阻塞时间
    /**
     * [__construct description]
     */
    public function __construct(){
        if(function_exists('memcache_init')){
            $this->mc = memcache_connect('memcache_host', 11211);
        }
    }

    /**
     * [get_key description]
     * @param  [type] $name [description]
     * @return [type]       [description]
     */
    private function get_key($name){
        $key = $this->key_prefix.$name;
        return $key;
    }

    /**
     * 捕获锁
     * @param  [type] $name [description]
     * @return [type]       [description]
     */
    public  function begin($name, $block = true)
    {
        if(!$this->mc || !$name){
            return false;
        }
        $max_block_time = $this->max_block_time;
        $key = $this->get_key($name);
        do{ 
            $re = memcache_add($this->mc, $key, 1, false, $this->expiration);
            if($re == true){
                $this->all_lock_names[$name] = 1;
                //$this->debug();
                break;
            }else{
                //dolog('Lock failed '.$name);
            }
            //echo '#'.PHP_EOL;
            //sleep(1);
        }while($block && $max_block_time-- && !sleep(1));
        return $re;
    }

    /**
     * 释放锁
     */
    public function release($name){
        if(!$this->mc || !$name){
            return false;
        }
        $key = $this->get_key($name);
        $re = memcache_delete($this->mc, $key);
        if($re == true){
            unset($this->all_lock_names[$name]);
        }
        return $re;
    }

    /**
     * 释放所有的锁
     */
    public function __destruct(){
        if(!$this->mc){
            return false;
        }
        foreach ($this->all_lock_names as $name => $value) {
            # code...
            $this->release($name);
        }
    }

    /**
     * 调试
     * @return [type] [description]
     */
    public function debug(){
        var_dump($this->all_lock_names);
        foreach ($this->all_lock_names as $name => $value) {
            $key = $this->get_key($name);
            if($this->mc){
                $value = memcache_get($this->mc, $key);
            }else{
                $value = "no such lock ";
            }
            echo "Lock name:$key, value:{$value}".PHP_EOL;
        }
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015-07-17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档