导航:首页 > 编程语言 > mysqlphp缓存机制

mysqlphp缓存机制

发布时间:2025-03-01 00:30:26

A. 网页制作php+mysql如何学习

我看完php的语法,感觉对网页制作没什么帮助--你这句话我能理解,也能看出你是一个辩证性思维比较强的人;我乐意为你解答你的问题。
你应该有过这样的经历吧,那就是你需要在某些网站里注册,那么为什么你离开很多天甚至几年后,你还是其中的会员呢?那就时因为你在注册的时候你输入的信息被存入到了数据库,以PHP+MySQL为例来说,就是PHP有能力把你输入的数据提交给数据库,MySQL数据库就存放了你的信息,等到你下次再登陆的时候呢,PHP就会到MySQL那里去取出数据来。这些算是PHP对网页制作的帮助吧?当然这个是比较浅显的例子,很多论坛,留言板之类的都是通过PHP+MySQL构筑的。
你的第二个问题,还需要什么知识,首先就需要操作数据库的知识,这里分两点,第一点,就是对数据库本身的认识,包括SQL语句,查询优化,使用索引,安全性能,事务与锁,权限设置等等,当然,你开始的时候会DDL DML就可以了,如果这里提到的名词你不是很清楚,你可以在网络上查查,那样你会更加明了;第二点,就是使用PHP来访问数据库,你看完PHP语法,应该要有访问数据库这样的章节才算完整。如果你学的PHP语法都是比较浅显的,那么你还需要更进一步,比如面向对象编程,缓存技术,静态化技术之类的,你要是感觉作用或区别不大,那是因为你没有充分考虑到如果是在大型项目中的情况。当然,需要的知识还很多,比如说PHP框架,JQuery之类的JS库,Samrty之类用用于模板技术的库等等。
你的第三个问题:之后该怎么学。首先要对网络的常识要很清楚,比如HTTP协议,什么是静态网站,什么是动态网站等等;再要清楚自己编写静态网页以及美工方面的功底如何,能够保证很熟练地独立开发一个静态网站来;至于这之后该怎么学,上面说的那些就是你的任务,当然,你还需要进一步了解它们都是怎么一回事,如果需要这样做的话。
你的第四个问题:教材其实很多,也差不多,你有语言功底了以后看什么都容易入门。当然,我看的是澳大利亚的一本PHP & MySQL web 开发第三版,虽然我买了这本书,不过我并不打算建议你去买,你要充分运用好网络资源,包括网络文库,专业名站,视频教材等等,另外,如果英语水平了得的话,建议你看英语原版。
希望你以后的学习会给你带来更多快乐!

B. php redis做mysql的缓存,怎么异步redis同步到mysql数据库

对于变化频率非常快的数据来说,如果还选择传统的静态缓存方式(Memocached、File System等)展示数据,可能在缓存的存取上会有很大的开销,并不能很好的满足需要,而Redis这样基于内存的NoSQL数据库,就非常适合担任实时数据的容器。

但是往往又有数据可靠性的需求,采用MySQL作为数据存储,不会因为内存问题而引起数据丢失,同时也可以利用关系数据库的特性实现很多功能。

所以就会很自然的想到是否可以采用MySQL作为数据存储引擎,Redis则作为Cache。而这种需求目前还没有看到有特别成熟的解决方案或工具,因此采用Gearman+PHP+MySQL UDF的组合异步实现MySQL到Redis的数据复制。

MySQL到Redis数据复制方案

无论MySQL还是Redis,自身都带有数据同步的机制,比较常用的MySQL的Master/Slave模式,就是由Slave端分析Master的binlog来实现的,这样的数据复制其实还是一个异步过程,只不过当服务器都在同一内网时,异步的延迟几乎可以忽略。

那么理论上也可以用同样方式,分析MySQL的binlog文件并将数据插入Redis。但是这需要对binlog文件以及MySQL有非常深入的理解,同时由于binlog存在Statement/Row/Mixedlevel多种形式,分析binlog实现同步的工作量是非常大的。

因此这里选择了一种开发成本更加低廉的方式,借用已经比较成熟的MySQL UDF,将MySQL数据首先放入Gearman中,然后通过一个自己编写的PHP Gearman Worker,将数据同步到Redis。比分析binlog的方式增加了不少流程,但是实现成本更低,更容易操作。

Gearman的安装与使用

Gearman是一个支持分布式的任务分发框架。设计简洁,获得了非常广泛的支持。一个典型的Gearman应用包括以下这些部分:

Gearman Job Server:Gearman核心程序,需要编译安装并以守护进程形式运行在后台

Gearman Client:可以理解为任务的收件员,比如在后台执行一个发送邮件的任务,可以在程序中调用一个Gearman Client并传入邮件的信息,然后就可以将执行结果立即展示给用户,而任务本身会慢慢在后台运行。

Gearman Worker:任务的真正执行者,一般需要自己编写具体逻辑并通过守护进程方式运行,Gearman Worker接收到Gearman Client传递的任务内容后,会按顺序处理。

以前曾经介绍过类似的后台任务处理项目Resque。两者的设计其实非常接近,简单可以类比为:

Gearman Job Server:对应Resque的Redis部分

Gearman Client:对应Resque的Queue操作

Gearman Worker:对应Resque的Worker和Job

这里之所以选择Gearman而不是Resque是因为Gearman提供了比较好用的MySQL UDF,工作量更小。

安装Gearman及PHP Gearman扩展

以下均以Ubuntu12.04为例。

apt-get install gearman gearman-server libgearman-dev

检查Gearman的运行状况:

/etc/init.d/gearman-job-server status

* gearmand is running

说明Gearman已经安装成功。

PHP的Gearman扩展可以通过pecl直接安装

pecl install gearman

echo "extension=gearman.so">/etc/php5/conf.d/gearman.ini

service php5-fpm restart

但是实测发现ubuntu默认安装的gearman版本过低,直接运行pecl install gearman会报错

configure: error: libgearman version 1.1.0or later required

因此Gearman + PHP扩展建议通过编译方式安装,这里为了简单说明,选择安装旧版本扩展:

pecl install gearman-1.0.3

Gearman + PHP实例

为了更容易理解后文Gearman的运行流程,这里不妨从一个最简单的Gearman实例来说明,比如要进行一个文件处理的操作,首先编写一个Gearman Client并命名为client.php:

<?php

$client =newGearmanClient();

$client->addServer();

$client->doBackground('writeLog','Log content');

echo '文件已经在后台操作';

运行这个文件,相当于模拟用户请求一个Web页面后,将处理结束的信息返回用户:

php client.php

查看一下Gearman的状况:

(echo status ; sleep 0.1)| netcat127.0.0.14730

可以看到输出为

writeLog 100.

说明已经在Gearman中建立了一个名为writeLog的任务,并且有1个任务在队列等待中。

而上面的4列分别代表当前的Gearman的运行状态:

任务名称

在等待队列中的任务

正在运行的任务

正在运行的Worker进程

可以使用watch进行实时监控:

watch -n 1"(echo status; sleep 0.1) | nc 127.0.0.1 4730"

然后我们需要编写一个Gearman Worker命名为worker.php:

<?php

$worker =newGearmanWorker();

$worker->addServer();

$worker->addFunction('writeLog','writeLog');while($worker->work());function writeLog($job){

$log = $job->workload();file_put_contents(__DIR__ .'/gearman.log', $log ." ", FILE_APPEND | LOCK_EX);}

Worker使用一个while死循环实现守护进程,运行

php worker.php

可以看到Gearman状态变为:

writeLog 001

同时查看同目录下gearman.log,内容应为从Client传入的值Log content。

通过MySQL UDF + Trigger同步数据到Gearman

MySQL要实现与外部程序互通的最好方式还是通过MySQL UDF(MySQL user defined functions)来实现。为了让MySQL能将数据传入Gearman,这里使用了lib_mysqludf_json和gearman-mysql-udf的组合。

安装lib_mysqludf_json

使用lib_mysqludf_json的原因是因为Gearman只接受字符串作为入口参数,可以通过lib_mysqludf_json将MySQL中的数据编码为JSON字符串

apt-get install libmysqlclient-dev

wget https://github.com/mysqludf/lib_mysqludf_json/archive/master.zip

unzip master.zip

cd lib_mysqludf_json-master/

rm lib_mysqludf_json.so

gcc $(mysql_config --cflags)-shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c

可以看到重新编译生成了 lib_mysqludf_json.so 文件,此时需要查看MySQL的插件安装路径:

mysql -u root -pPASSWORD --execute="show variables like '%plugin%';"+---------------+------------------------+|Variable_name|Value|+---------------+------------------------+| plugin_dir |/usr/lib/mysql/plugin/|+---------------+------------------------+

然后将 lib_mysqludf_json.so 文件复制到对应位置:

cp lib_mysqludf_json.so /usr/lib/mysql/plugin/

最后登入MySQL运行语句注册UDF函数:

CREATE FUNCTION json_object RETURNS STRING SONAME 'lib_mysqludf_json.so';

安装gearman-mysql-udf

方法几乎一样:

apt-get install libgearman-dev

wget https://launchpad.net/gearman-mysql-udf/trunk/0.6/+download/gearman-mysql-udf-0.6.tar.gz

tar -xzf gearman-mysql-udf-0.6.tar.gz

cd gearman-mysql-udf-0.6./configure --with-mysql=/usr/bin/mysql_config

-libdir=/usr/lib/mysql/plugin/

make && make install

登入MySQL运行语句注册UDF函数:

CREATE FUNCTION gman_do_background RETURNS STRING SONAME 'libgearman_mysql_udf.so';

CREATE FUNCTION gman_servers_set RETURNS STRING SONAME 'libgearman_mysql_udf.so';

最后指定Gearman服务器的信息:

SELECT gman_servers_set('127.0.0.1:4730');

通过MySQL触发器实现数据同步

最终同步哪些数据,同步的条件,还是需要根据实际情况决定,比如将数据表data的数据在每次更新时同步,那么编写Trigger如下:

DELIMITER $$

CREATE TRIGGER datatoredis AFTER UPDATE ON data

FOR EACH ROW BEGIN

SET @ret=gman_do_background('syncToRedis', json_object(NEW.id as`id`, NEW.volume as`volume`));END$$

DELIMITER ;

尝试在数据库中更新一条数据查看Gearman是否生效。

Gearman PHP Worker将MySQL数据异步复制到Redis

Redis作为时下当热的NoSQL缓存解决方案无需过多介绍,其安装及使用也非常简单:

apt-get install redis-server

pecl install redis

echo "extension=redis.so">/etc/php5/conf.d/redis.ini

然后编写一个Gearman Worker:redis_worker.php

#!/usr/bin/env php<?

$worker =newGearmanWorker();

$worker->addServer();

$worker->addFunction('syncToRedis','syncToRedis');

$redis =newRedis();

$redis->connect('127.0.0.1',6379);while($worker->work());function syncToRedis($job){global $redis;

$workString = $job->workload();

$work = json_decode($workString);if(!isset($work->id)){returnfalse;}

$redis->set($work->id, $workString);}

最后需要将Worker在后台运行:

nohup php redis_worker.php &

通过这种方式将MySQL数据复制到Redis,经测试单Worker基本可以瞬时完成。

C. php+mysql优化,百万至千万级快速分页mysql性能到底能有多高

php+Mysql 优化,百万至千万级快速分页

MySql 性能到底能有多高?用了php半年多,真正如此深入的去思考这个问题还是从前天开始。有过痛苦有过绝望,到现在充满信心!MySql 这个数据库绝对是适合dba级的高手去玩的,一般做一点1万篇新闻的小型系统怎么写都可以,用xx框架可以实现快速开发。可是数据量到了10万,百万至千万,他的性能还能那么高吗?一点小小的失误,可能造成整个系统的改写,甚至更本系统无法正常运行!好了,不那么多废话了。用事实说话,看例子:
数据表 collect ( id, title ,info ,vtype) 就这4个字段,其中 title 用定长,info 用text, id 是逐渐,vtype是tinyint,vtype是索引。这是一个基本的新闻系统的简单模型。现在往里面填充数据,填充10万篇新闻。
最后collect 为 10万条记录,数据库表占用硬盘1.6G。OK ,看下面这条sql语句:
select id,title from collect limit 1000,10; 很快;基本上0.01秒就OK,再看下面的
select id,title from collect limit 90000,10; 从9万条开始分页,结果?
8-9秒完成,my god 哪出问题了????其实要优化这条数据,网上找得到答案。看下面一条语句:
select id from collect order by id limit 90000,10; 很快,0.04秒就OK。为什么?因为用了id主键做索引当然快。网上的改法是:
select id,title from collect where id>=(select id from collect order by id limit 90000,1) limit 10;
这就是用了id做索引的结果。可是问题复杂那么一点点,就完了。看下面的语句
select id from collect where vtype=1 order by id limit 90000,10; 很慢,用了8-9秒!
到了这里我相信很多人会和我一样,有崩溃感觉!vtype 做了索引了啊?怎么会慢呢?vtype做了索引是不错,你直接 select id from collect where vtype=1 limit 1000,10; 是很快的,基本上0.05秒,可是提高90倍,从9万开始,那就是0.05*90=4.5秒的速度了。和测试结果8-9秒到了一个数量级。从这里开始有人提出了分表的思路,这个和discuz 论坛是一样的思路。思路如下:
建一个索引表: t (id,title,vtype) 并设置成定长,然后做分页,分页出结果再到 collect 里面去找info 。 是否可行呢?实验下就知道了。
10万条记录到 t(id,title,vtype) 里,数据表大小20M左右。用
select id from t where vtype=1 order by id limit 90000,10; 很快了。基本上0.1-0.2秒可以跑完。为什么会这样呢?我猜想是因为collect 数据太多,所以分页要跑很长的路。limit 完全和数据表的大小有关的。其实这样做还是全表扫描,只是因为数据量小,只有10万才快。OK,来个疯狂的实验,加到100万条,测试性能。
加了10倍的数据,马上t表就到了200多M,而且是定长。还是刚才的查询语句,时间是0.1-0.2秒完成!分表性能没问题?错!因为我们的limit还是9万,所以快。给个大的,90万开始
select id from t where vtype=1 order by id limit 900000,10; 看看结果,时间是1-2秒!
why 分表了时间还是这么长,非常之郁闷!有人说定长会提高limit的性能,开始我也以为,因为一条记录的长度是固定的,mysql 应该可以算出90万的位置才对啊? 可是我们高估了mysql 的智能,他不是商务数据库,事实证明定长和非定长对limit影响不大?怪不得有人说 discuz到了100万条记录就会很慢,我相信这是真的,这个和数据库设计有关!
难道MySQL 无法突破100万的限制吗???到了100万的分页就真的到了极限???
答案是: NO !!!! 为什么突破不了100万是因为不会设计mysql造成的。下面介绍非分表法,来个疯狂的测试!一张表搞定100万记录,并且10G 数据库,如何快速分页!
好了,我们的测试又回到 collect表,开始测试结论是: 30万数据,用分表法可行,超过30万他的速度会慢道你无法忍受!当然如果用分表+我这种方法,那是绝对完美的。但是用了我这种方法后,不用分表也可以完美解决!
答案就是:复合索引!有一次设计mysql索引的时候,无意中发现索引名字可以任取,可以选择几个字段进来,这有什么用呢?开始的select id from collect order by id limit 90000,10; 这么快就是因为走了索引,可是如果加了where 就不走索引了。抱着试试看的想法加了 search(vtype,id) 这样的索引。然后测试
select id from collect where vtype=1 limit 90000,10; 非常快!0.04秒完成!
再测试: select id ,title from collect where vtype=1 limit 90000,10; 非常遗憾,8-9秒,没走search索引!
再测试:search(id,vtype),还是select id 这个语句,也非常遗憾,0.5秒。
综上:如果对于有where 条件,又想走索引用limit的,必须设计一个索引,将where 放第一位,limit用到的主键放第2位,而且只能select 主键!
完美解决了分页问题了。可以快速返回id就有希望优化limit , 按这样的逻辑,百万级的limit 应该在0.0x秒就可以分完。看来mysql 语句的优化和索引时非常重要的!
好了,回到原题,如何将上面的研究成功快速应用于开发呢?如果用复合查询,我的轻量级框架就没的用了。分页字符串还得自己写,那多麻烦?这里再看一个例子,思路就出来了:
select * from collect where id in (9000,12,50,7000); 竟然 0秒就可以查完!
mygod ,mysql 的索引竟然对于in语句同样有效!看来网上说in无法用索引是错误的!
有了这个结论,就可以很简单的应用于轻量级框架了:
代码如下:
$db=dblink();
$db->pagesize=20;
$sql="select id from collect where vtype=$vtype";
$db->execute($sql);
$strpage=$db->strpage(); //将分页字符串保存在临时变量,方便输出
while($rs=$db->fetch_array()){
$strid.=$rs['id'].',';
}
$strid=substr($strid,0,strlen($strid)-1); //构造出id字符串
$db->pagesize=0; //很关键,在不注销类的情况下,将分页清空,这样只需要用一次数据库连接,不需要再开;
$db->execute("select id,title,url,sTime,gTime,vtype,tag from collect where id in ($strid)");
< php while($rs=$db->fetch_array()): >
<tr>
<td$amp;>amp;$amp;nbsp;< php echo $rs['id']; $amp;>amp;$lt;/td>
<td$amp;>amp;$amp;nbsp;< php echo $rs['url']; $amp;>amp;$lt;/td>
<td$amp;>amp;$amp;nbsp;< php echo $rs['sTime']; $amp;>amp;$lt;/td>
<td$amp;>amp;$amp;nbsp;< php echo $rs['gTime']; $amp;>amp;$lt;/td>
<td$amp;>amp;$amp;nbsp;< php echo $rs['vtype']; $amp;>amp;$lt;/td>
<td$amp;>amp;$amp;nbsp;<a act=show&id=< php echo $rs['id']; $amp;>quot;$ target="_blank"$amp;>amp;$lt; php echo $rs['title']; $amp;>amp;$lt;/a$amp;>amp;$lt;/td>
<td$amp;>amp;$amp;nbsp;< php echo $rs['tag']; $amp;>amp;$lt;/td>
</tr>
< php endwhile; >
</table>
< php
echo $strpage;
通过简单的变换,其实思路很简单:1)通过优化索引,找出id,并拼成 "123,90000,12000" 这样的字符串。2)第2次查询找出结果。
小小的索引+一点点的改动就使mysql 可以支持百万甚至千万级的高效分页!
通过这里的例子,我反思了一点:对于大型系统,PHP千万不能用框架,尤其是那种连sql语句都看不到的框架!因为开始对于我的轻量级框架都差点崩溃!只适合小型应用的快速开发,对于ERP,OA,大型网站,数据层包括逻辑层的东西都不能用框架。如果程序员失去了对sql语句的把控,那项目的风险将会成几何级数增加!尤其是用mysql 的时候,mysql 一定需要专业的dba 才可以发挥他的最佳性能。一个索引所造成的性能差别可能是上千倍!
PS: 经过实际测试,到了100万的数据,160万数据,15G表,190M索引,就算走索引,limit都得0.49秒。所以分页最好别让别人看到10万条以后的数据,要不然会很慢!就算用索引。经过这样的优化,mysql到了百万级分页是个极限!但有这样的成绩已经很不错,如果你是用sqlserver肯定卡死!而 160万的数据用 id in (str) 很快,基本还是0秒。如果这样,千万级的数据,mysql应该也很容易应付。

D. php+mysql可以处理亿级的数据吗

理论上是可以的,但效率上就有问题了,这么大量的数据一般不会放一张表里面,都会考虑分表,然后考虑索引、数据库主从、服务器配置等,提高查询效率php+mysql可以处理亿级的数据吗

阅读全文

与mysqlphp缓存机制相关的资料

热点内容
phpjs倒计时 浏览:230
对啊app怎么样 浏览:74
100个桃子算法 浏览:246
电脑文件jpg加密怎么解除 浏览:328
mapjava用法 浏览:118
全职程序员辞职 浏览:960
程序员那么可爱29集泄露版 浏览:204
中位数java 浏览:688
酒店预定app哪个好 浏览:263
剑网三商城文件夹 浏览:829
地基与基础pdf 浏览:923
方舟编译器运行游戏 浏览:142
zip压缩包乱码 浏览:363
阿里云服务器自带的jdk 浏览:254
linuxshellf 浏览:189
cad图纸加密哪个好 浏览:942
我的世界服务器如何把人拉黑名单 浏览:476
服务器规则怎么设置 浏览:961
小米11ultra无法查看obb文件夹 浏览:253
机顶盒一般内置用什么服务器 浏览:928