??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲色WWW成人永久网址,亚洲免费观看网站,亚洲av无码成人精品区http://www.tkk7.com/ruoyoux/category/40788.html为梦惌来Qؓ(f)自由而生? 性情若水Q风h_(d)风息水止Q故时而激荡,时又清^…?/description>zh-cnTue, 14 Jul 2009 08:48:44 GMTTue, 14 Jul 2009 08:48:44 GMT60每日一?2009/07/03 memcached完全剖析http://www.tkk7.com/ruoyoux/articles/285323.htmlBlog of JoJoBlog of JoJoFri, 03 Jul 2009 04:20:00 GMThttp://www.tkk7.com/ruoyoux/articles/285323.htmlhttp://www.tkk7.com/ruoyoux/comments/285323.htmlhttp://www.tkk7.com/ruoyoux/articles/285323.html#Feedback0http://www.tkk7.com/ruoyoux/comments/commentRss/285323.htmlhttp://www.tkk7.com/ruoyoux/services/trackbacks/285323.html1. memcached的基

译一技术评论社的文章,是讲memcached的连载?a >fcicq同学说这个东西很有用Q希望大家喜Ƣ?/p>

发表日:(x)2008/7/2
作者:(x)镉K雅广(Masahiro Nagano)
原文链接Q?a >http://gihyo.jp/dev/feature/01/memcached/0001

我是mixi株式?x)?/a>开发部pȝq营l的镉K? 日常负责E序的运营。从今天开始,分几次针对最q在Web应用的可扩展性领? 的热门话题memcachedQ与我公司开发部研究开发组的前坂一P 说明其内部结构和使用?/p>

memcached是什么?

memcached 是以LiveJournal 旗下Danga Interactive 公司?a >Brad Fitzpatric 为首开发的一ƾY件。现在已成ؓ(f) mixi? hatena? Facebook? Vox、LiveJournal{众多服务中 提高Web应用扩展性的重要因素?/p>

许多Web应用都将数据保存到RDBMS中,应用服务器从中读取数据ƈ在浏览器中显C? 但随着数据量的增大、访问的集中Q就?x)出现RDBMS的负担加重、数据库响应恶化? |站昄延迟{重大媄(jing)响?/p>

q时pmemcached大显w手?jin)。memcached是高性能的分布式内存~存服务器? 一般的使用目的是,通过~存数据库查询结果,减少数据库访问次敎ͼ以提高动态Web应用的速度? 提高可扩展性?/p>


? 一般情况下memcached的用?/p>

memcached的特?/h2>

memcached作ؓ(f)高速运行的分布式缓存服务器Q具有以下的特点?/p>

  • 协议?/li>
  • Zlibevent的事件处?/li>
  • 内置内存存储方式
  • memcached不互盔R信的分布式

协议?/h3>

memcached的服务器客户端通信q不使用复杂的XML{格式, 而用简单的Z文本行的协议。因此,通过telnet 也能在memcached上保存数据、取得数据。下面是例子?/p>

$ telnet localhost 11211

Trying 127.0.0.1...

Connected to localhost.localdomain (127.0.0.1).

Escape character is '^]'.

set foo 0 0 3 Q保存命令)(j)

bar Q数据)(j)

STORED Q结果)(j)

get foo Q取得命令)(j)

VALUE foo 0 3 Q数据)(j)

bar Q数据)(j)

协议文档位于memcached的源代码内,也可以参考以下的URL?/p>

Zlibevent的事件处?/h3>

libevent是个E序库,它将Linux的epoll、BSDcL作系l的kqueue{事件处理功? 装成统一的接口。即使对服务器的q接数增加,也能发挥O(1)的性能? memcached使用q个libevent库,因此能在Linux、BSD、Solaris{操作系l上发挥光性能? 关于事g处理q里׃再详l介l,可以参考Dan Kegel的The C10K Problem?/p>

内置内存存储方式

Z(jin)提高性能Qmemcached中保存的数据都存储在memcached内置的内存存储空间中? ׃数据仅存在于内存?sh),因此重启memcached、重启操作系l会(x)D全部数据消失? 另外Q内容容量达到指定g后,基于LRU(Least Recently Used)法自动删除不用的~存? memcached本n是ؓ(f)~存而设计的服务器,因此q没有过多考虑数据的永久性问题? 关于内存存储的详l信息,本连载的W二讲以后前坂会(x)q行介绍Q请届时参考?/p>

memcached不互盔R信的分布式

memcached管?#8220;分布?#8221;~存服务器,但服务器端ƈ没有分布式功能? 各个memcached不会(x)互相通信以共享信息。那么,怎样q行分布式呢Q? q完全取决于客户端的实现。本q蝲也将介绍memcached的分布式?/p>


? memcached的分布式

接下来简单介l一下memcached的用方法?/p>

安装memcached

memcached的安装比较简单,q里E加说明?/p>

memcached支持许多q_?/p>

  • Linux
  • FreeBSD
  • Solaris (memcached 1.2.5以上版本)
  • Mac OS X

另外也能安装在Windows上。这里用Fedora Core 8q行说明?/p>

memcached的安?/h3>

q行memcached需要本文开头介l的libevent库。Fedora 8中有现成的rpm包, 通过yum命o(h)安装卛_?/p>

$ sudo yum install libevent libevent-devel

memcached的源代码可以从memcached|站上下载。本文执W时的最新版本ؓ(f)1.2.5? Fedora 8虽然也包含了(jin)memcached的rpmQ但版本比较老。因为源代码安装q不困难Q? q里׃使用rpm?jin)?/p>

  • 下蝲memcachedQ?a >http://www.danga.com/memcached/download.bml

memcached安装与一般应用程序相同,configure、make、make installp?jin)?/p>

$ wget http://www.danga.com/memcached/dist/memcached-1.2.5.tar.gz

$ tar zxf memcached-1.2.5.tar.gz

$ cd memcached-1.2.5

$ ./configure

$ make

$ sudo make install

默认情况下memcached安装?usr/local/bin下?/p>

memcached的启?/h3>

从终端输入以下命令,启动memcached?/p>

$ /usr/local/bin/memcached -p 11211 -m 64m -vv

slab class 1: chunk size 88 perslab 11915

slab class 2: chunk size 112 perslab 9362

slab class 3: chunk size 144 perslab 7281

中间省略

slab class 38: chunk size 391224 perslab 2

slab class 39: chunk size 489032 perslab 2

<23 server listening

<24 send buffer was 110592, now 268435456

<24 server listening (udp)

<24 server listening (udp)

<24 server listening (udp)

<24 server listening (udp)

q里昄?jin)调试信息。这样就在前台启动了(jin)memcachedQ监听TCP端口11211 最大内存(sh)用量?4M。调试信息的内容大部分是关于存储的信息, 下次q蝲时具体说明?/p>

作ؓ(f)daemon后台启动Ӟ只需

$ /usr/local/bin/memcached -p 11211 -m 64m -d

q里使用的memcached启动选项的内容如下?/p>

选项 说明
-p 使用的TCP端口。默认ؓ(f)11211
-m 最大内存大。默认ؓ(f)64M
-vv 用very vrebose模式启动Q调试信息和错误输出到控制台
-d 作ؓ(f)daemon在后台启?/td>

上面四个是常用的启动选项Q其他还有很多,通过

$ /usr/local/bin/memcached -h

命o(h)可以昄。许多选项可以改变memcached的各U行为, 推荐M诅R?/p>

用客L(fng)q接

许多语言都实C(jin)q接memcached的客L(fng)Q其中以Perl、PHPZ? 仅仅memcached|站上列出的语言有

  • Perl
  • PHP
  • Python
  • Ruby
  • C#
  • C/C++
  • Lua

{等?/p>

  • memcached客户端APIQ?a >http://www.danga.com/memcached/apis.bml

q里介绍通过mixi正在使用的Perl库链接memcached的方法?/p>

使用Cache::Memcached

Perl的memcached客户端有

  • Cache::Memcached
  • Cache::Memcached::Fast
  • Cache::Memcached::libmemcached

{几个CPAN模块。这里介l的Cache::Memcached是memcached的作者Brad Fitzpatric的作品, 应该是memcached的客L(fng)中应用最为广泛的模块?jin)?/p>

使用Cache::Memcachedq接memcached

下面的源代码为通过Cache::Memcachedq接刚才启动的memcached的例子?/p>

#!/usr/bin/perl



use strict;

use warnings;

use Cache::Memcached;



my $key = "foo";

my $value = "bar";

my $expires = 3600; # 1 hour

my $memcached = Cache::Memcached->new({

servers => ["127.0.0.1:11211"],

compress_threshold => 10_000

});



$memcached->add($key, $value, $expires);

my $ret = $memcached->get($key);

print "$ret"n";

在这里,为Cache::Memcached指定?jin)memcached服务器的IP地址和一个选项Q以生成实例? Cache::Memcached常用的选项如下所C?/p>

选项 说明
servers 用数l指定memcached服务器和端口
compress_threshold 数据压羃时用的?/td>
namespace 指定d到键的前~

另外QCache::Memcached通过Storable模块可以Perl的复杂数据序列化之后再保存, 因此散列、数l、对象等都可以直接保存到memcached中?/p>

保存数据

向memcached保存数据的方法有

  • add
  • replace
  • set

它们的用方法都相同Q?/p>

my $add = $memcached->add( '?, '?, '期限' );

my $replace = $memcached->replace( '?, '?, '期限' );

my $set = $memcached->set( '?, '?, '期限' );

向memcached保存数据时可以指定期?U?。不指定期限Ӟmemcached按照LRU法保存数据? q三个方法的区别如下Q?/p>

选项 说明
add 仅当存储I间中不存在键相同的数据时才保存
replace 仅当存储I间中存在键相同的数据时才保?/td>
set 与add和replace不同Q无Z旉保存

获取数据

获取数据可以使用get和get_multiҎ(gu)?/p>

my $val = $memcached->get('?);

my $val = $memcached->get_multi('?', '?', '?', '?', '?');

一ơ取得多条数据时使用get_multi。get_multi可以非同步地同时取得多个键| 光度要比循环调用get快数十倍?/p>

删除数据

删除数据使用deleteҎ(gu)Q不q它有个独特的功能?/p>

$memcached->delete('?, 'd旉(U?');

删除W一个参数指定的键的数据。第二个参数指定一个时间|可以止使用同样的键保存新数据? 此功能可以用于防止缓存数据的不完整。但是要注意Q?strong>set函数忽视该阻塞,照常保存数据

增一和减一操作

可以memcached上特定的键g数器使用?/p>

my $ret = $memcached->incr('?);

$memcached->add('?, 0) unless defined $ret;

增一和减一是原子操作,但未讄初始值时Q不?x)自动赋?。因此, 应当q行错误(g)查,必要时加入初始化操作。而且Q服务器端也不会(x)? 过2<sup>32</sup>时的行ؓ(f)q行(g)查?/p>

ȝ

q次单介l了(jin)memcachedQ以?qing)它的安装方法、Perl客户端Cache::Memcached的用法? 只要知道Qmemcached的用方法十分简单就_?jin)?/p>

下次由前坂来说明memcached的内部结构。了(jin)解memcached的内部构造, p知道如何使用memcached才能使Web应用的速度更上一层楼? Ƣ迎l箋阅读下一章?/p>


2.理解memcached的内存存?/h1>

下面是《memcached全面剖析》的W二部分?/p>

发表日:(x)2008/7/9
作者:(x)前坂?Toru Maesaka)
原文链接Q?a >http://gihyo.jp/dev/feature/01/memcached/0002

我是mixi株式?x)?/a>研究开发组的前坂徹? 上次的文章介l了(jin)memcached是分布式的高速缓存服务器? 本次介lmemcached的内部构造的实现方式Q以?qing)内存的理方式? 另外Qmemcached的内部构造导致的q也将加以说明?/p>

Slab Allocation机制Q整理内存(sh)侉K复?/h2>

最q的memcached默认情况下采用了(jin)名ؓ(f)Slab Allocator的机制分配、管理内存? 在该机制出现以前Q内存的分配是通过Ҏ(gu)有记录简单地q行malloc和free来进行的? 但是Q这U方式会(x)D内存片Q加重操作系l内存管理器的负担,最坏的情况下, ?x)导致操作系l比memcachedq程本nq慢。Slab Allocator是册问题而诞生的?/p>

下面来看看Slab Allocator的原理。下面是memcached文档中的slab allocator的目标:(x)

the primary goal of the slabs subsystem in memcached was to eliminate memory fragmentation issues totally by using fixed-size memory chunks coming from a few predetermined size classes.

也就是说QSlab Allocator的基本原理是按照预先规定的大,分配的内存分割成特定长度的块, 以完全解军_存碎片问题?/p>

Slab Allocation的原理相当简单?分配的内存分割成各U尺寸的块(chunkQ, q把寸相同的块分成l(chunk的集合)(j)Q图1Q?/p>


? Slab Allocation的构造图

而且Qslab allocatorq有重复使用已分配的内存的目的? 也就是说Q分配到的内存(sh)?x)释放,而是重复利用?/p>

Slab Allocation的主要术?/h3>

Page

分配lSlab的内存空_(d)默认?MB。分配给Slab之后Ҏ(gu)slab的大切分成chunk?/p>

Chunk

用于~存记录的内存空间?/p>

Slab Class

特定大小的chunk的组?/p>

在Slab中缓存记录的原理

下面说明memcached如何针对客户端发送的数据选择slabq缓存到chunk中?/p>

memcachedҎ(gu)收到的数据的大小Q选择最适合数据大小的slabQ图2Q? memcached中保存着slab内空闲chunk的列表,Ҏ(gu)该列表选择chunkQ? 然后数据缓存(sh)其中?/p>


? 选择存储记录的组的方?/p>

实际上,Slab Allocator也是有利也有弊。下面介l一下它的缺炏V?/p>

Slab Allocator的缺?/h2>

Slab Allocator解决?jin)当初的内存片问题Q但新的机制也给memcached带来?jin)新的问题?/p>

q个问题是Q由于分配的是特定长度的内存Q因此无法有效利用分配的内存? 例如Q将100字节的数据缓存到128字节的chunk中,剩余?8字节浪费了(jin)Q图3Q?/p>


? chunkI间的?/p>

对于该问题目前还没有完美的解x(chng)案,但在文档中记载了(jin)比较有效的解x(chng)案?/p>

The most efficient way to reduce the waste is to use a list of size classes that closely matches (if that's at all possible) common sizes of objects that the clients of this particular installation of memcached are likely to store.

是_(d)如果预先知道客户端发送的数据的公用大,或者仅~存大小相同的数据的情况下, 只要使用适合数据大小的组的列表,可以减浪贏V?/p>

但是很遗憾,现在q(sh)能进行Q何调优,只能期待以后的版本了(jin)? 但是Q我们可以调节slab class的大的差别? 接下来说明growth factor选项?/p>

使用Growth Factorq行调优

memcached在启动时指定 Growth Factor因子Q通过-f选项Q, 可以在某种E度上控制slab之间的差异。默认gؓ(f)1.25? 但是Q在该选项出现之前Q这个因子曾l固定ؓ(f)2Q称?#8220;powers of 2”{略?/p>

让我们用以前的设|,以verbose模式启动memcached试试看:(x)

$ memcached -f 2 -vv

下面是启动后的verbose输出Q?/p>

slab class   1: chunk size    128 perslab  8192

slab class 2: chunk size 256 perslab 4096

slab class 3: chunk size 512 perslab 2048

slab class 4: chunk size 1024 perslab 1024

slab class 5: chunk size 2048 perslab 512

slab class 6: chunk size 4096 perslab 256

slab class 7: chunk size 8192 perslab 128

slab class 8: chunk size 16384 perslab 64

slab class 9: chunk size 32768 perslab 32

slab class 10: chunk size 65536 perslab 16

slab class 11: chunk size 131072 perslab 8

slab class 12: chunk size 262144 perslab 4

slab class 13: chunk size 524288 perslab 2

可见Q从128字节的组开始,l的大小依次增大为原来的2倍? q样讄的问题是Qslab之间的差别比较大Q有些情况下q当浪费内存? 因此Qؓ(f)量减少内存?gu)费Q两q前q加?jin)growth factorq个选项?/p>

来看看现在的默认讄Qf=1.25Q时的输出(幅所限,q里只写到第10l)(j)Q?/p>

slab class   1: chunk size     88 perslab 11915

slab class 2: chunk size 112 perslab 9362

slab class 3: chunk size 144 perslab 7281

slab class 4: chunk size 184 perslab 5698

slab class 5: chunk size 232 perslab 4519

slab class 6: chunk size 296 perslab 3542

slab class 7: chunk size 376 perslab 2788

slab class 8: chunk size 472 perslab 2221

slab class 9: chunk size 592 perslab 1771

slab class 10: chunk size 744 perslab 1409

可见Q组间差距比因子?时小得多Q更适合~存几百字节的记录? 从上面的输出l果来看Q可能会(x)觉得有些计算误差Q? q些误差是ؓ(f)?jin)保持字节数的对齐而故意设|的?/p>

memcached引入产品Q或是直接用默认D行部|时Q? 最好是重新计算一下数据的预期q_长度Q调整growth factorQ? 以获得最恰当的设|。内存是珍贵的资源,费太可惜?jin)?/p>

接下来介l一下如何用memcached的stats命o(h)查看slabs的利用率{各U各L(fng)信息?/p>

查看memcached的内部状?/h2>

memcached有个名ؓ(f)stats的命令,使用它可以获得各U各L(fng)信息? 执行命o(h)的方法很多,用telnet最为简单:(x)

$ telnet L?端口?/pre>

q接到memcached之后Q输入stats再按回RQ即可获得包括资源利用率在内的各U信息? 此外Q输?stats slabs"?stats items"q可以获得关于缓存记录的信息? l束E序误入quit?/p>

q些命o(h)的详l信息可以参考memcached软g包内的protocol.txt文档?/p>

$ telnet localhost 11211

Trying ::1...

Connected to localhost.

Escape character is '^]'.

stats

STAT pid 481

STAT uptime 16574

STAT time 1213687612

STAT version 1.2.5

STAT pointer_size 32

STAT rusage_user 0.102297

STAT rusage_system 0.214317

STAT curr_items 0

STAT total_items 0

STAT bytes 0

STAT curr_connections 6

STAT total_connections 8

STAT connection_structures 7

STAT cmd_get 0

STAT cmd_set 0

STAT get_hits 0

STAT get_misses 0

STAT evictions 0

STAT bytes_read 20

STAT bytes_written 465

STAT limit_maxbytes 67108864

STAT threads 4

END

quit

另外Q如果安装了(jin)libmemcachedq个面向C/C++语言的客L(fng)库,׃(x)安装 memstat q个命o(h)? 使用Ҏ(gu)很简单,可以用更的步骤获得与telnet相同的信息,q能一ơ性从多台服务器获得信息?/p>

$ memstat --servers=server1,server2,server3,...

libmemcached可以从下面的地址获得Q?/p>

查看slabs的用状?/h2>

使用memcached的创造着Brad写的名ؓ(f)memcached-tool的Perl脚本Q可以方便地获得slab的用情? Q它?yu)memcached的返回值整理成Ҏ(gu)阅读的格式)(j)。可以从下面的地址获得脚本Q?/p>

使用Ҏ(gu)也极其简单:(x)

$ memcached-tool L?端口 选项

查看slabs使用状况时无需指定选项Q因此用下面的命令即可:(x)

$ memcached-tool L?端口

获得的信息如下所C:(x)

 #  Item_Size   Max_age  1MB_pages Count   Full?

1 104 B 1394292 s 1215 12249628 yes

2 136 B 1456795 s 52 400919 yes

3 176 B 1339587 s 33 196567 yes

4 224 B 1360926 s 109 510221 yes

5 280 B 1570071 s 49 183452 yes

6 352 B 1592051 s 77 229197 yes

7 440 B 1517732 s 66 157183 yes

8 552 B 1460821 s 62 117697 yes

9 696 B 1521917 s 143 215308 yes

10 872 B 1695035 s 205 246162 yes

11 1.1 kB 1681650 s 233 221968 yes

12 1.3 kB 1603363 s 241 183621 yes

13 1.7 kB 1634218 s 94 57197 yes

14 2.1 kB 1695038 s 75 36488 yes

15 2.6 kB 1747075 s 65 25203 yes

16 3.3 kB 1760661 s 78 24167 yes

各列的含义ؓ(f)Q?/p>

?/td> 含义
# slab class~号
Item_Size Chunk大小
Max_age LRU内最旧的记录的生存时?/td>
1MB_pages 分配lSlab的页?/td>
Count Slab内的记录?/td>
Full? Slab内是否含有空闲chunk

从这个脚本获得的信息对于调优非常方便Q强烈推荐用?/p>

内存存储的ȝ

本次单说明了(jin)memcached的缓存机制和调优Ҏ(gu)? 希望读者能理解memcached的内存管理原理及(qing)其优~点?/p>

下次l说明LRU和Expire{原理,以及(qing)memcached的最新发展方向—? 可扩充体p(pluggable architecherQ)(j)?/p>


3.memcached的删除机制和发展方向


下面是《memcached全面剖析》的W三部分?/p>

发表日:(x)2008/7/16
作者:(x)前坂?Toru Maesaka)
原文链接Q?a >http://gihyo.jp/dev/feature/01/memcached/0003

memcached是缓存,所以数据不?x)永久保存在服务器上Q这是向pȝ中引入memcached的前提? 本次介绍memcached的数据删除机Ӟ以及(qing)memcached的最新发展方向——二q制协议QBinary ProtocolQ? 和外部引擎支持?/p>

memcached在数据删除方面有效利用资?/h2>

数据不会(x)真正从memcached中消?/h3>

上次介绍q, memcached不会(x)释放已分配的内存。记录超时后Q客L(fng)无法再看见该记录(invisibleQ透明Q, 其存储空间即可重复用?/p>

Lazy Expiration

memcached内部不会(x)监视记录是否q期Q而是在get时查看记录的旉戻I(g)查记录是否过期? q种技术被UCؓ(f)lazyQ惰性)(j)expiration。因此,memcached不会(x)在过期监视上耗费CPU旉?/p>

LRUQ从~存?sh)有效删除数据的原?/h2>

memcached?x)优先用已时的记录的I间Q但即如此Q也?x)发生追加新记录时空间不的情况Q? 此时p使用名ؓ(f) Least Recently UsedQLRUQ机制来分配I间? ֐思义Q这是删?#8220;最q最?#8221;的记录的机制? 因此Q当memcached的内存空间不x(chng)Q无法从slab class 获取到新的空间时Q,׃最q未被用的记录中搜索,q将其空间分配给新的记录? 从缓存的实用角度来看Q该模型十分理想?/p>

不过Q有些情况下LRU机制反倒会(x)造成ȝ(ch)。memcached启动旉过“-M”参数可以止LRUQ如下所C:(x)

$ memcached -M -m 1024

启动时必L意的是,写?#8220;-m”选项是用来指定最大内存大的。不指定具体数值则使用默认?4MB?/p>

指定“-M”参数启动后,内存用尽时memcached?x)返回错误? 话说回来Qmemcached毕竟不是存储器,而是~存Q所以推荐用LRU?/p>

memcached的最新发展方?/h2>

memcached的roadmap上有两个大的目标。一个是二进制协议的{划和实玎ͼ另一个是外部引擎的加载功能?/p>

关于二进制协?/h3>

使用二进制协议的理由是它不需要文本协议的解析处理Q得原本高速的memcached的性能更上一层楼Q? q能减少文本协议的漏z。目前已大部分实玎ͼ开发用的代码库中已包含?jin)该功能? memcached的下载页面上有代码库的链接?/p>

二进制协议的格式

协议的包?4字节的Q其后面是键和无l构数据QUnstructured DataQ? 实际的格式如下(引自协议文档Q:(x)

 Byte/     0       |       1       |       2       |       3       |   

/ | | | |

|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|

+---------------+---------------+---------------+---------------+

0/ HEADER /

/ /

/ /

/ /

+---------------+---------------+---------------+---------------+

24/ COMMAND-SPECIFIC EXTRAS (as needed) /

+/ (note length in th extras length header field) /

+---------------+---------------+---------------+---------------+

m/ Key (as needed) /

+/ (note length in key length header field) /

+---------------+---------------+---------------+---------------+

n/ Value (as needed) /

+/ (note length is total body length header field, minus /

+/ sum of the extras and key length body fields) /

+---------------+---------------+---------------+---------------+

Total 24 bytes

如上所C,包格式十分简单。需要注意的是,占据?6字节的头?HEADER)分ؓ(f) h_(d)Request HeaderQ和响应_(d)Response HeaderQ两U? 头部中包含了(jin)表示包的有效性的Magic字节、命令种cR键长度、值长度等信息Q格式如下:(x)

Request Header



Byte/ 0 | 1 | 2 | 3 |

/ | | | |

|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|

+---------------+---------------+---------------+---------------+

0| Magic | Opcode | Key length |

+---------------+---------------+---------------+---------------+

4| Extras length | Data type | Reserved |

+---------------+---------------+---------------+---------------+

8| Total body length |

+---------------+---------------+---------------+---------------+

12| Opaque |

+---------------+---------------+---------------+---------------+

16| CAS |

| |

+---------------+---------------+---------------+---------------+
Response Header



Byte/ 0 | 1 | 2 | 3 |

/ | | | |

|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|

+---------------+---------------+---------------+---------------+

0| Magic | Opcode | Key Length |

+---------------+---------------+---------------+---------------+

4| Extras length | Data type | Status |

+---------------+---------------+---------------+---------------+

8| Total body length |

+---------------+---------------+---------------+---------------+

12| Opaque |

+---------------+---------------+---------------+---------------+

16| CAS |

| |

+---------------+---------------+---------------+---------------+

如希望了(jin)解各个部分的详细内容Q可以checkout出memcached的二q制协议的代码树(wi)Q? 参考其中的docs文g夹中的protocol_binary.txt文档?/p>

HEADER中引人注目的地方

看到HEADER格式后我的感x(chng)Q键的上限太大了(jin)Q现在的memcached规格中,键长度最大ؓ(f)250字节Q? 但二q制协议中键的大用2字节表示。因此,理论上最大可使用65536字节Q?<sup>16</sup>Q长的键? 管250字节以上的键q不?x)太常用Q二q制协议发布之后可以用巨大的键了(jin)?/p>

二进制协议从下一版本1.3pd开始支持?/p>

外部引擎支持

我去q曾l试验性地memcached的存储层攚w成?jin)可扩展的(pluggableQ?/p>

MySQL的Brian Aker看到q个攚w之后,将代码发到?jin)memcached的邮件列表? memcached的开发者也十分感兴,放C(jin)roadmap中。现在由我和 memcached的开发者Trond Norbye协同开发(规格设计、实现和试Q? 和国外协同开发时时差是个大问题,但抱着相同的愿景, 最后终于可以将可扩展架构的原型公布?jin)? 代码库可以从memcached的下载页?/a> 上访问?/p>

外部引擎支持的必要?/h3>

世界上有许多memcached的派生YӞ其理由是希望怹保存数据、实现数据冗余等Q? 即牺牲一些性能也在所不惜。我在开发memcached之前Q在mixi的研发部也曾l? 考虑q重新发明memcached?/p>

外部引擎的加载机制能装memcached的网l功能、事件处理等复杂的处理? 因此Q现阶段通过强制手段或重新设计等方式使memcached和存储引擎合作的困难 ׃(x)烟消云散Q尝试各U引擎就?x)变得轻而易举了(jin)?/p>

单API设计的成功的关键

该项目中我们最重视的是API设计。函数过多,?x)引擎开发者感到麻?ch)? q于复杂Q实现引擎的门槛׃(x)q高。因此,最初版本的接口函数只有13个? 具体内容限于幅Q这里就省略?jin),仅说明一下引擎应当完成的操作Q?/p>

  • 引擎信息Q版本等Q?/li>
  • 引擎初始?/li>
  • 引擎关闭
  • 引擎的统计信?/li>
  • 在容量方面,试l定记录能否保存
  • 为itemQ记录)(j)l构分配内存
  • 释放itemQ记录)(j)的内?/li>
  • 删除记录
  • 保存记录
  • 回收记录
  • 更新记录的时间戳
  • 数学q算处理
  • 数据的flush

对详l规格有兴趣的读者,可以checkout engine目的代码,阅读器中的engine.h?/p>

重新审视现在的体p?/h3>

memcached支持外部存储的难Ҏ(gu)Q网l和事g处理相关的代码(核心(j)服务器)(j)? 内存存储的代码紧密关联。这U现象也UCؓ(f)tightly coupledQ紧密耦合Q? 必须内存存储的代码从核?j)服务器中独立出来,才能灉|地支持外部引擎? 因此Q基于我们设计的APIQmemcached被重构成下面的样子:(x)


重构之后Q我们与1.2.5版、二q制协议支持版等q行?jin)性能Ҏ(gu)Q证实了(jin)它不?x)造成性能影响?/p>

在考虑如何支持外部引擎加蝲Ӟ让memcachedq行q行控制Qconcurrency controlQ的Ҏ(gu)是最为容易的Q? 但是对于引擎而言Qƈ行控制正是性能的真谛,因此我们采用?jin)将多线E支持完全交l引擎的设计Ҏ(gu)?/p>

以后的改q,?x)得memcached的应用范围更为广泛?/p>

ȝ

本次介绍?jin)memcached的超时原理、内部如何删除数据等Q在此之上又介绍?jin)二q制协议? 外部引擎支持{memcached的最新发展方向。这些功能要?.3版才?x)支持,敬请期待Q?/p>

q是我在本连载中的最后一。感谢大安L的文章!

下次由长野来介绍memcached的应用知识和应用E序兼容性等内容?/p>



4. memcached的分布式法


发表日:(x)2008/7/23
作者:(x)镉K雅广(Masahiro Nagano)
原文链接Q?a >http://gihyo.jp/dev/feature/01/memcached/0004

我是Mixi的长野? W??/a>? W??/a> 由前坂介l了(jin)memcached的内部情c(din)本ơ不再介lmemcached的内部结构, 开始介lmemcached的分布式?/p>

memcached的分布式

正如W??/a>中介l的那样Q? memcached虽然UCؓ(f)“分布?#8221;~存服务器,但服务器端ƈ没有“分布?#8221;功能? 服务器端仅包? W??/a>? W??/a> 前坂介绍的内存存储功能,其实现非常简单? 至于memcached的分布式Q则是完全由客户端程序库实现的? q种分布式是memcached的最大特炏V?/p>

memcached的分布式是什么意思?

q里多次使用?#8220;分布?#8221;q个词,但ƈ未做详细解释? 现在开始简单地介绍一下其原理Q各个客L(fng)的实现基本相同?/p>

下面假设memcached服务器有node1~node3三台Q? 应用E序要保存键名ؓ(f)“tokyo”“kanagawa”“chiba”“saitama”“gunma” 的数据?/p>


? 分布式简介:(x)准备

首先向memcached中添?#8220;tokyo”。将“tokyo”传给客户端程序库后, 客户端实现的法׃(x)Ҏ(gu)“?#8221;来决定保存数据的memcached服务器? 服务器选定后,卛_令它保存“tokyo”?qing)其倹{?/p>


? 分布式简介:(x)d?/p>

同样Q?#8220;kanagawa”“chiba”“saitama”“gunma”都是先选择服务器再保存?/p>

接下来获取保存的数据。获取时也要要获取的键“tokyo”传递给函数库? 函数库通过与数据保存时相同的算法,Ҏ(gu)“?#8221;选择服务器? 使用的算法相同,p选中与保存时相同的服务器Q然后发送get命o(h)? 只要数据没有因ؓ(f)某些原因被删除,p获得保存的倹{?/p>


? 分布式简介:(x)获取?/p>

q样Q将不同的键保存C同的服务器上Q就实现?jin)memcached的分布式? memcached服务器增多后Q键׃(x)分散Q即使一台memcached服务器发生故? 无法q接Q也不会(x)影响其他的缓存,pȝ依然能l运行?/p>

接下来介l?a >W??/a> 中提到的Perl客户端函数库Cache::Memcached实现的分布式Ҏ(gu)?/p>

Cache::Memcached的分布式Ҏ(gu)

Perl的memcached客户端函数库Cache::Memcached? memcached的作者Brad Fitzpatrick的作品,可以说是原装的函数库?jin)?/p>

该函数库实现?jin)分布式功能Q是memcached标准的分布式Ҏ(gu)?/p>

Ҏ(gu)余数计算分散

Cache::Memcached的分布式Ҏ(gu)单来_(d)是“Ҏ(gu)服务器台数的余数q行分散”? 求得键的整数哈希|再除以服务器台数Q根据其余数来选择服务器?/p>

下面Cache::Memcached化成以下的Perl脚本来进行说明?/p>

use strict;

use warnings;

use String::CRC32;



my @nodes = ('node1','node2','node3');

my @keys = ('tokyo', 'kanagawa', 'chiba', 'saitama', 'gunma');



foreach my $key (@keys) {

my $crc = crc32($key); # CRC?br />
my $mod = $crc % ( $#nodes + 1 );

my $server = $nodes[ $mod ]; # Ҏ(gu)余数选择服务?br />
printf "%s => %s"n", $key, $server;

}

Cache::Memcached在求哈希值时使用?jin)CRC?/p>

首先求得字符串的CRC|Ҏ(gu)该值除以服务器节点数目得到的余数决定服务器? 上面的代码执行后输入以下l果Q?/p>

tokyo       => node2

kanagawa => node3

chiba => node2

saitama => node1

gunma => node1

Ҏ(gu)该结果,“tokyo”分散到node2Q?#8220;kanagawa”分散到node3{? 多说一句,当选择的服务器无法q接ӞCache::Memcached?x)将q接ơ数 d到键之后Q再ơ计哈希值ƈ试q接。这个动作称为rehash? 不希望rehash时可以在生成Cache::Memcached对象时指?#8220;rehash => 0”选项?/p>

Ҏ(gu)余数计算分散的缺?/h3>

余数计算的方法简单,数据的分散性也相当优秀Q但也有其缺炏V? 那就是当d或移除服务器Ӟ~存重组的代L(fng)当巨大? d服务器后Q余数就?x)生巨变,q样无法获取与保存时相同的服务器, 从而媄(jing)响缓存的命中率。用Perl写段代码来验证其代h(hun)?/p>

use strict;

use warnings;

use String::CRC32;



my @nodes = @ARGV;

my @keys = ('a'..'z');

my %nodes;



foreach my $key ( @keys ) {

my $hash = crc32($key);

my $mod = $hash % ( $#nodes + 1 );

my $server = $nodes[ $mod ];

push @{ $nodes{ $server } }, $key;

}



foreach my $node ( sort keys %nodes ) {

printf "%s: %s"n", $node, join ",", @{ $nodes{$node} };

}

q段Perl脚本演示?jin)?#8220;a”?#8220;z”的键保存到memcachedq访问的情况? 其保存?sh)mod.plq执行?/p>

首先Q当服务器只有三台时Q?/p>

$ mod.pl node1 node2 nod3

node1: a,c,d,e,h,j,n,u,w,x

node2: g,i,k,l,p,r,s,y

node3: b,f,m,o,q,t,v,z

l果如上Qnode1保存a、c、d、e……Qnode2保存g、i、k……Q? 每台服务器都保存?sh)?个到10个数据?/p>

接下来增加一台memcached服务器?/p>

$ mod.pl node1 node2 node3 node4

node1: d,f,m,o,t,v

node2: b,i,k,p,r,y

node3: e,g,l,n,u,w

node4: a,c,h,j,q,s,x,z

d?jin)node4。可见,只有d、i、k、p、r、y命中?jin)。像q样Q添加节点后 键分散到的服务器?x)发生巨大变化?6个键中只有六个在讉K原来的服务器Q? 其他的全都移C(jin)其他服务器。命中率降低?3%。在Web应用E序中用memcachedӞ 在添加memcached服务器的瞬间~存效率?x)大q度下降Q负载会(x)集中到数据库服务器上Q? 有可能会(x)发生无法提供正常服务的情c(din)?/p>

mixi的Web应用E序q用中也有这个问题,D无法dmemcached服务器? 但由于用了(jin)新的分布式方法,现在可以轻而易丑֜dmemcached服务器了(jin)? q种分布式方法称?Consistent Hashing?/p>

Consistent Hashing

关于Consistent Hashing的思想Qmixi株式?x)社的开发blog{许多地斚w介绍q, q里只简单地说明一下?/p>

Consistent Hashing的简单说?/h3>

Consistent Hashing如下所C:(x)首先求出memcached服务器(节点Q的哈希| q将光|到0?32的圆QcontinuumQ上? 然后用同L(fng)Ҏ(gu)求出存储数据的键的哈希|q映到圆上? 然后从数据映到的位|开始顺旉查找Q将数据保存到找到的W一个服务器上? 如果过232仍然找不到服务器Q就?x)保存到W一台memcached服务器上?/p>


? Consistent HashingQ基本原?/p>

从上囄状态中d一台memcached服务器。余数分布式法׃保存键的服务器会(x)发生巨大变化 而媄(jing)响缓存的命中率,但Consistent Hashing中,只有在continuum上增加服务器的地炚w时针方向的 W一台服务器上的键会(x)受到影响?/p>


? Consistent HashingQ添加服务器

因此QConsistent Hashing最大限度地抑制?jin)键的重新分布? 而且Q有的Consistent Hashing的实现方法还采用?jin)虚拟节点的思想? 使用一般的hash函数的话Q服务器的映地点的分布非常不均匀? 因此Q用虚拟节点的思想Qؓ(f)每个物理节点Q服务器Q? 在continuum上分?00?00个点。这样就能抑制分布不均匀Q? 最大限度地减小服务器增减时的缓存重新分布?/p>

通过下文中介l的使用Consistent Hashing法的memcached客户端函数库q行试的结果是Q? 由服务器台数QnQ和增加的服务器台数QmQ计增加服务器后的命中率计公式如下:(x)

(1 - n/(n+m)) * 100

支持Consistent Hashing的函数库

本连载中多次介绍的Cache::Memcached虽然不支持Consistent HashingQ? 但已有几个客L(fng)函数库支持了(jin)q种新的分布式算法? W一个支持Consistent Hashing和虚拟节点的memcached客户端函数库? 名ؓ(f)libketama的PHP库,由last.fm开发?/p>

至于Perl客户端,q蝲?a >W??/a> 中介l过的Cache::Memcached::Fast和Cache::Memcached::libmemcached支持 Consistent Hashing?/p>

两者的接口都与Cache::Memcached几乎相同Q如果正在用Cache::MemcachedQ? 那么可以方便地替换q来。Cache::Memcached::Fast重新实现?jin)libketamaQ? 使用Consistent Hashing创徏对象时可以指定ketama_points选项?/p>

my $memcached = Cache::Memcached::Fast->new({

servers => ["192.168.0.1:11211","192.168.0.2:11211"],

ketama_points => 150

});

另外QCache::Memcached::libmemcached 是一个用了(jin)Brain Aker开发的C函数库libmemcached的Perl模块? libmemcached本n支持几种分布式算法,也支持Consistent HashingQ? 其Perll定也支持Consistent Hashing?/p>

ȝ

本次介绍?jin)memcached的分布式法Q主要有memcached的分布式是由客户端函数库实现Q? 以及(qing)高效率地分散数据的Consistent Hashing法。下ơ将介绍mixi在memcached应用斚w的一些经验, 和相关的兼容应用E序?/p>


5. memcached的应用和兼容E序


发表日:(x)2008/7/30
作者:(x)镉K雅广(Masahiro Nagano)
原文链接Q?a >http://gihyo.jp/dev/feature/01/memcached/0005

我是Mixi的长野。memcached的连载终于要l束?jin)? ?a >上次为止Q? 我们介绍?jin)与memcached直接相关的话题,本次介绍一些mixi的案例和 实际应用上的话题Qƈ介绍一些与memcached兼容的程序?

mixi案例研究

mixi在提供服务的初期阶段׃用了(jin)memcached? 随着|站讉K量的急剧增加Q单Uؓ(f)数据库添加slave已无法满需要,因此引入?jin)memcached? 此外Q我们也从增加可扩展性的斚wq行?jin)验证,证明了(jin)memcached的速度和稳定性都能满需要? 现在Qmemcached已成为mixi服务中非帔R要的l成部分?/p>


? 现在的系l组?/p>

服务器配|和数量

mixi使用?jin)许许多多服务器Q如数据库服务器、应用服务器、图片服务器? 反向代理服务器等。单单memcached有近200台服务器在运行? memcached服务器的典型配置如下Q?/p>

  • CPUQIntel Pentium 4 2.8GHz
  • 内存Q?GB
  • 盘Q?46GB SCSI
  • 操作pȝQLinuxQx86_64Q?/li>

q些服务器以前曾用于数据库服务器{。随着CPU性能提升、内存(sh)h(hun)g降, 我们U极地将数据库服务器、应用服务器{换成了(jin)性能更强大、内存更多的服务器? q样Q可以抑制mixi整体使用的服务器数量的急剧增加Q降低管理成本? ׃memcached服务器几乎不占用CPUQ就换下来的服务器用作memcached服务器了(jin)?/p>

memcachedq程

每台memcached服务器仅启动一个memcachedq程。分配给memcached的内存(sh)ؓ(f)3GBQ? 启动参数如下Q?/p>

/usr/bin/memcached -p 11211 -u nobody -m 3000 -c 30720

׃使用?jin)x86_64的操作系l,因此能分?GB以上的内存?2位操作系l中Q? 每个q程最多只能?GB内存。也曄考虑q启动多个分?GB以下内存的进E, 但这样一台服务器上的TCPq接数就?x)成倍增加,理上也变得复杂Q? 所以mixiq一使用?4位操作系l?/p>

另外Q虽然服务器的内存(sh)ؓ(f)4GBQ却仅分配了(jin)3GBQ是因ؓ(f)内存分配量超q这个| 有可能D内存?sh)?swap)。连载的W??/a>? 前坂讲解q了(jin)memcached的内存存?#8220;slab allocator”Q当时说q,memcached启动? 指定的内存分配量是memcached用于保存数据的量Q没有包?#8220;slab allocator”本n占用的内存? 以及(qing)Z(jin)保存数据而设|的理I间。因此,memcachedq程的实际内存分配量要比 指定的容量要大,q一点应当注意?/p>

mixi保存在memcached中的数据大部分都比较?yu)。这Pq程的大要? 指定的容量大很多。因此,我们反复改变内存分配量进行验证, 认?GB的大不?x)引发swapQ这是现在应用的数倹{?/p>

memcached使用Ҏ(gu)和客L(fng)

现在Qmixi的服务将200台左右的memcached服务器作Z个pool使用? 每台服务器的定w?GBQ那么全体就有了(jin)近600GB的巨大的内存数据库? 客户端程序库使用?jin)本q蝲中多ơ提到R的Cache::Memcached::FastQ? 与服务器q行交互。当?dng)~存的分布式法使用的是 W??/a>介绍q的 Consistent Hashing法?/p>

应用层上memcached的用方法由开发应用程序的工程师自行决定ƈ实现? 但是Qؓ(f)?jin)防止R轮再造、防止Cache::Memcached::Fast上的教训再次发生Q? 我们提供?jin)Cache::Memcached::Fast的wrap模块q用?/p>

通过Cache::Memcached::Fastl持q接

Cache::Memcached的情况下Q与memcached的连接(文g句柄Q保存在Cache::Memcached包内的类变量中? 在mod_perl和FastCGI{环境下Q包内的变量不会(x)像CGI那样随时重新启动Q? 而是在进E中一直保持。其l果是不会(x)断开与memcached的连接, 减少?jin)TCPq接建立时的开销Q同时也能防止短旉内反复进行TCPq接、断开 而导致的TCP端口资源枯竭?/p>

但是QCache::Memcached::Fast没有q个功能Q所以需要在模块之外 Cache::Memcached::Fast对象保持在类变量中,以保证持久连接?/p>

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(@_);

}

上面的例子中QCache::Memcached::Fast对象保存到类变量$fast中?/p>

公共数据的处理和rehash

诸如mixi的主上的新闻这L(fng)所有用户共享的~存数据、设|信息等数据Q? ?x)占用许多页Q访问次C非常多。在q种条g下,讉K很容易集中到某台memcached服务器上? 讉K集中本nq不是问题,但是一旦访问集中的那台服务器发生故障导致memcached无法q接Q? ׃(x)产生巨大的问题?/p>

q蝲?a >W??/a> 中提刎ͼCache::Memcached拥有rehash功能Q即在无法连接保存数据的服务器的情况下, ?x)再ơ计hash|q接其他的服务器?/p>

但是QCache::Memcached::Fast没有q个功能。不q,它能够在q接服务器失败时Q? 短时间内不再q接该服务器的功能?/p>

my $fast = Cache::Memcached::Fast->new({

max_failures => 3,

failure_timeout => 1

});

在failure_timeoutU内发生max_failures以上ơ连接失败,׃再连接该memcached服务器? 我们的设|是1U钟3ơ以上?/p>

此外Qmixiq(sh)ؓ(f)所有用户共享的~存数据的键名设|命名规则, W合命名规则的数据会(x)自动保存到多台memcached服务器中Q? 取得时从中仅选取一台服务器。创函数库后Q就可以使memcached服务器故? 不再产生其他影响?/p>

memcached应用l验

到此为止介绍?jin)memcached内部构造和函数库,接下来介l一些其他的应用l验?/p>

通过daemontools启动

通常情况下memcachedq行得相当稳定,但mixi现在使用的最新版1.2.5 曄发生q几ơmemcachedq程L的情c(din)架构上保证?jin)即使有几台memcached故障 也不?x)?jing)响服务,不过对于memcachedq程L的服务器Q只要重新启动memcachedQ? 可以正常运行,所以采用了(jin)监视memcachedq程q自动启动的Ҏ(gu)? 于是使用?jin)daemontools?/p>

daemontools是qmail的作者DJB开发的UNIX服务理工具集, 其中名ؓ(f)supervise的程序可用于服务启动、停止的服务重启{?/p>

q里不介ldaemontools的安装了(jin)。mixi使用?jin)以下的run脚本来启动memcached?/p>

#!/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使用?jin)名?#8220;nagios”的开源监视Y件来监视memcached?/p>

在nagios中可以简单地开发插Ӟ可以详细地监视memcached的get、add{动作? 不过mixi仅通过stats命o(h)来确认memcached的运行状态?/p>

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

}

此外Qmixistats目录的结果通过rrdtool转化成图形,q行性能监视Q? q将每天的内存(sh)用量做成报表Q通过邮g与开发者共享?/p>

memcached的性能

q蝲中已介绍q,memcached的性能十分优秀。我们来看看mixi的实际案例? q里介绍的图表是服务所使用的访问最为集中的memcached服务器?/p>


? h?/p>


? 量


? TCPq接?/p>

从上至下依次求数、流量和TCPq接数。请求数最大ؓ(f)15000qpsQ? 量辑ֈ400MbpsQ这时的q接数已过?0000个? 该服务器没有特别的硬Ӟ是开头介l的普通的memcached服务器? 此时的CPU利用率ؓ(f)Q?/p>


? CPU利用?/p>

可见Q仍然有idle的部分。因此,memcached的性能非常高, 可以作ؓ(f)Web应用E序开发者放?j)地保存(sh)时数据或缓存数据的地方?/p>

兼容应用E序

memcached的实现和协议都十分简单,因此有很多与memcached兼容的实现? 一些功能强大的扩展可以memcached的内存数据写到磁盘(sh)Q实现数据的持久性和冗余? q蝲W??/a> 介绍q,以后的memcached的存储层变成可扩展的(pluggableQ,逐渐支持q些功能?/p>

q里介绍几个与memcached兼容的应用程序?/p>

repcached
为memcached提供复制(replication)功能的patch?/dd>
Flared
存储到QDBM。同时实C(jin)异步复制和fail over{功能?/dd>
memcachedb
存储到BerkleyDB。还实现?jin)message queue?/dd>
Tokyo Tyrant
数据存储到Tokyo Cabinet。不仅与memcached协议兼容Q还能通过HTTPq行讉K?/dd>

Tokyo Tyrant案例

mixi使用?jin)上q兼容应用程序中的Tokyo Tyrant。Tokyo Tyrant是^林开发的 Tokyo Cabinet DBM的网l接口。它有自q协议Q但也拥有memcached兼容协议Q? 也可以通过HTTPq行数据交换。Tokyo Cabinet虽然是一U将数据写到盘的实玎ͼ但速度相当快?/p>

mixiq没有将Tokyo Tyrant作ؓ(f)~存服务器,而是它作ؓ(f)保存键值对l合的DBMS来用? 主要作ؓ(f)存储用户上次讉K旉的数据库来用。它与几乎所有的mixi服务都有养I 每次用户讉K面旉要更新数据,因此负荷相当高。MySQL的处理十分笨重, 单独使用memcached保存数据又有可能?x)丢失数据,所以引入了(jin)Tokyo Tyrant? 但无需重新开发客L(fng)Q只需原封不动C用Cache::Memcached::Fast卛_Q? q也是优点之一。关于Tokyo Tyrant的详l信息,请参考本公司的开发blog?/p>

ȝ

到本ơؓ(f)止,“memcached全面剖析”pdq束了(jin)。我们介l了(jin)memcached的基、内部结构? 分散法和应用等内容。读完后如果(zhn)能对memcached产生兴趣Q就是我们的荣幸? 关于mixi的系l、应用方面的信息Q请参考本公司?a >开发blog? 感谢(zhn)的阅读?/p>








Blog of JoJo 2009-07-03 12:20 发表评论
]]>每日一?2009/07/03 How to install NGINXhttp://www.tkk7.com/ruoyoux/articles/285313.htmlBlog of JoJoBlog of JoJoFri, 03 Jul 2009 03:28:00 GMThttp://www.tkk7.com/ruoyoux/articles/285313.htmlhttp://www.tkk7.com/ruoyoux/comments/285313.htmlhttp://www.tkk7.com/ruoyoux/articles/285313.html#Feedback0http://www.tkk7.com/ruoyoux/comments/commentRss/285313.htmlhttp://www.tkk7.com/ruoyoux/services/trackbacks/285313.html Nginx (pronounced Engine-X) is a russian open source httpd server originally written by Igor Sysoev back in 2005. Nginx is a very light weight httpd server and reverse proxy. It is estimated that approx. 3 per cent of all web servers run nginx. In Russia the number is as high as 20 percent, including some of their biggest web sites. Nginx is also used by Wordpress.com and 4chan.

Why use Nginx instead of Apache or Lighty? Nginx should be fast. I mean FAST. Fast in a way of over 10000 concurrent requests / sec per server. Now that's fast!

I have wanted to screw 'round with Nginx for a while, so here goes nothing!

How to install Nginx on your Linux box

Nginx can be downloaded from www.nginx.net. Simple web page displays the latest distribution packages and small introduction. Further instructions can be found from Nginx Wiki.

I installed Nginx on my CentOs 5.1 running on VMWare & Macbook. Nginx's version was 0.6.32. The default installation is very straightforward - configure, make & make install. I had to install pcre packages to my box before installing httpd server in order to enable rewrite module. I also used --prefix module to install application where i wanted:

[root@cluster1 nginx-0.6.32]# ./configure --prefix=/opt/nginx-0.6.32
[root@cluster1 nginx-0.6.32]# make
[root@cluster1 nginx-0.6.32]# make install

After this Nginx is ready to serve static files!


How to configure Nginx

When you move to your Nginx installation directory, here's what you see:

drwxr-xr-x 2 root root 4096 Oct 5 23:52 sbin
drwxr-xr-x 2 root root 4096 Oct 5 23:52 html
drwxr-xr-x 2 root root 4096 Oct 5 23:52 conf

Sbin directory has only nginx executable file which starts up httpd. Html directory is same as htdocs directory in Apache - copy your files here in order to serve 'em to the world! Conf-file has all configuration files.

When you start up your nginx (just go to sbin and type ./nginx in order to start your web server!) you get few more directories:

drwx------ 2 nobody root 4096 Oct 5 23:52 proxy_temp
drwxr-xr-x 2 root root 4096 Oct 5 23:52 logs
drwx------ 2 nobody root 4096 Oct 5 23:52 fastcgi_temp
drwx------ 2 nobody root 4096 Oct 5 23:52 client_body_temp

In the conf-directory you can see the following files:

-rw-r--r-- 1 root root 3610 Oct 5 23:52 win-utf
-rw-r--r-- 1 root root 2726 Oct 5 23:52 nginx.conf.default
-rw-r--r-- 1 root root 2726 Oct 5 23:52 nginx.conf
-rw-r--r-- 1 root root 2991 Oct 5 23:52 mime.types.default
-rw-r--r-- 1 root root 2991 Oct 5 23:52 mime.types
-rw-r--r-- 1 root root 2223 Oct 5 23:52 koi-win
-rw-r--r-- 1 root root 2837 Oct 5 23:52 koi-utf
-rw-r--r-- 1 root root 909 Oct 5 23:52 fastcgi_params.default
-rw-r--r-- 1 root root 909 Oct 5 23:52 fastcgi_params

The most important file of them all is of course nginx.conf. The default configuration looks like this after installation:

#user nobody;
worker_processes 1;

#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;

#pid logs/nginx.pid;


events {
worker_connections 1024;
}


These are default configuration parameters to set user and logging preferences. If you are your box to run many different applications it is a good idea to change default user to something else, like "nginx" or "www_user".

Worker_connections parameter sets the maximum number of connections each worker can handle. This is quite good default value.

The following part defines base settings for the http access:

http {
include mime.types;
default_type application/octet-stream;


You should not tamper round with mime types because you will likely end up with screwed up web server!

If you want to, you can also change default log format in the following part.

#log_format main '$remote_addr - $remote_user [$time_local] $request '
# '"$status" $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';

#access_log logs/access.log main;


TCP nopush setting means that HTTP response hearders are all sent in one packet. Sendfile setting means that Nginx ignores the details of the file it is sending and uses kernel sendfile support instead. Keepalive setting defines how long server waits for users packets. This should be changed only to few seconds on busy sites. Gzip compression saves bandwith on site, depending what kind of packets server is sending.

sendfile on;
#tcp_nopush on;

#keepalive_timeout 0;
keepalive_timeout 65;

#gzip on;



The following server part is just like server settings on Apache HTTPD and if you have tampered 'round with Apache before this is quite straightforward to you.

server {
listen 80;
server_name localhost;

#charset koi8-r;

#access_log logs/host.access.log main;

location / {
root html;
index index.html index.htm;
}

#error_page 404 /404.html;

# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}


Example how to configure virtual host on Nginx:

# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;

# location / {
# root html;
# index index.html index.htm;
# }
#}




These were basic examples of Nginx and what one can do with it. I stripped some configuration examples but here you can see the basics. Later we're going to configure Nginx to use PHP and we're going thru how to use mod_rewrite with Nginx.


[root@TEST ~]# cd /usr/local/site/nginx/conf/



Blog of JoJo 2009-07-03 11:28 发表评论
]]>
每日一?2009/06/11 NginX + Apache http://www.tkk7.com/ruoyoux/articles/281404.htmlBlog of JoJoBlog of JoJoThu, 11 Jun 2009 03:48:00 GMThttp://www.tkk7.com/ruoyoux/articles/281404.htmlhttp://www.tkk7.com/ruoyoux/comments/281404.htmlhttp://www.tkk7.com/ruoyoux/articles/281404.html#Feedback0http://www.tkk7.com/ruoyoux/comments/commentRss/281404.htmlhttp://www.tkk7.com/ruoyoux/services/trackbacks/281404.html --------------------------------------------------------------------------------------------
#
# Virtual Hosts
#
# If you want to maintain multiple domains/hostnames on your
# machine you can setup VirtualHost containers for them. Most configurations
# use only name-based virtual hosts so the server doesn't need to worry about
# IP addresses. This is indicated by the asterisks in the directives below.
#
# Please see the documentation at
# <URL:http://httpd.apache.org/docs/2.2/vhosts/>
# for further details before you try to setup virtual hosts.
#
# You may use the command line option '-S' to verify your virtual host
# configuration.

#
# Use name-based virtual hosting.
#
NameVirtualHost *:8080

#
# VirtualHost example:
# Almost any Apache directive may go into a VirtualHost container.
# The first VirtualHost section is used for all requests that do not
# match a ServerName or ServerAlias in any <VirtualHost> block.
#

<VirtualHost *:8080>
DocumentRoot /usr/local/site/webroot/mydomain1.com
ServerName mydomain1.com
ErrorLog "/var/log/apache_log/mydomain1.com-error_log"
CustomLog "|/usr/local/site/apache/bin/rotatelogs /var/log/apache_log/apache_accesslog/mydomain1.com-access_log.%Y%m%d 86400 -360" common
<Directory "/usr/local/site/webroot/mydomain1.com">
Options -Indexes FollowSymLinks
AllowOverride None
Options ExecCGI
#Options None
Order allow,deny
Allow from all

#AuthType basic
#AuthName "private area"
#AuthBasicProvider file
#AuthUserFile /usr/local/site/webroot/mydomain1.com/.htpasswd
#Require valid-user
#Options Indexes FollowSymLinks
#AllowOverride All
#Order deny,allow
ErrorDocument 404  '/?c=interact.image&f=show'
</Directory>
RedirectMatch 404 /".svn(/|$)

</VirtualHost>


<VirtualHost *:8080>
DocumentRoot /usr/local/site/webroot/mydomain2.com
ServerName mydomain2.com
ErrorLog "/var/log/apache_log/hkogop-error_log"
CustomLog "|/usr/local/site/apache/bin/rotatelogs /var/log/apache_log/apache_accesslog/mydomain2.com-access_log.%Y%m%d 86400 -360" common
<Directory "/usr/local/site/webroot/mydomain2.com">
Options -Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all

#AuthType basic
#AuthName "private area"
#AuthBasicProvider file
#AuthUserFile /usr/local/site/webroot/mydomain1.com/.htpasswd
#Require valid-user
#Options -Indexes FollowSymLinks
#AllowOverride All
#Order deny,allow
ErrorDocument 404  '/?c=interact.image&f=show'
</Directory>
RedirectMatch 404 /".svn(/|$)

</VirtualHost>


<VirtualHost *:8080>
DocumentRoot /usr/local/site/webroot/mydomain3.com
ServerName mydomain3.com
ErrorLog "/var/log/apache_log/stage-hkogop-error_log"
CustomLog "|/usr/local/site/apache/bin/rotatelogs /var/log/apache_log/apache_accesslog/mydomain3.com-access_log.%Y%m%d 86400 -360" common
<Directory "/usr/local/site/webroot/mydomain3.com">
Options -Indexes FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all

#AuthType basic
#AuthName "private area"
#AuthBasicProvider file
#AuthUserFile /usr/local/site/webroot/mydomain3.com/.htpasswd
#Require valid-user
#Options -Indexes FollowSymLinks
#AllowOverride All
#Order deny,allow
</Directory>
RedirectMatch 404 /".svn(/|$)

</VirtualHost>



<VirtualHost *:8080>
DocumentRoot /usr/local/site/webroot/mydomain4.com
ServerName mydomain4.com
ErrorLog "/var/log/apache_log/mydomain4.com-error_log"
CustomLog "|/usr/local/site/apache/bin/rotatelogs /var/log/apache_log/apache_accesslog/mydomain4.com-access_log.%Y%m%d 86400 -360" common

<Directory "/usr/local/site/webroot/mydomain4.com">
Options -Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all

#AuthType basic
#AuthName "private area"
#AuthBasicProvider file
#AuthUserFile /usr/local/site/webroot/mydomain4.com/.htpasswd
#Require valid-user
#Options -Indexes FollowSymLinks
#AllowOverride All
#Order deny,allow

</Directory>
<Location /zcart/index.php>
 Order Deny,Allow
 Deny from All
 Satisfy All
</Location>

RedirectMatch 404 /".svn(/|$)
</VirtualHost>

cat nginx.conf
--------------------------------------------------------------------------------------------
user  mdrop;
worker_processes  1;
master_process on;
daemon off;

error_log  logs/error.log;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] $request '
                      '"$status" $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  logs/access.log  main;

    sendfile        on;
    tcp_nopush     on;
    tcp_nodelay     on;
    #keepalive_timeout  0;
    keepalive_timeout  65;


        gzip on;
        gzip_types text/html text/css ;
        gzip_comp_level 3;
        gzip_proxied any;
        gzip_vary on;

    server {
        listen       80;
        server_name  _*;

        #charset koi8-r;

        #access_log  logs/access.log  ;

  
        location ~* ".(jpg|jpeg|gif|css|png|js|ico|html|inc|mp3|xml|swf)$ {
            root   /usr/local/site/webroot/$host/;
            index  index.html index.htm index.php;
    }

        location / {
                proxy_pass   http://127.0.0.1:8080;
        proxy_set_header  Host  $host;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_pass_header Server;

        client_max_body_size       8m;
        client_body_buffer_size    128k;

        proxy_connect_timeout      90;
        proxy_send_timeout         90;
        proxy_read_timeout         90;

        proxy_buffer_size          4k;
        proxy_buffers              64 32k;
        proxy_busy_buffers_size    64k;
        proxy_temp_file_write_size 64k;

        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }


        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        location ~ /".ht {
            deny  all;
        }
        location ~ /".svn {
            deny  all;
        }

        location ~ /"sql {
            deny  all;
        }

    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443;
    #    server_name  localhost;

    #    ssl                  on;
    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_timeout  5m;

    #    ssl_protocols  SSLv2 SSLv3 TLSv1;
    #    ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
    #    ssl_prefer_server_ciphers   on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}





Blog of JoJo 2009-06-11 11:48 发表评论
]]>
每日一?2009/06/09 How to disable directory browsing using .htaccess - Apache Web Serverhttp://www.tkk7.com/ruoyoux/articles/280804.htmlBlog of JoJoBlog of JoJoTue, 09 Jun 2009 02:49:00 GMThttp://www.tkk7.com/ruoyoux/articles/280804.htmlhttp://www.tkk7.com/ruoyoux/comments/280804.htmlhttp://www.tkk7.com/ruoyoux/articles/280804.html#Feedback0http://www.tkk7.com/ruoyoux/comments/commentRss/280804.htmlhttp://www.tkk7.com/ruoyoux/services/trackbacks/280804.htmldisable directory browsing in security aspect. To disable directory browsing in apache web server you need to edit the httpd.conf or .htaccess

Disable directory browsing using .htaccess:-

  • Open your .htacces file
  • Look for Options Indexes
  • If Options Indexes exists modify it to Options -Indexes or else add Options -Indexes as a new line
  • The directory browsing feature should be disable by now

Disable directory browsing using httpd.conf:-

  • Open your httpd.conf, normally it’s located at /usr/local/apache/conf or /etc/httpd.conf
  • Go to your own Virtual Host settings and look for “Options Indexes
  • Change the Indexes to -Indexes if Option Indexes exists or else add the Options -Indexes line
  • Restart your apache web server.
  • The directory browsing feature should be disable by now

Disable directory browsing in CPanel Share Hosting enviroment:-

  • Login to your CPanel
  • Click on Index Manager
  • Directory will be list down. Click on the directory name which you want to disable the directory browsing
  • Select No Index and click Save
  • The directory browsing feature should be disable by now

Once you disable directory browsing, visitor will not able to browse your directory by accessing the directory directly (if there is no index.html file). This will protect your files from exposing to the public.



http://ubuntuforums.org/archive/index.php/t-234876.html



Blog of JoJo 2009-06-09 10:49 发表评论
]]>
每日一?2009/06/06 linux服务器配|之Sendmail配置http://www.tkk7.com/ruoyoux/articles/280353.htmlBlog of JoJoBlog of JoJoSat, 06 Jun 2009 11:22:00 GMThttp://www.tkk7.com/ruoyoux/articles/280353.htmlhttp://www.tkk7.com/ruoyoux/comments/280353.htmlhttp://www.tkk7.com/ruoyoux/articles/280353.html#Feedback0http://www.tkk7.com/ruoyoux/comments/commentRss/280353.htmlhttp://www.tkk7.com/ruoyoux/services/trackbacks/280353.html今天我们来配|一下简单的sendmail服务。。。呵c(din)、、真的简单的配置。。?br />
rpm -q sendmail

q需安装q三个包
 sendmail-cf-8.12.8-4.i386

 sendmail-devel-8.12.8-4.i

 sendmail-doc-8.12.8-4.i38

安装好后Q我开始配|文ӞQ,Q,

修改/etc/mail/local-hosts-name文g
[root@localhost named]# cat /etc/mail/local-host-names 
# local-host-names - include all aliases for your machine here. 
xuwini.com 


更改/etc/mail/sendmail.mc文gQ修改下列地方:(x) 
DaemonPortsOptions=Port=smtp,Addr=127.0.0.1, Name=MTA 更改为:(x) 
DaemonPortsOptions=Port=smtp,Addr=yourip或?.0.0.0, Name=MTA 
然后m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf 


修改 /etc/rc.d/rc.local
加入一?nbsp;/usr/sbin/saslauthd -a shadow


用户理 
认证的配|:(x)修改/etc/mail/sendmail.mc中的字段Q取?#8220;TRUST_AUTH_MECH”一行和下一?#8220;define”处的注释。然后m4 /etc/ mail/sendmail.mc>/etc/mail/sendmail.cf?nbsp;
[root@localhost named]# chkconfig --list saslauthd 开启认?nbsp;
saslauthd 0:off 1:off 2:off 3:off 4:off 5:off 6:off 
[root@localhost named]# chkconfig --level 35 saslauthd on 


建立用户帐号 
[root@localhost named]# groupadd mailuser 
[root@localhost named]# adduser -g mailuser -s /bin/bash xuwin 
[root@localhost named]# adduser -g mailuser -s /sbin/nologin xxx 
[root@localhost named]# passwd xuwin 
[root@localhost named]# passwd xxx 密码都是123 



【修?etc/aliases文g实现邮g转发和邮件列表:(x) 
admin: xxx 为邮件用户xxx讄别名admin 
testgroup: xuwin,xxx 实现发 发给testgroup的邮件发lxuwin ?nbsp;xxx 以上2个可以分别测?nbsp;
#newaliases ?nbsp; -------对于我们单的邮g体系没什么大的用处,个h觉得



讉K控制讄 
更改/etc/mail/accesss文gQ增加:(x) 
[root@localhost named]# cat /etc/mail/access 
# Check the /usr/share/doc/sendmail/README.cf file for a description 
# of the format of this file. (search for access_db in that file) 
# The /usr/share/doc/sendmail/README.cf is part of the sendmail-doc 
# package. 

# by default we allow relaying from localhost... 
localhost.localdomain RELAY 
localhost RELAY 
127.0.0.1 RELAY 
xuwin.com RELAY 
完成后makemap hash /etc/mail/access.db < /etc/mail/accessq行数据库更新?br />

#service sendmail restart 

已经成功q入。。。?br /> 我们试着来写一份简单的信。。?br /> 那么我在服务器上收信看看。。。。晕倒。。把密码打出啦。。?br /> [root@localhost root]# telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 localhost.localdomain ESMTP Sendmail 8.12.8/8.12.8; Sun, 10 Aug 2008 20:47:0
6 +0800
mail from: root@xuwin.com
250 2.1.0 root@xuwin.com... Sender ok
rcpt to: xuwin@xuwin.com
250 2.1.5 xuwin@xuwin.com... Recipient ok
data
354 Enter mail, end with "." on a line by itself
test
hi.baidu.com/proxuwin
xuwin.com
.
250 2.0.0 m7ACl6B7004271 Message accepted for delivery
quit
221 2.0.0 localhost.localdomain closing connection
Connection closed by foreign host.
(g)查日志[root@localhost root]# tail /var/log/maillog

你如果想在客h上收发邮Ӟ那么q需跟着我做。。呵c(din)。。上面算是成功了(jin)Q我们看看接下来?x)不会(x)成功。。。。期待。?br />
(g)imap是否安装rpm -q imap
安装rpm -ivh imap-*.rpm

[root@localhost root]# chkconfig imap on
[root@localhost root]# service xinetd restart
停止 xinetdQ?nbsp; 定  ]
启动 xinetdQ?nbsp; 定  ]
[root@localhost root]# grep imap /etc/services
imap            143/tcp         imap2           # Interim Mail Access Proto v2
imap            143/udp         imap2
imap3           220/tcp                         # Interactive Mail Access
imap3           220/udp                         # Protocol v3
imaps           993/tcp                         # IMAP over SSL
imaps           993/udp                         # IMAP over SSL

有错误。。。那么就仔细(g)查一下,我们刚刚的配|?br /> 看了(jin)一下,我把|络服务重启?jin)一下。。不知道行不行。。。呵?br /> 我们l箋。。。。我估计是imap没配|好Q因为可以发送的。。。?br /> 你们看。。。没出错。。完全是可行的。。。。这个就是我们刚刚发的。。。?br /> 。。。。功夫不负有?j)h 啊。。找到原因了(jin)。。。呵c(din)?nbsp;/sbin/chkconfig imap on。。。。。。是imap没启动。。。晕倒。。?br />
收到信了(jin)把。。。?br />
当然我们不可能在一台服务器上那么瞎搞,一般都是两C个域q行邮g交互。。。方法跟q个是一L(fng)。。大家可以试试。。。呵c(din)。。?br />
教程到此Q不好意思,费大家那么多的旉在找错误上。。。?/strong>

Blog of JoJo 2009-06-06 19:22 发表评论
]]>
վ֩ģ壺 һƵ| ĻӰԺ| ߹ۿHַ| ˳777߲| ҹþþþþ| ޾Ʒ˳| ˳߹ۿa| պѸ岥| þw5www| 97޳| 99ƵƷƵ7| Ƶ| þþþþþAv| AV˵߹ۿ| jŮpƵ| þĻƵ| ƬƵ| þþþù˾Ʒҹ | ޵һAVվ| ޹ר| ԻȫƵۿ| ձAëһƬ| ĻӰѹۿ| Ƶһ| AVһ| Ƶ߹ۿѲӰԺ| þþƷ뾫Ʒר| ѱվڹۿ| AVרAVëվ| 91޾Ʒ߹ۿ| Ƶ߹ۿ| ߹ۿƵ| ëƬavպav| Ƶַ| ˮwww| ѸӰ| av뾫Ʒվ| ޹avŪŵ˸| avվ| ?VþþƷ| ޳aƬ߹|