共计 4879 个字符,预计需要花费 13 分钟才能阅读完成。
如何进行 memcached 的应用和兼容程序的分析,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
下面介绍一些 mixi 的案例和 实际应用上的话题,并介绍一些与 memcached 兼容的程序。
mixi 案例研究
mixi 在提供服务的初期阶段就使用了 memcached。随着网站访问量的急剧增加,单纯为数据库添加 slave 已无法满足需要,因此引入了 memcached。此外,我们也从增加可扩展性的方面进行了验证,证明了 memcached 的速度和稳定性都能满足需要。现在,memcached 已成为 mixi 服务中非常重要的组成部分。
图 1 现在的系统组件
服务器配置和数量
mixi 使用了许许多多服务器,如数据库服务器、应用服务器、图片服务器、反向代理服务器等。单单 memcached 就有将近 200 台服务器在运行。memcached 服务器的典型配置如下:
CPU:Intel Pentium 4 2.8GHz
内存:4GB
硬盘:146GB SCSI
操作系统:Linux(x86_64)
这些服务器以前曾用于数据库服务器等。随着 CPU 性能提升、内存价格下降,我们积极地将数据库服务器、应用服务器等换成了性能更强大、内存更多的服务器。这样,可以抑制 mixi 整体使用的服务器数量的急剧增加,降低管理成本。由于 memcached 服务器几乎不占用 CPU,就将换下来的服务器用作 memcached 服务器了。
memcached 进程
每台 memcached 服务器仅启动一个 memcached 进程。分配给 memcached 的内存为 3GB,启动参数如下:
/usr/bin/memcached -p 11211 -u nobody -m 3000 -c 30720
由于使用了 x86_64 的操作系统,因此能分配 2GB 以上的内存。32 位操作系统中,每个进程最多只能使用 2GB 内存。也曾经考虑过启动多个分配 2GB 以下内存的进程,但这样一台服务器上的 TCP 连接数就会成倍增加,管理上也变得复杂,所以 mixi 就统一使用了 64 位操作系统。
另外,虽然服务器的内存为 4GB,却仅分配了 3GB,是因为内存分配量超过这个值,就有可能导致内存交换(swap)。连载的第 2 次中 前坂讲解过了 memcached 的内存存储“slab allocator”,当时说过,memcached 启动时 指定的内存分配量是 memcached 用于保存数据的量,没有包括“slab allocator”本身占用的内存、以及为了保存数据而设置的管理空间。因此,memcached 进程的实际内存分配量要比 指定的容量要大,这一点应当注意。
mixi 保存在 memcached 中的数据大部分都比较小。这样,进程的大小要比 指定的容量大很多。因此,我们反复改变内存分配量进行验证,确认了 3GB 的大小不会引发 swap,这就是现在应用的数值。
memcached 使用方法和客户端
现在,mixi 的服务将 200 台左右的 memcached 服务器作为一个 pool 使用。每台服务器的容量为 3GB,那么全体就有了将近 600GB 的巨大的内存数据库。客户端程序库使用了本连载中多次提到车的 Cache::Memcached::Fast,与服务器进行交互。当然,缓存的分布式算法使用的是 第 4 次介绍过的 Consistent Hashing 算法。
Cache::Memcached::Fast – search.cpan.org
应用层上 memcached 的使用方法由开发应用程序的工程师自行决定并实现。但是,为了防止车轮再造、防止 Cache::Memcached::Fast 上的教训再次发生,我们提供了 Cache::Memcached::Fast 的 wrap 模块并使用。
通过 Cache::Memcached::Fast 维持连接
Cache::Memcached 的情况下,与 memcached 的连接(文件句柄)保存在 Cache::Memcached 包内的类变量中。在 mod_perl 和 FastCGI 等环境下,包内的变量不会像 CGI 那样随时重新启动,而是在进程中一直保持。其结果就是不会断开与 memcached 的连接,减少了 TCP 连接建立时的开销,同时也能防止短时间内反复进行 TCP 连接、断开 而导致的 TCP 端口资源枯竭。
但是,Cache::Memcached::Fast 没有这个功能,所以需要在模块之外 将 Cache::Memcached::Fast 对象保持在类变量中,以保证持久连接。
package Gihyo::Memcached;
use strict;
use warnings;
use Cache::Memcached::Fast;
my @server_list = qw/192.168.1.1:11211 192.168.1.1:11211/;
my $fast; ## 用于保持对象
sub new { my $self = bless {}, shift;
if ( !$fast ) { $fast = Cache::Memcached::Fast- new({ servers = \@server_list });
}
$self- {_fast} = $fast;
return $self;
sub get {
my $self = shift;
$self- {_fast}- get(@_);
}
上面的例子中,Cache::Memcached::Fast 对象保存到类变量 $fast 中。
公共数据的处理和 rehash
诸如 mixi 的主页上的新闻这样的所有用户共享的缓存数据、设置信息等数据,会占用许多页,访问次数也非常多。在这种条件下,访问很容易集中到某台 memcached 服务器上。访问集中本身并不是问题,但是一旦访问集中的那台服务器发生故障导致 memcached 无法连接,就会产生巨大的问题。
连载的第 4 次 中提到,Cache::Memcached 拥有 rehash 功能,即在无法连接保存数据的服务器的情况下,会再次计算 hash 值,连接其他的服务器。
但是,Cache::Memcached::Fast 没有这个功能。不过,它能够在连接服务器失败时,短时间内不再连接该服务器的功能。
my $fast = Cache::Memcached::Fast- new({
max_failures = 3,
failure_timeout = 1
});
在 failure_timeout 秒内发生 max_failures 以上次连接失败,就不再连接该 memcached 服务器。我们的设置是 1 秒钟 3 次以上。
此外,mixi 还为所有用户共享的缓存数据的键名设置命名规则,符合命名规则的数据会自动保存到多台 memcached 服务器中,取得时从中仅选取一台服务器。创建该函数库后,就可以使 memcached 服务器故障 不再产生其他影响。
memcached 应用经验
到此为止介绍了 memcached 内部构造和函数库,接下来介绍一些其他的应用经验。
通过 daemontools 启动
通常情况下 memcached 运行得相当稳定,但 mixi 现在使用的最新版 1.2.5 曾经发生过几次 memcached 进程死掉的情况。架构上保证了即使有几台 memcached 故障 也不会影响服务,不过对于 memcached 进程死掉的服务器,只要重新启动 memcached,就可以正常运行,所以采用了监视 memcached 进程并自动启动的方法。于是使用了 daemontools。
daemontools 是 qmail 的作者 DJB 开发的 UNIX 服务管理工具集,其中名为 supervise 的程序可用于服务启动、停止的服务重启等。
daemontools
这里不介绍 daemontools 的安装了。mixi 使用了以下的 run 脚本来启动 memcached。
#!/bin/sh
if [ -f /etc/sysconfig/memcached ];then
. /etc/sysconfig/memcached
exec 2 1
exec /usr/bin/memcached -p $PORT -u $USER -m $CACHESIZE -c $MAXCONN $OPTIONS
监视
mixi 使用了名为“nagios”的开源监视软件来监视 memcached。
Nagios: Home
在 nagios 中可以简单地开发插件,可以详细地监视 memcached 的 get、add 等动作。不过 mixi 仅通过 stats 命令来确认 memcached 的运行状态。
define command {
command_name check_memcached
command_line $USER1$/check_tcp -H $HOSTADDRESS$ -p 11211 -t 5 -E -s stats\r\nquit\r\n -e uptime -M crit
}
此外,mixi 将 stats 目录的结果通过 rrdtool 转化成图形,进行性能监视,并将每天的内存使用量做成报表,通过邮件与开发者共享。
memcached 的性能
连载中已介绍过,memcached 的性能十分优秀。我们来看看 mixi 的实际案例。这里介绍的图表是服务所使用的访问最为集中的 memcached 服务器。
图 2 请求数
图 3 流量
图 4 TCP 连接数
从上至下依次为请求数、流量和 TCP 连接数。请求数最大为 15000qps,流量达到 400Mbps,这时的连接数已超过了 10000 个。该服务器没有特别的硬件,就是开头介绍的普通的 memcached 服务器。此时的 CPU 利用率为:
图 5 CPU 利用率
可见,仍然有 idle 的部分。因此,memcached 的性能非常高,可以作为 Web 应用程序开发者放心地保存临时数据或缓存数据的地方。
兼容应用程序
memcached 的实现和协议都十分简单,因此有很多与 memcached 兼容的实现。一些功能强大的扩展可以将 memcached 的内存数据写到磁盘上,实现数据的持久性和冗余。连载第 3 次 介绍过,以后的 memcached 的存储层将变成可扩展的(pluggable),逐渐支持这些功能。
这里介绍几个与 memcached 兼容的应用程序。
repcached
为 memcached 提供复制 (replication) 功能的 patch。
Flared
存储到 QDBM。同时实现了异步复制和 fail over 等功能。
memcachedb
存储到 BerkleyDB。还实现了 message queue。
Tokyo Tyrant
将数据存储到 Tokyo Cabinet。不仅与 memcached 协议兼容,还能通过 HTTP 进行访问。
Tokyo Tyrant 案例
mixi 使用了上述兼容应用程序中的 Tokyo Tyrant。Tokyo Tyrant 是平林开发的 Tokyo Cabinet DBM 的网络接口。它有自己的协议,但也拥有 memcached 兼容协议,也可以通过 HTTP 进行数据交换。Tokyo Cabinet 虽然是一种将数据写到磁盘的实现,但速度相当快。
mixi 并没有将 Tokyo Tyrant 作为缓存服务器,而是将它作为保存键值对组合的 DBMS 来使用。主要作为存储用户上次访问时间的数据库来使用。它与几乎所有的 mixi 服务都有关,每次用户访问页面时都要更新数据,因此负荷相当高。MySQL 的处理十分笨重,单独使用 memcached 保存数据又有可能会丢失数据,所以引入了 Tokyo Tyrant。但无需重新开发客户端,只需原封不动地使用 Cache::Memcached::Fast 即可,这也是优点之一。
mixi Engineers Blog – Tokyo Tyrant による耐高負荷 DB の構築
mixi Engineers Blog – Tokyo (Cabinet|Tyrant)の新機能
关于如何进行 memcached 的应用和兼容程序的分析问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注丸趣 TV 行业资讯频道了解更多相关知识。