redisは負荷等化を実現し,ハッシュテーブルで格納し,削除する
12104 ワード
CIフレームワークへの統合
コントローラで呼び出す:
本文は“life is gonna be better”のブログから出て、転載して作者と連絡してください!
<?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”のブログから出て、転載して作者と連絡してください!