使用消息队列发布微博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的值