元リンク: http://gihyo.jp/dev/feature/01/memcached/0005
href="http://gihyo.jp/dev/feature/01/memcached/0005">
この連載記事へのリンクはこちら:
ミクシィの永野です。 memcachedの連載もいよいよ終わりに近づいてきました。 前回まではmemcachedに直接関係するトピックを紹介してきましたが、今回はmixiの事例や実践的なトピックを紹介し、memcachedと互換性のあるプログラムをいくつか紹介します。 href="http://tech.idv2.com/2008/07/24/memcached-004/">
id="more-614">mixiのサービス提供においてMemcachedが利用されました。初期段階。 Web サイトへのアクセス数が急増しているため、データベースにスレーブを追加するだけではニーズに対応できなくなったため、memcached が導入されました。また、スケーラビリティ向上の面でも検証を行い、memcachedの速度と安定性がニーズに応えられることを証明しました。 現在、memcached は mixi サービスの非常に重要な部分になっています。
図 1 現在のシステムコンポーネント
Mixi は、データベース サーバー、アプリケーション サーバー、画像サーバー、リバース プロキシ サーバーなど、多くのサーバーを使用しています。 Memcached だけでも 200 近くのサーバーが実行されています。 memcached サーバーの一般的な構成は次のとおりです:
これらのサーバーは以前はデータベースに使用されていましたサーバーなどCPU のパフォーマンスが向上し、メモリの価格が低下するにつれて、データベース サーバーとアプリケーション サーバーを、より強力なパフォーマンスとより多くのメモリを備えたサーバーに積極的に置き換えます。 これにより、mixi全体で使用するサーバー台数の急増を抑え、管理コストを削減することができます。 memcached サーバーは CPU をほとんど使用しないため、置き換えられたサーバーが memcached サーバーとして使用されます。
各 memcached サーバーは 1 つの memcached プロセスのみを開始します。 memcached に割り当てられるメモリは 3GB で、起動パラメータは次のとおりです:
/usr/bin/memcached -p 11211 -u nobody -m 3000 -c 30720
x86_64 オペレーティング システムにより、2GB を超えるメモリを割り当てることができます。 32 ビット オペレーティング システムでは、各プロセスは最大 2GB のメモリしか使用できません。 2GB未満のメモリを割り当てるプロセスを複数起動することも検討しましたが、1台のサーバーでのTCP接続数が2倍になり、管理が煩雑になるため、mixiでは64ビットOSを使用しています。
また、サーバーのメモリは4GBですが、3GBしか割り当てられていません。これは、この値を超えるメモリ割り当てにより、メモリのスワップ(スワップ)が発生する可能性があるためです。連載第2回では前坂中氏がmemcachedのメモリストレージ「スラブアロケータ」について解説しましたが、その際、memcachedの起動時に指定するメモリ割り当て量はmemcachedがデータを保存するために使用する量であり、占有メモリは含まれないと述べました。 「スラブ アロケータ」自体、およびデータを保存するために設定された管理スペースによって。したがって、memcached プロセスの実際のメモリ割り当ては、指定された容量よりも大きくなることに注意してください。
mixi によって memcached に保存されるデータのほとんどは比較的小さいものです。このように、プロセスのサイズは指定された容量よりも大幅に大きくなります。そこでメモリ割り当て量を何度も変更して検証し、3GBのサイズでスワップが発生しないことを確認したのが現在適用されている値です。
現在、mixiのサービスでは約200台のmemcachedサーバーをプールとして使用しています。 各サーバーの容量は 3GB であるため、サーバー全体では 600GB 近い巨大なメモリ データベースが搭載されています。 クライアント ライブラリは、このシリーズで何度も言及している Cache::Memcached::Fast を使用してサーバーと対話します。もちろん、キャッシュの分散アルゴリズムは第4回で紹介したConsistent Hashingアルゴリズムを使用します。
应用层上memcached的使用方法由开发应用程序的工程师自行决定并实现。 但是,为了防止车轮再造、防止Cache::Memcached::Fast上的教训再次发生, 我们提供了Cache::Memcached::Fast的wrap模块并使用。
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中。
诸如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运行得相当稳定,但mixi现在使用的最新版1.2.5 曾经发生过几次memcached进程死掉的情况。架构上保证了即使有几台memcached故障 也不会影响服务,不过对于memcached进程死掉的服务器,只要重新启动memcached, 就可以正常运行,所以采用了监视memcached进程并自动启动的方法。 于是使用了daemontools。
daemontools是qmail的作者DJB开发的UNIX服务管理工具集, 其中名为supervise的程序可用于服务启动、停止的服务重启等。
这里不介绍daemontools的安装了。mixi使用了以下的run脚本来启动memcached。
#!/bin/sh if [ -f /etc/sysconfig/memcached ];then . /etc/sysconfig/memcached fi exec 2>&1 exec /usr/bin/memcached -p $PORT -u $USER -m $CACHESIZE -c $MAXCONN $OPTIONS
mixi使用了名为“nagios”的开源监视软件来监视memcached。
在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的性能十分优秀。我们来看看mixi的实际案例。 这里介绍的图表是服务所使用的访问最为集中的memcached服务器。
图2 请求数
src="http://tech.idv2.com/wp-content/uploads/2008/07/memcached の総合分析 – 5. memcached アプリケーションと互換プログラム_PHP チュートリアル">图3 流量
src="http://tech.idv2.com/wp-content/uploads/2008/07/memcached の総合分析 – 5. memcached アプリケーションと互換プログラム_PHP チュートリアル">图4 TCP连接数
上から下まで、リクエスト、トラフィック、TCP 接続の数です。リクエストの最大数は 15,000qps、トラフィックは 400Mbps に達し、この時点の接続数は 10,000 を超えています。 このサーバーには特別なハードウェアはなく、冒頭で紹介した通常の memcached サーバーです。 このときの CPU 使用率は次のとおりです。
図 5 CPU 使用率
まだアイドル部分があることがわかります。したがって、memcached は非常に高いパフォーマンスを備えており、Web アプリケーション開発者が一時データまたはキャッシュ データを保存するための安全な場所として使用できます。
memcached の実装とプロトコルは非常にシンプルなので、memcached と互換性のある実装が多数あります。 一部の強力な拡張機能は、memcached メモリ データをディスクに書き込み、データの永続性と冗長性を実現できます。 連載第 3 回で紹介したように、将来の memcached ストレージ層はプラガブルになり、これらの機能を段階的にサポートする予定です。
memcached と互換性のあるアプリケーションをいくつか紹介します。
mixiでは上記対応アプリの東京タイラントを使用しております。 Tokyo Tyrant は、平林氏が開発した Tokyo Cabinet DBM のネットワークインターフェースです。独自のプロトコルを持っていますが、memcached と互換性のあるプロトコルも備えており、HTTP 経由でデータを交換することもできます。 Tokyo Cabinetはディスクにデータを書き込む実装ですが、かなり高速です。
mixiは、東京タイラントをキャッシュサーバーとしてではなく、キーと値のペアの組み合わせを保存するDBMSとして使用しています。 主にユーザーの最終アクセス時刻を保存するデータベースとして使用されます。ほぼすべてのmixiサービスに関係しており、ユーザーがページにアクセスするたびにデータを更新する必要があるため、負荷がかなり高くなります。 MySQLの処理は非常に煩雑で、memcachedだけでデータを保存するとデータが失われる可能性があるため、Tokyo Tyrantを導入しました。 ただし、クライアントを再開発する必要はなく、Cache::Memcached::Fast を変更せずに使用することができます。これも利点の 1 つです。 Tokyo Tyrantの詳細については、弊社開発ブログをご覧ください。
これで「memcachedの総合解析」シリーズは終了です。 memcached の基礎、内部構造、分散アルゴリズム、応用について紹介しました。これを読んでmemcachedに興味を持っていただければ幸いです。 mixiのシステムやアプリケーションについては、当社の開発ブログをご覧ください。 読んでくれてありがとう。
著作権声明: 自由に再印刷することができますが、再印刷する場合は、元の著者であるチャーリー、元のリンク、およびこの声明を明記する必要があります。
id="content_2_5"> id="content_2_3"> id="content_2_2">