url hash 是用于提高 squid 命中率的一种架构算法,一般现行的架构通常是使用 dns 轮询或 lvs 等将访问量负载均衡到数台 squid,这样做可以使 squid 的访问量做到了均衡,但是忽略了一个重要方面 -- 数据量。在这种架构下,每台 squid 的数据量虽然是一致的,但通常都是满载,并且存在数据重 复缓存的情况。如果后端服务器数据容量或者用户的访问热点数远远超过缓存机器的内存容量,甚至配置的 disk cache 容量,那么 squid 将会大量使用磁盘或者不停与后端服务器索取内容。
在新的架构下,使用 nginx 架载于 squid 之前,如果 squid 机器有 4 台,那么在这 4 台机器上装上 nginx,nginx 使用 80 端口,而 squid 改为 3128 端口或其他端口。nginx 的效率非常高,消耗内存也非常少,所以并不需考虑加装 nginx 所带来的性能损耗。然后在 nginx 上 配置 url hash,使访问量根据 url 均衡分布到各台 squid,根据 url 分流之后,每一个 url 就会只存在于一台 squid 中,每台 squid 的数据都会完全 不同。我们有 4 台机器,每台 2G 内存的话,原先极有可能因为数据大量重复,内存使用率仍然为 2G,而现在我们经过数据均衡分布,8G 内存可以达到充分利 用。
是否会存在访问不均的情况呢?是有可能的,但是根据大数原理,访问量基本可以保持一致,只要不存在单一的特别夸张的热点。
假如 squid 是利用 squidclient 来刷新数据的话,新的架构提供了更高效的方法:在后端服务器中模拟 url hash 的算法来找到内容所在的 squid,然后对此服务器刷新内容即可。在旧的架构中,需要遍历所有的服务器,比较低效。
具体配置如下:
nginx 本身并没有提供 url hash 功能(暂时),需要安装第三方模块 ngx_http_upstream_hash_module
http://wiki.codemongers.com/NginxHttpUpstreamRequestHashModule?action=AttachFile&do=get&target=nginx_upstream_hash-0.2.tar.gz
cd nginx-0.5.xx
patch -p0 < /path/to/upstream/hash/directory/nginx-0.5.xx.patch
./configure 时加上参数
--add-module=path/to/upstream/hash/directory
make; make install
完成安装
配置:
在 upstream 中加入 hash 语句,server 语句中不能写入 weight 等其他的参数,hash_method 是使用的 hash 算法
upstream backend {
server squid1:3128;
server squid2:3128;
hash $request_uri;
hash_method crc32;
}
hash 算法可以使用 crc32 和默认的 simple,在 java 中可利用 java.util.zip.CRC32 类实现,simple 算法的 c 语言实现如下
#define ngx_hash(key, c) ((u_int) key * 31 c)
u_int ngx_hash_key(u_char *data, size_t len)
{
u_int i, key;
key = 0;
for (i = 0; i < len; i ) {
key *= 31;
key = data[i];
}
return key;
}
java 代码(随手写未测试):
public static long getSimpleHash(String data)
{
long key = 0;
char[] chars = data.toCharArray();
for (int i=0; i
key *= 31;
key = (int) chars[i];
}
return key;
}
然后对生成的 key 和 upstream 里的服务器数量做一次求余计算,得到服务器号。
提供 hash 算法的目的如前所述,是便于后端服务器迅速找到内容对应的 squid 服务器。
在 ngx_http_upstream_hash_module 模块里有一个 hash_again 的标签,可以解决 squid 意外死机的问题。不过,如果 使用了该标签,那么后端的计算对应服务器的方法就会出现错误。可以使用的办法为,提供一台备份的 squid 服务器,假如有 squid 死机,那么在 nginx 里设置 error_page 404 和 502 到这台备份服务器,后端刷新缓存时亦要同时刷备份服务器。
利用 nginx url hash 提高 squid 服务器命中率
最新推荐文章于 2023-05-25 13:06:55 发布