redisは負荷等化を実現し,ハッシュテーブルで格納し,削除する


CIフレームワークへの統合
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
 * Created by JetBrains PhpStorm.
 * User: xiaobai
 * Date: 14-9-26
 * Time:   10:33
 * To change this template use File | Settings | File Templates.
 */

class Redis_cluster {
//      M/S        
    private $_isUseCluster = false;
    // Slave     
    private $_sn = 0;

    //        
    private $_linkHandle = array(
        'master'=>null,//       Master
        'slave'=>array(),//       Slave
    );

    protected $_CI = NULL;
    //       
    public $_cache_server_config = array();
    protected static $instance = null;
    /**
     *     
     *
     * @param boolean $isUseCluster      M/S   
     */
    public function __construct(){
        $this->_CI = &get_instance();
        $redis_config_file = $this->_CI->config->load('redis', TRUE, TRUE);
        $redis_config_file_content = $this->_CI->config->item('redis');
        $redis_config_setting = $redis_config_file_content['redis_cluster_config'];
        $redis_config = $redis_config_setting[$redis_config_setting['use_setting']];

        //      M/S        
        if(TRUE == array_key_exists('use_cluster', $redis_config) && (TRUE == is_bool($redis_config['use_cluster']))) {
            $this->_isUseCluster = $redis_config['use_cluster'];
            $this->_cache_server_config = $redis_config['cache_server'];
            $this->connect($this->_cache_server_config['master']);
            //                         
            if(TRUE == $redis_config['use_cluster'] && TRUE == is_array($this->_cache_server_config['slave']) && count($this->_cache_server_config['slave']) > 0) {
                foreach($this->_cache_server_config['slave'] AS $slave_cache) {
                    $this->connect($slave_cache, FALSE);
                }
            } else {
                //          
                $this->_isUseCluster = FALSE;
            }
        } else {
            show_error('Cache Error' , $status_code = 500, 'An Error - Redis config Error');
        }

    }

    /**
     *   
     * @return Service_Redis
     */
    public static function getInstance()
    {
        if( self::$instance == null )
        {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     *      ,  :       ,    ,       
     *
     * @param array $config Redis     
     * @param boolean $isMaster             Master    
     * @return boolean
     */
    public function connect($config=array('host'=>'127.0.0.1','port'=>6379), $isMaster=true){
        // default port
        if(!isset($config['port'])){
            $config['port'] = 6379;
        }
        //    Master   
        if($isMaster){
            $this->_linkHandle['master'] = new Redis();
            $redis_connect = $this->_linkHandle['master']->pconnect($config['host'],$config['port'], $config['timeout']);
            if (isset($config['password']) && FALSE == is_null($config['password']))
            {
                $redis_connect->auth($config['password']);
            }
        }else{
            //    Slave   
            $this->_linkHandle['slave'][$this->_sn] = new Redis();
            $redis_connect = $this->_linkHandle['slave'][$this->_sn]->pconnect($config['host'],$config['port'], $config['timeout']);
            if (isset($config['password']) && FALSE == is_null($config['password']))
            {
                $redis_connect->auth($config['password']);
            }
            ++$this->_sn;
        }
        return $redis_connect;
    }

    /**
     *     
     *
     * @param int $flag      0:   Master 1:   Slave 2:    
     * @return boolean
     */
    public function close($flag=2){
        switch($flag){
            //    Master
            case 0:
                $this->getRedis()->close();
                break;
            //    Slave
            case 1:
                for($i=0; $i<$this->_sn; ++$i){
                    $this->_linkHandle['slave'][$i]->close();
                }
                break;
            //     
            case 2:
                $this->getRedis()->close();
                for($i=0; $i<$this->_sn; ++$i){
                    $this->_linkHandle['slave'][$i]->close();
                }
                break;
        }
        return true;
    }

    /**
     *    Redis             
     *
     * @param boolean $isMaster          true:  Master false:  Slave
     * @param boolean $slaveOne    Slave   true:          Slave   false:     Slave  
     * @return redis object
     */
    public function getRedis($isMaster=true,$slaveOne=true){
        //     Master
        if($isMaster){
            return $this->_linkHandle['master'];
        }else{
            return $slaveOne ? $this->_getSlaveRedis() : $this->_linkHandle['slave'];
        }
    }

    /**
     *    
     *
     * @param string $key   KEY
     * @param string $value    
     * @param int $expire     , 0:       
     */
    public function save($key, $value, $expire=0){
        //     
        if($expire == 0){
            $ret = $this->getRedis()->set($key, $value);
        }else{
            $ret = $this->getRedis()->setex($key, $expire, $value);
        }
        return $ret;
    }

    /**
     *    
     *
     * @param string $key   KEY,        $key = array('key1','key2')
     * @return string || boolean       false,        
     */
    public function get($key){
        //         
        $func = is_array($key) ? 'mGet' : 'get';
        //     M/S
        if(! $this->_isUseCluster){
            return $this->getRedis()->{$func}($key);
        }
        //     M/S
        return $this->_getSlaveRedis()->{$func}($key);
    }


    /*
    // magic function
    public function __call($name,$arguments){
    return call_user_func($name,$arguments);
    }
    */
    /**
     *         ,   key       ,       
     *
     * @param string $key   KEY
     * @param string $value    
     * @return boolean
     */
    public function setnx($key, $value){
        return $this->getRedis()->setnx($key, $value);
    }

    /**
     *     
     *
     * @param string || array $key   KEY,     :"key1"     :array('key1','key2')
     * @return int        
     */
    public function delete($key){
        // $key => "key1" || array('key1','key2')
        return $this->getRedis()->delete($key);
    }

    /**
     *      ,   ++$i ,   key           0        
     *
     * @param string $key   KEY
     * @param int $default        
     * @return int      
     */
    public function incr($key,$default=1){
        if($default == 1){
            return $this->getRedis()->incr($key);
        }else{
            return $this->getRedis()->incrBy($key, $default);
        }
    }

    /**
     *      ,   --$i ,   key           0        
     *
     * @param string $key   KEY
     * @param int $default        
     * @return int      
     */
    public function decr($key,$default=1){
        if($default == 1){
            return $this->getRedis()->decr($key);
        }else{
            return $this->getRedis()->decrBy($key, $default);
        }
    }

    /**
     *        
     *
     * @return boolean
     */
    public function clear(){
        return $this->getRedis()->flushDB();
    }

    /* ===================        =================== */

    /**
     *    HASH    Redis Slave      
     *
     * @return redis object
     */
    private function _getSlaveRedis(){
        //     Slave      
        if($this->_sn <= 1){
            return $this->_linkHandle['slave'][0];
        }
        //    Hash    Slave    
        $hash = $this->_hashId(mt_rand(), $this->_sn);
        return $this->_linkHandle['slave'][$hash];
    }

    /**
     *   ID   hash   0~m-1     
     *
     * @param string $id
     * @param int $m
     * @return int
     */
    private function _hashId($id,$m=10)
    {
        //    K    0~m-1                  
        $k = md5($id);
        $l = strlen($k);
        $b = bin2hex($k);
        $h = 0;
        for($i=0;$i<$l;$i++){
            //    HASH
            $h += substr($b,$i*2,2);
        }
        $hash = ($h*1)%$m;
        return $hash;
    }

    /**
     *    lpush
     */
    public function lpush($key,$value){
        return $this->getRedis()->lpush($key,$value);
    }

    /**
     *    add lpop
     */
    public function lpop($key){
        return $this->getRedis()->lpop($key);
    }
    /**
     * lrange
     */
    public function lrange($key,$start,$end){
        //     M/S
        if(! $this->_isUseCluster){
            return $this->getRedis()->lrange($key,$start,$end);
        }
        //     M/S
        return $this->_getSlaveRedis()->lrange($key,$start,$end);
    }

    /**
     *    set hash opeation
     */
    public function hset($name,$key,$value){
        if(is_array($value)){
            return $this->getRedis()->hset($name,$key,serialize($value));
        }
        return $this->getRedis()->hset($name,$key,$value);
    }
    /**
     *    get hash opeation
     */
    public function hget($name,$key = null,$serialize=true){
        //     M/S
        if(! $this->_isUseCluster){
            $redis = $this->getRedis();
        } else {
            //     M/S
            $redis = $this->_getSlaveRedis();
        }
        if($key){
            $row = $redis->hget($name,$key);
            if($row && $serialize){
                $row = unserialize($row);
            }
            return $row;
        }
        return $redis->hgetAll($name);
    }

    /**
     *    delete hash opeation
     */
    public function hdel($name,$key = null){
        if($key){
            return $this->getRedis()->hdel($name,$key);
        }
        return $this->getRedis()->hdel($name);
    }
    /**
     * Transaction start
     */
    public function multi(){
        return $this->getRedis()->multi();
    }
    /**
     * Transaction send
     */

    public function exec(){
        return $this->getRedis()->exec();
    }

    public function __destruct(){
        $this->close(2);
    }
}
/* End of file Redis.php */

コントローラで呼び出す:
    public function run(){
            $this->load->library('redis_cluster');
            
            $this->redis_cluster->hset('hash','log_925','error_status=0');
            $this->redis_cluster->hset('hash','log_926','error_status=0');
            $this->redis_cluster->hset('hash','log_927','error_status=0');
            
            var_dump($this->redis_cluster->hget('hash'));
            
            $this->redis_cluster->hdel('hash','log_925');
            
            var_dump($this->redis_cluster->hget('hash'));
            var_dump($this->redis_cluster->multi());
            
            $this->redis_cluster->connect();
            $this->redis_cluster->save('log','record_nothing');
            var_dump($this->redis_cluster->get('log'));
            $this->redis_cluster->delete('log');
            var_dump($this->redis_cluster->get('log'));
        }

本文は“life is gonna be better”のブログから出て、転載して作者と連絡してください!