-一个简单的数据缓存解决方案

最近做了一个聊天室系统,系统有N个聊天室,在并发量很大的情况下,如果用户聊天记录直接写入MySql的话,对数据库的冲击会很大。这里我写了个简单的解决方案:聊天数据先存入redis的队列中,然后用crontab每隔1分钟执行PHP脚本,把数据从redis队列中“批量”移到mysql。当有多条插入语句时,把数据拼装成1条insert语句,减少数据库的操作次数。

1. 配置文件 config.php

<?php

function dbMessageConfig(){

//用户信息库表的配置

return array(

‘database_type‘ => ‘mysql‘,

‘database_name‘ => ‘test‘,

‘server‘ => ‘127.0.0.1‘,

‘username‘ => ‘root‘,

‘password‘ => ‘root‘,

‘charset‘ => ‘utf8‘

);

}

function redisCacheConfig(){

return array(

‘ip‘ => ‘127.0.0.1‘,

‘port‘ => ‘6379‘,

‘password‘ => ‘888888‘

);

}

2. redis2mysql.php

<?php

error_reporting(E_ALL^E_NOTICE^E_WARNING);

require_once dirname(__FILE__).‘/config.php‘;

$dbMessage = dbMessageConfig();

$configRedis = redisCacheConfig();

$r = new \Redis();

$r->connect($configRedis[‘ip‘], $configRedis[‘port‘]);

$r->auth($configRedis[‘password‘]);

//获取redis中的消息

$message = $r->rpop(‘chat_message‘);

$tenantArr = array();

if(!empty($message)){

$tmpArr = explode(‘:‘, $message);

$tenant_id = $tmpArr[0];

if(!empty($tenant_id) && is_numeric($tenant_id)){

if(!empty($tmpArr[1])) $tenantArr[$tenant_id] = $tmpArr[1];

}

}

//一次最多取20条记录

$MAX_NUM = 20;

$index = 1;

while(!empty($message) && $MAX_NUM > $index){

$message = $r->rpop(‘chat_message‘);

//echo $message;

$tmpArr = explode(‘:‘, $message);

$tenant_id = $tmpArr[0];

if(!empty($tenant_id) && is_numeric($tenant_id)){

if(!empty($tmpArr[1])){

if(array_key_exists($tenant_id, $tenantArr)){

$tmp = $tenantArr[$tenant_id];

$tmp = $tmp.",".$tmpArr[1];

$tenantArr[$tenant_id] = $tmp;

}else{

$tenantArr[$tenant_id] = $tmpArr[1];

}

}

}

$index = $index + 1;

}

$table_message = ‘chat_message‘;

$dbh = new \PDO(‘mysql:host=‘.$dbMessage[‘server‘].‘;dbname=‘.$dbMessage[‘database_name‘], $dbMessage[‘username‘], $dbMessage[‘password‘]);

$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$dbh->exec(‘set names ‘.$dbMessage[‘charset‘]);

foreach ($tenantArr as $tenant_id=>$sql) {

$sqlstr = ‘insert INTO ‘.$table_message.‘_‘.$tenant_id.‘ VALUES ‘.$sql.‘;‘;

$stmt = $dbh->prepare($sqlstr);

$stmt->execute();

}

3. 配置crontab

*/1 * * * * /opt/php/bin/php -f /usr/local/php/redis2mysql.php >/dev/null 2>&1

启动crontab:/sbin/service crond start

4. 写入redis的sql语句(java代码):

//把chatmessage发送到redis储存

Jedis redis = RedisUtil.getJedis();

String key="message";

StringBuffer strMsg = new StringBuffer(tenant_id);

strMsg.append(":(NULL,");

strMsg.append(room_id);

strMsg.append(",");

strMsg.append(uid);

strMsg.append(",‘");

strMsg.append(username);

strMsg.append("‘,");

strMsg.append(user_type);

strMsg.append(",‘");

strMsg.append(avatar);

strMsg.append("‘,‘");

strMsg.append(content);

strMsg.append("‘,");

strMsg.append(add_time);

strMsg.append(",1)");

redis.lpush(key, strMsg.toString());

参考:

⑴ crontab启动 、运行和编辑查看

http://blog.csdn.net/ariessurfer/article/details/7459183

⑵ crontab定时任务配置

http://www.cnblogs.com/kerrycode/p/3238346.html

⑶ php mysql PDO使用

http://blog.csdn.net/qq635785620/article/details/11284591

时间: 2024-09-30 19:31:48

-一个简单的数据缓存解决方案的相关文章

一个简单的数据增量更新策略(Android / MongoDB / Django)

我在做个人APP - CayKANJI - 的时候遇到一个问题: 怎样增量式地把日语汉字数据地从服务器更新到APP端,即每次用户执行更新操作时,只获取版本高于本地缓存的内容. 数据格式 为了能够与mongoDB无缝结合,并省去编写后台代码的麻烦,索性就把汉字数据保存成json文件,上传到服务器后,交给web应用去读取并写入数据库. 汉字文件就是普通的json格式. { "category": "行為ー2", "contents": [ { &qu

一个简单高效的多线程解决方案

import java.io.File; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicInteger; /**  * 多线程抓取数据的简单程序  */ public class MultithreadFetcher { /** 阻塞队列的最大长度,防止内存溢出.  */ pub

一个简单的带缓存http代理

眼下1.0版模型非常easy.即对客户机发来的请求进行简单处理后,转发到server.转发之前先检查本地缓存.假设有.则直接回送给客户本地资源 程序流程大致例如以下图: 缓存是通过把文件保存到磁盘上,然后把索引记录在内存里实现,数据结构例如以下,兴许会考虑加入其它字段.比方时间戳等. typedef struct Cache_node { char name[MAX_LINE_SIZE]; char path[MAX_LINE_SIZE]; struct Cache_node * next; }

分享给大家一个简单的数据导出excel类

<?php /** * 生成excel文件操作 * * @author wesley wu * @date 2013.12.9 */ class Excel { private $limit = 10000; public function download($data, $fileName) { $fileName = $this->_charset($fileName); header("Content-Type: application/vnd.ms-excel; charse

一个简单xml数据转换为数组的方法

本人用easywechat做微信回复图文,从数据库中拿到的数据直接是xml拼好的数据,但是框架只有自带的获取xml格式的语句,所有需要将xml数据中所需要的数据拿出来用来拼接. 搜了好多资料说的都很麻烦.ps:可能是我水平不够;-) ok,废话不多说, 上代码: // 以这个xml数据串为例 $xml = "<item><Title><![CDATA[亲爱的顾客:]]></Title><Content><![CDATA[]]>

一个简单json数据提交实例

1.客户端编程:jsp页面 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd

.net 手写实现一个简单实体数据验证

源于一次面试中的面试题,代码如下所示: public class Product { public string Name { get; set; } public string Description { get; set; } public void Validate1() { if (string.IsNullOrEmpty(this.Name)) { throw new Exception("请输入名称"); } if (string.IsNullOrEmpty(this.De

cache应用(asp.net 2.0 SQL数据缓存依赖 [SqlCacheDependency ] )

Asp.net 2.0 提供了一个新的数据缓存功能,就是利用sql server2005 的异步通知功能来实现缓存 1.首先在sqlserver2005 中创建一个test的数据库. 在SQL Server 2005上执行 ALTER DATABASE <DatabaseName> SET ENABLE_BROKER;语句让相应的数据库启用监听服务,以便支持SqlDependency特性. 添加一个 employee的数据库表. 1CREATETABLE[dbo].[employee](2[i

3.使用闭包实现数据缓存

闭包: 闭包是指可以包含自由(未绑定到特定对象)变量的代码块:这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量).“闭包” 一词来源于以下两者的结合:要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境(作用域).在PHP.Scala.Scheme.Common Lisp.Smalltalk.Groovy.JavaScript.Ruby. Python.Go.Lua.objective