文件缓存管理
一个高负载高访问量通常都是由N台服务器和多种语言所编写的工具共同负载着的。今天暂时不説集群、负载均衡之类的东西。我们先简单的説一下,我们平常都能遇到的东西,而且也是非常重要的。那就是”缓存”缓存根据不同的用途和更新频率可分为 “内存缓存”和”硬盘缓存”。有些人肯定会问了,什么样的缓存要放到内存/硬盘。比如论坛一些更新非常频繁的帖子列表、查看帖子等数据。可以缓存到内存中。像一些会员资料,更新不频繁的 数据都可以缓存到硬盘里。尽量做到”能不动数据库就尽量不用动数据库”。 大家都知道一个目录不能存放太多文件,如果一个目录超出了一定数量的文件(各个系统的所定义的文件量不太一样),将会造成系统查找文件\枚举文件将会变的非常缓慢。所以必须得设计出一个高效的文件缓存分布器,让文件缓存均衡的分布在各个目录.
前一段时间用Comsenz公司的UCenter Home帮学校做了一个小东西,发现Ucenter是一个很好的东西,稍作改动便可以做成一个单点登录系统。Ucenter把用户的资本资料独立出来,便于第三方应用;比如用户头像的调用,对于一个网站来讲,这些头像的读取是最频繁的,因此如何来快速的找到这些头像就涉及到一定的算法问题,Ucenter是一个文件缓存的例子,由于ucenter是根据用户ID来做的,这个算法相对简单,大家可以查看相关代码,特别是现在的web2.0应用,像Flickr的图片站每张图片度剪切成不同的尺寸保存起来,分别在不同的地方使用,不可能把所有的图片保存在相同的路径下面。
对于非整形的数据如何缓存,这里可能涉及到一定的算法,比如CRC32对缓存的数据处理然后截取不同的区间的数据分组来做。
下面是一个5G的网友 提供的一种PHP解决方案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | < ?php function dfs_hash($str) { $checksum = crc32($str); $checksum=sprintf("%u\n", $checksum); $tmpstr = substr($checksum,0,9); return $tmpstr[0].$tmpstr[1].$tmpstr[2]."/". $tmpstr[3].$tmpstr[4].$tmpstr[5]."/". $tmpstr[6].$tmpstr[7].$tmpstr[8]; } function mkdirs($str, $l2 = 0777) { // $l1:dir $l2:mode if (!is_dir($str)) { mkdirs(dirname($str), $l2); return @mkdir($str, $l2); } return true; } function write_to_file($file_name, $data, $method = "a+") { $filenum = fopen($file_name, $method); flock($filenum, LOCK_EX); $file_data = fwrite($filenum, $data); fclose($filenum); return $file_data; } $name = ($argv[1]<>'')?$argv[1]:"none"; $thepath = dfs_hash($name); if(mkdirs($thepath)) { $thefile = $thepath."/".$name.".txt"; $rs=write_to_file($thefile,date('Y-m-d H:i:s')); if($rs) echo "store:{$thefile}\n"; } |
这段代码的思路不错,但是毕竟是基于PHP做的,效率不高,感兴趣的朋友可以重写,呵呵。
我在网上找到了另外一更高效的库。
连接地址:http://bbs.chinaunix.net/viewthread.php?tid=1030480 ,我在Ubuntu的虚拟机下做了测试:
测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | < ?php function getmicrotime() { list($usec, $sec) = explode(" ",microtime()); return ((float)$usec + (float)$sec); } $time_start = getmicrotime(); for($i=0;$i<=1000000;$i++) { //echo km_hash_path("abcedf"); km_hash_path("abcdef"); } $time_end = getmicrotime(); $time = $time_end - $time_start;</font> echo "运行时间: $time seconds"; //输出运行总时间 /* bool is_alnum ( string var ) -- 测试字符是否为英文或数字 bool is_alpha ( string var ) -- 测试字符是否为英文字母 bool is_lower ( string var ) -- 测试字符是否为小写字母 bool is_upper ( string var ) -- 测试字符是否为大写字母 */ ?> |
100万条数据效率如下:运行时间: 0.0200309753418 seconds









Comments