使用消息隊列發佈微博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的值