PHP Redis應用示例

使用消息隊列發佈微博php

使用場景:在一些用戶創造內容的應用中,可能會出現1秒有上千萬個用戶同事發佈消息的狀況,使用mysql極可能形成「too many connections」錯誤,能夠使用redis來下降mysql的併發量mysql

實現思路:使用Redis的List類型做爲消息隊列,把用戶發佈的消息暫時存儲在消息隊列中,接着使用一個conn程序把消息隊列中的消息插入mysql。這樣有效下降mysql併發量redis

實現過程及相關代碼示例算法

1)爲了下降Mysql併發數,先把用戶發佈的微博存在Redissql

//建立reds對象
$redis = new Redis('127.0.0.1', 6379);
$redis->connect();

$weibo_info = [
    'uid' => 1,
    'content' => 'test redis',
    'timestamp' => time()
];

//把微博消息插入到weibo_list隊列
$redis->lpush('weibo_list', json_encode($weibo_info));

$redis->close();

2)把微博存到Redis之後,編寫一個cron程序把redis中的微博信息插入到mysqljson

$redis = new Redis('127.0.0.1', 6379);//建立redis對象
$redis->connect();

while(TRUE) {
    if($redis->lsize('weibo_list') > 0) {
        $info = $redis->rpop('weibo_list');
        $info = json_decode($info);
        //數據插入到mysql的代碼在此省略...
    } else {
        //若是隊列中沒有任務的時候,睡眠1s,讓出cpu給其餘進程
        sleep(1);
    }
}

$redis->close();

使用消息隊列的優缺點:消息隊列存在一個‘延時’的缺點,爲了下降延時,能夠運行多個cron程序同時把消息隊列中的數據插入mysql。使用消息隊列的好處是可擴展性好,當一臺redis服務器不能應付大量併發,使用‘一致性hash算法’把併發分發到不一樣的redis服務器。服務器

Redis替換文件存儲Sessionsession

使用場景:PHP默認使用文件存儲session,若是併發量大,效率很是低。而Redis對高併發的支持很是好併發

實現過程及相關代碼示例函數

1)編寫一個session管理類SessionManager,主要用來鏈接redis服務器,使用session_set_save_handler函數設置session回調函數,並調用session_start函數開啓session功能

class SessionManager
{
    private $redis;//redis對象
    private $sessionSavePath;
    private $sessionName;
    private $sessionExpireTime = 30;

    public function __construct()
    {
        $this->redis = new Redis();
        $this->redis->connect('127.0.0.1', 6379);

        //設置回調函數,php.ini配置文件的session.save_haandler選項需設置爲user,纔會生效
        $retval = session_set_save_handler(
            [$this, 'open'],
            [$this, 'close'],
            [$this, 'read'],
            [$this, 'write'],
            [$this, 'destroy'],
            [$this, 'gc']
        );

        session_start();//開啓session功能
    }

    //當session打開時調用此函數。第一個參數是保持session的路徑,第二個參數是session的名字
    public function open($path, $name) {
        return true;
    }

    //當session操做完成調用此函數
    public function close() {
        return true;
    }

    //以sessionId做爲參數。經過sessionId從數據存儲方取出數據,並返回此數據
    public function read($id) {
        $value = $this->redis->get($id);
        if($value) {
            return $value;
        } else {
            return '';
        }
    }

    //以sessionId做爲key,把session的數據做爲value存儲到redis服務器,設置session的過時時間爲30s
    public function write($id, $data) {
        if($this->redis->set($id, $data)) {
            $this->redis->expire($id, $this->sessionExpireTime);
            return true;
        }

        return false;
    }

    //以sessionId做爲key從redis服務器中刪除對應的session數據
    public function destroy($id) {
        if($this->redis->delete($id)) {
            return true;
        }

        return false;
    }

    //當PHP執行session垃圾回收機制時觸發
    public function gc($maxlifetime) {
        return true;
    }

    public function __destruct() {
        session_write_close();//關閉session
    }
}

2)包含SessionManager類,實例化一個SessionManager對象

include 'SessionManager.php';

new SessionManager();//開啓session管理

$_SESSION['username'] = 'Rita';//建立一個名爲username的session變量

echo $_SESSION['username'];//獲取一個session變量名爲username的值
相關文章
相關標籤/搜索