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脚本的10个技巧(4)
Oct 09 PHP
理解和运用PHP中的多态性[译]
Aug 02 PHP
php结合ajax实现赞、顶、踩功能实例
May 12 PHP
PHP提交表单失败后如何保留已经填写的信息
Jun 20 PHP
PHP实现将科学计数法转换为原始数字字符串的方法
Dec 16 PHP
php获取错误信息的方法
Jul 17 PHP
分享10段PHP常用代码
Nov 11 PHP
php使用curl并发减少后端访问时间的方法分析
May 12 PHP
thinkphp3.x中变量的获取和过滤方法详解
May 20 PHP
Zend Framework过滤器Zend_Filter用法详解
Dec 09 PHP
Laravel中前端js上传图片到七牛云的示例代码
Sep 04 PHP
PHP连接MySQL数据库的三种方式实例分析【mysql、mysqli、pdo】
Nov 04 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中通过ADO调用Access数据库的方法测试不通过
2006/12/31 PHP
php 数组的创建、调用和更新实现代码
2009/03/09 PHP
Can't create/write to file 'C:\WINDOWS\TEMP\...MYSQL报错解决方法
2011/06/30 PHP
使用php+Ajax实现唯一校验实现代码[简单应用]
2011/11/29 PHP
调试一段PHP程序时遇到的三个问题
2012/01/17 PHP
dvwa+xampp搭建显示乱码的问题及解决方案
2015/08/23 PHP
菜鸟javascript基础资料整理2
2010/12/06 Javascript
一个挺有意思的Javascript小问题说明
2011/09/26 Javascript
html dom节点操作(获取/修改/添加或删除)
2014/01/23 Javascript
Angularjs中使用Filters详解
2016/03/11 Javascript
json传值以及ajax接收详解
2016/05/24 Javascript
jQuery实现简洁的轮播图效果实例
2016/09/07 Javascript
zTree树形菜单交互选项卡效果的实现方法
2017/12/25 Javascript
ng-alain表单使用方式详解
2018/07/10 Javascript
解决element ui select下拉框不回显数据问题的解决
2019/02/20 Javascript
vue使用自定义指令实现拖拽
2021/01/29 Javascript
微信小程序中使用 async/await的方法实例分析
2020/05/06 Javascript
Python ORM框架SQLAlchemy学习笔记之安装和简单查询实例
2014/06/10 Python
使用Protocol Buffers的C语言拓展提速Python程序的示例
2015/04/16 Python
Python正则表达式教程之二:捕获篇
2017/03/02 Python
Python 装饰器深入理解
2017/03/16 Python
Python使用matplotlib填充图形指定区域代码示例
2018/01/16 Python
Flask Web开发入门之文件上传(八)
2018/08/17 Python
解决Python中list里的中文输出到html模板里的问题
2018/12/17 Python
如何使用django的MTV开发模式返回一个网页
2019/07/22 Python
澳大利亚办公室装修:JasonL Office Furniture
2019/06/25 全球购物
彪马香港官方网上商店:PUMA香港
2020/12/06 全球购物
String是最基本的数据类型吗?
2013/06/13 面试题
毕业生找工作的自我评价
2013/10/18 职场文书
操行评语大全
2014/04/30 职场文书
团队拓展活动总结
2014/08/27 职场文书
2014年学生会干事工作总结
2014/11/07 职场文书
2015年“七七卢沟桥事变”纪念活动总结
2015/03/24 职场文书
检讨书范文大全
2015/05/07 职场文书
MongoDB安装使用并实现Python操作数据库
2021/06/28 MongoDB
Java 泛型详解(超详细的java泛型方法解析)
2021/07/02 Java/Android