php 关于锁的一些看法
2013-12-14 23:58
330 查看
背景:在一个项目中,需要一次对数据很复杂的计算,其中一次计算需要花费大概30秒钟时间,大概需要查询一个比较大的表300次左右,然后还需要进行查询7-8次数据库,然后进行组合排序等功能,完成最终结果。对于一个估算平均10w次的一个接口来说,无论从时间上讲和对于数据库的压力来说,这是完全不能接受的,但很幸运的是我们的需求只要求数据每天更新一次。
为此我们有了三种方法
第一种方案:这个方案是我一个同事提出,对300次查询进行优化,把计算结果规为一个表的一个属性,每天定时脚本得出这个属性,,这样查询只需7-8次就能完成。
第二种方案:这个方案是我另一个同事提出,对整个结果进行存储,这样就需要一句sql就能搞定,但是每天需要有一次比较长的查询排序放在一个结果表里面。
第三种方案:是我提出,为什么不把数据放在一个文件里面呢,这样数据库一次查询都没有了,不是降低了每天10w次的访问吗?于是我同事跟我说到进程同步问题,我很是迷茫,php不是有加锁功能吗?为什么不能放在一个文件里面,在使用file_put_content 加入LOCK_EX不是能预防读写锁问题吗。随着数据的增多,为什么一定要用数据库呢,几乎所有的瓶颈都是数据库上面,为什么不能尽量减少数据库的负担呢。于是我做了以下一些实验。
编写两个程序
process1:
set_time_limit(-1);
$filename="D://text.txt";
for($i=0;$i<100;$i++){
file_put_contents($filename, $i,FILE_APPEND|LOCK_EX);
sleep(1);
}
process2:
<?php
set_time_limit(-1);
$filename="D://text.txt";
$string = file_get_contents($filename);
for($i=0;$i<100;$i++){
if(empty($string)){
echo error_get_last().var_dump($string).'<br>';
}else{
echo $string."<br>";
}
sleep(1);
}
因为使用不同浏览器验证,我不知道这会不会产生什么影响。但是结果却是加锁后proceess2只能获得未加锁的内容。还是找不到关于为什么不能使用文件的原因,如果说数据完整和一致性管理上,第三种方法有他的劣势。但是我觉得跟进程无关。希望有人能回答我这些问题
另附我查询到的一些php锁资料
flock -- 轻便的咨询文件锁定
PHP 支持以咨询方式(也就是说所有访问程序必须使用同一方式锁定, 否则它不会工作)锁定全部文件的一种轻便方法。
注:
在 Windows 下 flock() 将会强制执行。
flock() 操作的 handle
必须是一个已经打开的文件指针。operation
可以是以下值之一:
要取得共享锁定(读取程序),将
operation 设为 LOCK_SH(PHP 4.0.1 以前的版本设置为 1)。
要取得独占锁定(写入程序),将
operation 设为 LOCK_EX(PHP 4.0.1 以前的版本中设置为 2)。
要释放锁定(无论共享或独占),将
operation 设为 LOCK_UN(PHP 4.0.1 以前的版本中设置为 3)。
如果你不希望 flock() 在锁定时堵塞,则给
operation 加上 LOCK_NB(PHP 4.0.1 以前的版本中设置为 4)。
为此我们有了三种方法
第一种方案:这个方案是我一个同事提出,对300次查询进行优化,把计算结果规为一个表的一个属性,每天定时脚本得出这个属性,,这样查询只需7-8次就能完成。
第二种方案:这个方案是我另一个同事提出,对整个结果进行存储,这样就需要一句sql就能搞定,但是每天需要有一次比较长的查询排序放在一个结果表里面。
第三种方案:是我提出,为什么不把数据放在一个文件里面呢,这样数据库一次查询都没有了,不是降低了每天10w次的访问吗?于是我同事跟我说到进程同步问题,我很是迷茫,php不是有加锁功能吗?为什么不能放在一个文件里面,在使用file_put_content 加入LOCK_EX不是能预防读写锁问题吗。随着数据的增多,为什么一定要用数据库呢,几乎所有的瓶颈都是数据库上面,为什么不能尽量减少数据库的负担呢。于是我做了以下一些实验。
编写两个程序
process1:
set_time_limit(-1);
$filename="D://text.txt";
for($i=0;$i<100;$i++){
file_put_contents($filename, $i,FILE_APPEND|LOCK_EX);
sleep(1);
}
process2:
<?php
set_time_limit(-1);
$filename="D://text.txt";
$string = file_get_contents($filename);
for($i=0;$i<100;$i++){
if(empty($string)){
echo error_get_last().var_dump($string).'<br>';
}else{
echo $string."<br>";
}
sleep(1);
}
因为使用不同浏览器验证,我不知道这会不会产生什么影响。但是结果却是加锁后proceess2只能获得未加锁的内容。还是找不到关于为什么不能使用文件的原因,如果说数据完整和一致性管理上,第三种方法有他的劣势。但是我觉得跟进程无关。希望有人能回答我这些问题
另附我查询到的一些php锁资料
flock
(PHP 3 >= 3.0.7, PHP 4, PHP 5)flock -- 轻便的咨询文件锁定
说明
bool flock ( int handle, int operation [, int &wouldblock] )PHP 支持以咨询方式(也就是说所有访问程序必须使用同一方式锁定, 否则它不会工作)锁定全部文件的一种轻便方法。
注:
在 Windows 下 flock() 将会强制执行。
flock() 操作的 handle
必须是一个已经打开的文件指针。operation
可以是以下值之一:
要取得共享锁定(读取程序),将
operation 设为 LOCK_SH(PHP 4.0.1 以前的版本设置为 1)。
要取得独占锁定(写入程序),将
operation 设为 LOCK_EX(PHP 4.0.1 以前的版本中设置为 2)。
要释放锁定(无论共享或独占),将
operation 设为 LOCK_UN(PHP 4.0.1 以前的版本中设置为 3)。
如果你不希望 flock() 在锁定时堵塞,则给
operation 加上 LOCK_NB(PHP 4.0.1 以前的版本中设置为 4)。
相关文章推荐
- 关于php线程安全的一些东西
- 关于php 数组的一些感想心得
- 关于PHP、Ruby、Java三种程序员的一些偏见
- 关于阿里如何吸引大学生用户理财的一些个人看法
- 关于Socket与Http协议的一些总结以及部分个人看法
- 关于php的一些小谈
- 关于getchar()函数的一些看法
- PHP连接MySQL出现乱码的一些个人看法
- 本学期的关于C语言的课已经正式结束 一些个人关于C语言学习的看法
- 关于高端ARM处理器选型的一些个人看法(作者:gooogleman)
- 关于目标检测和跟踪的一些看法
- 关于absolute的一些看法
- 关于C/C++语言中头文件的使用的一些看法
- 关于线程的一些个人看法(上)
- 关于PHP的多线程扩展pcntl的一些测试
- 关于PHP和ROR的一些思考
- 关于php命名空间的一些小细节
- **关于常量折叠,虚函数表的个人实践及一些看法,若有错漏处欢迎各位指正**
- PHP的关于变量和日期处理的一些面试题目整理
- 关于DataTable和DataSet的一些看法