文件缓存管理

一个高负载高访问量通常都是由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]&lt;&gt;'')?$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&lt;=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

 

Tags: , ,

Comments

No comments so far.
  • Leave a Reply
     
    Your gravatar
    Your Name
     
     
     
     
     
 
About This Website

Lamp development & SEO & Plan of Website & Project Managment

Learn more »
Follow Us (SNS)
Help & Support

more about Bruce.xu»

Get in touch

QQ: +252339382
Email: shjuto @ gmail.com

Online contact form »