PHP结合Redis+MySQL实现冷热数据交换应用案例详解


Posted in PHP onJuly 09, 2019

本文实例讲述了PHP结合Redis+MySQL实现冷热数据交换应用案例。分享给大家供大家参考,具体如下:

场景:某网站需要对其项目做一个投票系统,投票项目上线后一小时之内预计有100万用户进行投票,希望用户投票完就能看到实时的投票情况

这个场景可以使用redis+mysql冷热数据交换来解决。

何为冷热数据交换?

冷数据:之前使用的数据,热数据:当前使用的数据。
交换:将Redis中的数据周期的存储到MySQL中

业务流程

用户进行投票后,首先将投票数据保存到Redis中,这些数据就是热数据,然后定期(如5s)将热数据保存到MySQL中,这些数据就变为冷数据,然后将冷数据从Redis中删除,周而复始,知道一个小时投票结束。

项目结构图

PHP结合Redis+MySQL实现冷热数据交换应用案例详解

index.html文件

这是投票的首页,有3个投票按钮,模拟给3个用户投票,点击按钮,使用ajax调用vote.php文件

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
  <title>Document</title>
</head>
<script src="http://lib.sinaapp.com/js/jquery/1.9.1/jquery-1.9.1.min.js"></script>
<body>
  <p><span id="uid1">0</span><input type="button" value="用户1" onclick="vote(1);" /></p>
  <p><span id="uid2">0</span><input type="button" value="用户2" onclick="vote(2);" /></p>
  <p><span id="uid3">0</span><input type="button" value="用户3" onclick="vote(3);" /></p>
</body>
<script>
  function vote(i){
    $.get('vote.php?uid='+i,function(rs){
      var span = '#uid'+i;
      $(span).html(rs);
    });
  }
</script>
</html>

vote.php

这个文件主要实现投票的逻辑。首先连接上Redis服务器,然后保存投票人id,然后将投票人id为key记录每个用户的票数,然后返回给index.html文件,最后使用global_voteid作为key记录总票数,也可以作为MySQL的自增长的键。然后记录uid,ip,time等数据。

注意格式有一定的要求:

假如voteid为3,记录的是ip,那么键为vote:3:ip:127.0.0.1

<?php
$redis = new Redis();
$redis->connect('localhost',6379);
//计算每个用户的总票数
$uid = intval($_GET['uid']);
//$uid = mt_rand(1,3);//随机指定投票人员,方便进行压力测试
echo $redis->incr($uid);
$voteid = $redis->incr('global_voteid');
$redis->set('vote:'.$voteid.':uid',$uid);
$ip = $_SERVER['REMOTE_ADDR'];
$redis->set('vote:'.$voteid.':ip',$ip);
$redis->set('vote:'.$voteid.':time',time());

重点内容

这个文件主要实现冷热数据交换,首先连接MySQL数据库和redis服务器,然后每隔5秒去执行while循环,在while循环里获取自增长的投票主键和最近一次插入mysql的投票主键(位置)。判断插入的位置是否存在,如果不存在就从头插入,如果全部插入完毕,就进行等待,如果没有插入完毕,就进行插入操作。

<?php
//连接数据库
$pdo = new PDO('mysql:host=localhost;dbname=test','root','1234');
$pdo->query('set names utf8');
//连接redis
$redis = new Redis();
$redis->connect('localhost',6379);
//永真循环
while(true){
  $vid = $redis->get('global_voteid');//自增长的主键
  $last = $redis->get('last');//最近一次插入mysql的投票主键
  //如果没有插入数据库,刚开始的肯定为true
  if(!$last){
    $last = 0;//设置为0
  }
  //如果所有的数据都被插入到MySQL中
  if($vid == $last){
    echo "wait\n";//输出等待
  }else{
    //进行插入到数据库操作
    $sql = 'insert into vote(vid,uid,ip,time) values';
    for($i = $vid;$i>$last;$i--){
      $k1 = 'vote:'.$i.':uid';
      $k2 = 'vote:'.$i.':ip';
      $k3 = 'vote:'.$i.':time';
      $row = $redis->mget([$k1,$k2,$k3]);
      $sql.="($i,$row[0],'$row[1]',$row[2]),";
            $redis->delete($k1,$k2,$k3);
    }
    $sql = substr($sql,0,-1);
    $pdo->exec($sql);
    $redis->set('last',$vid);//设置插入的主键位置
    echo 'OK';
  }
  sleep(5);//每隔5秒执行循环
}

vote表

PHP结合Redis+MySQL实现冷热数据交换应用案例详解

运行步骤:

1、使用php命令行工具调用swap.php

PHP结合Redis+MySQL实现冷热数据交换应用案例详解

2、使用Apache的ab工具进行压力测试。

PHP结合Redis+MySQL实现冷热数据交换应用案例详解

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
php的计数器程序
Oct 09 PHP
DISCUZ 分页代码
Jan 02 PHP
php代码审计比较有意思的例子
May 07 PHP
让codeigniter与swfupload整合的最佳解决方案
Jun 12 PHP
destoon二次开发模板及调用语法汇总
Jun 21 PHP
destoon实现VIP排名一直在前面排序的方法
Aug 21 PHP
PHP实现格式化文件数据大小显示的方法
Jan 03 PHP
thinkPHP学习笔记之安装配置篇
Mar 05 PHP
DEDE实现转跳属性文档在模板上调用出转跳地址
Nov 04 PHP
浅谈ThinkPHP5.0版本和ThinkPHP3.2版本的区别
Jun 17 PHP
PHP单例模式模拟Java Bean实现方法示例
Dec 07 PHP
laravel-admin 实现给grid的列添加行数序号的方法
Oct 08 PHP
PHP+Redis开发的书签案例实战详解
Jul 09 #PHP
使用composer命令加载vendor中的第三方类库 的方法
Jul 09 #PHP
Laravel+Intervention实现上传图片功能示例
Jul 09 #PHP
Laravel框架实现多个视图共享相同数据的方法详解
Jul 09 #PHP
Laravel5.1框架注册中间件的三种场景详解
Jul 09 #PHP
PHP使用 Pear 进行安装和卸载包的方法详解
Jul 08 #PHP
PHP 7.4中使用预加载的方法详解
Jul 08 #PHP
You might like
php扩展ZF――Validate扩展
2008/01/10 PHP
php获取服务器信息的实现代码
2013/02/04 PHP
PHP仿博客园 个人博客(1) 数据库与界面设计
2013/07/05 PHP
关于PHP文件的自动运行方法分析
2016/05/13 PHP
Yii中的relations数据关联查询及统计功能用法详解
2016/07/14 PHP
window.onload 加载完毕的问题及解决方案(上)
2009/07/09 Javascript
JavaScript 事件系统
2010/07/22 Javascript
浅谈JavaScript中运算符的优先级
2015/07/07 Javascript
jQuery前端开发35个小技巧
2016/05/24 Javascript
vue按需加载实例详解
2019/09/06 Javascript
Layui表格行工具事件与数据回填方法
2019/09/13 Javascript
layui字体图标 loading图标静止不旋转的解决方法
2019/09/23 Javascript
基于Vue 撸一个指令实现拖拽功能
2019/10/09 Javascript
vue接口请求加密实例
2020/08/11 Javascript
Javascript var变量删除原理及实现
2020/08/26 Javascript
JS绘图Flot如何实现可选显示曲线图功能
2020/10/16 Javascript
JavaScript对象访问器Getter及Setter原理解析
2020/12/08 Javascript
windows下wxPython开发环境安装与配置方法
2014/06/28 Python
python实现上传样本到virustotal并查询扫描信息的方法
2014/10/05 Python
Python Web框架Flask下网站开发入门实例
2015/02/08 Python
Python与Redis的连接教程
2015/04/22 Python
详细解读Python中解析XML数据的方法
2015/10/15 Python
Python简单实现TCP包发送十六进制数据的方法
2016/04/16 Python
Python机器学习之K-Means聚类实现详解
2018/02/22 Python
Python实现的企业粉丝抽奖功能示例
2019/07/26 Python
Python计算指定日期是今年的第几天(三种方法)
2020/03/26 Python
Python面向对象特殊属性及方法解析
2020/09/16 Python
使用CSS3在触屏上为按钮实现激活效果
2013/09/27 HTML / CSS
html5 input输入实时检测以及延时优化
2018/07/18 HTML / CSS
人力资源管理毕业生自荐信
2013/11/21 职场文书
电信营业员自我评价分享
2014/01/17 职场文书
绿化先进工作者事迹材料
2014/01/30 职场文书
工程师岗位职责规定
2014/02/26 职场文书
2015入党个人自传范文
2015/06/26 职场文书
中国梦宣传标语口号
2015/12/26 职场文书
漫画《尖帽子的魔法工坊》宣布动画化
2022/04/06 日漫