`

memcached全面剖析

阅读更多

idv2.com

memcached全面剖析

长野雅广、前坂徹著

charlee 译

版本1.0

1

idv2.com

目录

译者序.................................................................................................................................................4

第1 章 memcached的基础.................................................................................................................5

1.1 memcached是什么?...............................................................................................................5

1.2 memcached的特征...................................................................................................................6

协议简单....................................................................................................................................6

基于libevent的事件处理..........................................................................................................6

内置内存存储方式.....................................................................................................................6

memcached不互相通信的分布式.............................................................................................6

1.3 安装memcached......................................................................................................................7

memcached的安装.....................................................................................................................7

memcached的启动.....................................................................................................................8

1.4 用客户端连接...........................................................................................................................8

1.5 使用Cache::Memcached..........................................................................................................9

使用Cache::Memcached连接memcached................................................................................9

保存数据..................................................................................................................................10

获取数据..................................................................................................................................10

删除数据..................................................................................................................................10

增一和减一操作.......................................................................................................................10

1.6 总结........................................................................................................................................11

第2章 理解memcached的内存存储..............................................................................................12

2.1 Slab Allocation机制:整理内存以便重复使用...................................................................12

Slab Allocation的主要术语.....................................................................................................13

2.2 在Slab中缓存记录的原理....................................................................................................13

2.3 Slab Allocator的缺点.............................................................................................................13

2.4 使用Growth Factor进行调优................................................................................................14

2.5 查看memcached的内部状态................................................................................................15

2.6 查看slabs的使用状况...........................................................................................................16

2.7 总结........................................................................................................................................17

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

3.1 memcached在数据删除方面有效利用资源.........................................................................18

数据不会真正从memcached中消失......................................................................................18

Lazy Expiration........................................................................................................................18

3.2 LRU:从缓存中有效删除数据的原理.................................................................................18

3.3 memcached的最新发展方向.................................................................................................18

关于二进制协议.......................................................................................................................19

二进制协议的格式...................................................................................................................19

HEADER中引人注目的地方..................................................................................................20

2

idv2.com

3.4 外部引擎支持........................................................................................................................20

外部引擎支持的必要性...........................................................................................................20

简单API设计的成功的关键...................................................................................................21

重新审视现在的体系...............................................................................................................21

3.5 总结.......................................................................................................................................22

第4 章 memcached的分布式算法...................................................................................................23

4.1 memcached的分布式.............................................................................................................23

memcached的分布式是什么意思?.......................................................................................23

4.2 Cache::Memcached的分布式方法........................................................................................25

根据余数计算分散...................................................................................................................25

根据余数计算分散的缺点.......................................................................................................26

4.3 Consistent Hashing.................................................................................................................27

Consistent Hashing的简单说明...............................................................................................27

支持Consistent Hashing的函数库..........................................................................................29

4.4 总结.......................................................................................................................................29

第5 章 memcached的应用和兼容程序...........................................................................................30

5.1 mixi案例研究.........................................................................................................................30

服务器配置和数量...................................................................................................................30

memcached进程.......................................................................................................................31

memcached使用方法和客户端...............................................................................................31

5.2 memcached应用经验.............................................................................................................32

通过daemontools启动.............................................................................................................33

监视..........................................................................................................................................33

memcached的性能...................................................................................................................33

5.3 兼容应用程序........................................................................................................................35

Tokyo Tyrant案例.....................................................................................................................35

5.4 总结.......................................................................................................................................36

3

idv2.com 译者序

译者序

如今,越来越多的Web应用程序开始使用memcached这个高速的缓存服务器软件。然而,

memcached的基础知识远远未能像其他Web技术那样普及,memcached在国内的大规模应用也鲜为

人知。而日本的mixi(http://mixi.jp)则在这方面走在了前面,不仅大规模使用memcached作为缓

存来加速Web应用,而且自行开发了Tokyo Cabinit、Tokyo Tyrant等一系列相关的软件。

最近,日本的技术评论社的网站上刊登了mixi的两名工程师长野雅广、前坂徹撰写的一篇连载

《memcachedを知り尽くす》。这篇连载语言简洁、通俗易懂,非常适合memcached入门的人阅读。

因此我将它翻译成中文,发表在我的技术blog(tech.idv2.com)上。然后将翻译结果合并后稍作加

工,形成了这篇PDF文档,以方便阅读。

本文的原文地址如下,懂日语的朋友可以直接去参考原文:

● http://gihyo.jp/dev/feature/01/memcached/

翻译后的文章地址如下:

● 第1章:http://tech.idv2.com/2008/07/10/memcached001/

● 第2章:http://tech.idv2.com/2008/07/11/memcached002/

● 第3章:http://tech.idv2.com/2008/07/16/memcached003/

● 第4章:http://tech.idv2.com/2008/07/24/memcached004/

● 第5章:http://tech.idv2.com/2008/07/31/memcached005/

本PDF可以在这个地址下载:

● http://tech.idv2.com/2008/08/17/memcachedpdf/

charlee

2008年8月17日

4

idv2.com 第1 章 memcached的基础

第1章 memcached的基础

我是 mixi 株式会社 开发部系统运营组的长野。日常负责程序的运营。从今天开始,将针对最近在

Web应用的可扩展性领域的热门话题memcached,与我公司开发部研究开发组的前坂一起,说明其

内部结构和使用。

1.1 memcached是什么?

memcached 是以LiveJournal 旗下Danga Interactive 公司的Brad Fitzpatric 为首开发的一款软件。现在

已成为mixi、hatena、Facebook、Vox、LiveJournal等众多服务中提高Web应用扩展性的重要因素。

许多Web应用都将数据保存到RDBMS中,应用服务器从中读取数据并在浏览器中显示。但随着数

据量的增大、访问的集中,就会出现RDBMS的负担加重、数据库响应恶化、网站显示延迟等重大

影响。

这时就该memcached大显身手了。memcached是高性能的分布式内存缓存服务器。一般的使用目的

是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展

性。

图1.1:一般情况下memcached的用途

5

idv2.com 第1 章 memcached的基础

1.2 memcached的特征

memcached作为高速运行的分布式缓存服务器,具有以下的特点。

• 协议简单

• 基于libevent的事件处理

• 内置内存存储方式

• memcached不互相通信的分布式

协议简单

memcached的服务器客户端通信并不使用复杂的XML等格式,而使用简单的基于文本行的协议。

因此,通过telnet也能在memcached上保存数据、取得数据。下面是例子。

$ telnet localhost 11211

Trying 127.0.0.1...

Connected to localhost.localdomain (127.0.0.1).

Escape character is '^]'.

set foo 0 0 3 (保存命令)

bar (数据)

STORED (结果)

get foo (取得命令)

VALUE foo 0 3 (数据)

bar (数据)

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

• http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt

基于libevent的事件处理

libevent是个程序库,它将Linux的epoll、BSD类操作系统的kqueue等事件处理功能封装成统一的

接口。即使对服务器的连接数增加,也能发挥O(1)的性能。memcached使用这个libevent库,因此

能在Linux、BSD、Solaris等操作系统上发挥其高性能。关于事件处理这里就不再详细介绍,可以

参考Dan Kegel的The C10K Problem。

• libevent: http://www.monkey.org/~provos/libevent/

• The C10K Problem: http://www.kegel.com/c10k.html

内置内存存储方式

为了提高性能,memcached中保存的数据都存储在memcached内置的内存存储空间中。由于数据仅

存在于内存中,因此重启memcached、重启操作系统会导致全部数据消失。另外,内容容量达到指

定值之后,就基于LRU(Least Recently Used)算法自动删除不使用的缓存。memcached本身是为缓存

而设计的服务器,因此并没有过多考虑数据的永久性问题。关于内存存储的详细信息,请参考本文

的第 2 章 以后前坂介绍的内容。

memcached不互相通信的分布式

memcached尽管是“分布式”缓存服务器,但服务器端并没有分布式功能。各个memcached不会互

相通信以共享信息。那么,怎样进行分布式呢?这完全取决于客户端的实现。本文也将介绍

memcached的分布式。

6

idv2.com 第1 章 memcached的基础

图1.2:memcached的分布式

接下来简单介绍一下memcached的使用方法。

1.3 安装memcached

memcached的安装比较简单,这里稍加说明。

memcached支持许多平台。

• Linux

• FreeBSD

• Solaris (memcached 1.2.5以上版本)

• Mac OS X

另外也能安装在Windows上。这里使用Fedora Core 8进行说明。

memcached的安装

运行memcached需要本文开头介绍的libevent库。Fedora 8中有现成的rpm包,通过yum命令安装

即可。

$ sudo yum install libevent libeventdevel

memcached的源代码可以从memcached网站上下载。本文执笔时的最新版本为1.2.5。Fedora 8虽然

也包含了memcached的rpm,但版本比较老。因为源代码安装并不困难,这里就不使用rpm了。

• 下载memcached:http://www.danga.com/memcached/download.bml

memcached安装与一般应用程序相同,configure、make、make install就行了。

$ wget http://www.danga.com/memcached/dist/memcached1.2.5.

tar.gz

$ tar zxf memcached1.2.5.

tar.gz

$ cd memcached1.2.5

$ ./configure

$ make

7

idv2.com 第1 章 memcached的基础

$ sudo make install

默认情况下memcached安装到/usr/local/bin下。

memcached的启动

从终端输入以下命令,启动memcached。

$ /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)

这里显示了调试信息。这样就在前台启动了memcached,监听TCP端口11211最大内存使用量为

64M。调试信息的内容大部分是关于存储的信息,下一章将具体说明。

作为daemon后台启动时,只需

$ /usr/local/bin/memcached p

11211 m

64m d

这里使用的memcached启动选项的内容如下。

选项说明

p

使用的TCP端口。默认为11211

m

最大内存大小。默认为64M

vv

用very vrebose模式启动,调试信息和错误输出到控制台

d

作为daemon在后台启动

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

$ /usr/local/bin/memcached h

命令可以显示。许多选项可以改变memcached的各种行为,推荐读一读。

1.4 用客户端连接

许多语言都实现了连接memcached的客户端,其中以Perl、PHP为主。仅仅memcached网站上列出

的语言就有

• Perl

• PHP

• Python

• Ruby

• C#

8

idv2.com 第1 章 memcached的基础

• C/C++

• Lua

等等。

• memcached 客户端API:http://www.danga.com/memcached/apis.bml

这里介绍通过mixi正在使用的Perl库链接memcached的方法。

1.5 使用Cache::Memcached

Perl的memcached客户端有

• Cache::Memcached

• Cache::Memcached::Fast

• Cache::Memcached::libmemcached

等几个CPAN模块。这里介绍的Cache::Memcached是memcached的作者Brad Fitzpatric的作品,应

该算是memcached的客户端中应用最为广泛的模块了。

• Cache::Memcached search.

cpan.org: http://search.cpan.org/dist/CacheMemcached/

使用Cache::Memcached连接memcached

下面的源代码为通过Cache::Memcached连接刚才启动的memcached的例子。

#!/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指定了memcached服务器的IP地址和一个选项,以生成实例。

Cache::Memcached常用的选项如下所示。

选项说明

servers 用数组指定memcached服务器和端口

compress_threshold 数据压缩时使用的值

namespace 指定添加到键的前缀

另外,Cache::Memcached通过Storable模块可以将Perl的复杂数据序列化之后再保存,因此散列、

数组、对象等都可以直接保存到memcached中。

9

idv2.com 第1 章 memcached的基础

保存数据

向memcached保存数据的方法有

• add

• replace

• set

它们的使用方法都相同:

my $add = $memcached>

add( '键', '值', '期限' );

my $replace = $memcached>

replace( '键', '值', '期限' );

my $set = $memcached>

set( '键', '值', '期限' );

向memcached保存数据时可以指定期限(秒)。不指定期限时,memcached按照LRU算法保存数据。

这三个方法的区别如下:

选项说明

add 仅当存储空间中不存在键相同的数据时才保存

replace 仅当存储空间中存在键相同的数据时才保存

set 与add和replace不同,无论何时都保存

获取数据

获取数据可以使用get和get_multi方法。

my $val = $memcached>

get('键');

my $val = $memcached>

get_multi('键1', '键2', '键3', '键4', '键5');

一次取得多条数据时使用get_multi。get_multi可以非同步地同时取得多个键值,其速度要比循环调

用get快数十倍。

删除数据

删除数据使用delete方法,不过它有个独特的功能。

$memcached>

delete('键', '阻塞时间(秒)');

删除第一个参数指定的键的数据。第二个参数指定一个时间值,可以禁止使用同样的键保存新数据。

此功能可以用于防止缓存数据的不完整。但是要注意,set 函数忽视该阻塞,照常保存数据。

增一和减一操作

可以将memcached上特定的键值作为计数器使用。

my $ret = $memcached>

incr('键');

$memcached>

add('键', 0) unless defined $ret;

增一和减一是原子操作,但未设置初始值时,不会自动赋成0。因此,应当进行错误检查,必要时

加入初始化操作。而且,服务器端也不会对超过232时的行为进行检查。

10

idv2.com 第1 章 memcached的基础

1.6 总结

这次简单介绍了memcached,以及它的安装方法、Perl客户端Cache::Memcached的用法。只要知道,

memcached的使用方法十分简单就足够了。

下一章由前坂来说明memcached的内部结构。了解memcached的内部构造,就能知道如何使用

memcached才能使Web应用的速度更上一层楼。欢迎继续阅读下一章。

11

idv2.com 第2章 理解memcached的内存存储

第2章 理解memcached的内存存储

我是 mixi 株式会社 研究开发组的前坂徹。上一章的文章介绍了memcached是分布式的高速缓存服

务器。本次将介绍memcached的内部构造的实现方式,以及内存的管理方式。另外,memcached的

内部构造导致的弱点也将加以说明。

2.1 Slab Allocation机制:整理内存以便重复使用

最近的memcached默认情况下采用了名为Slab Allocator的机制分配、管理内存。在该机制出现以

前,内存的分配是通过对所有记录简单地进行malloc和free来进行的。但是,这种方式会导致内存

碎片,加重操作系统内存管理器的负担,最坏的情况下,会导致操作系统比memcached进程本身还

慢。Slab Allocator就是为解决该问题而诞生的。

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

the primary goal of the slabs subsystem in memcached was to eliminate memory fragmentation issues

totally by using fixedsize

memory chunks coming from a few predetermined size classes.

也就是说,Slab Allocator的基本原理是按照预先规定的大小,将分配的内存分割成特定长度的块,

以完全解决内存碎片问题。

Slab Allocation的原理相当简单。将分配的内存分割成各种尺寸的块(chunk),并把尺寸相同的块

分成组(chunk的集合)(图2.1)。

图2.1:Slab Allocation的构造图

而且,slab allocator还有重复使用已分配的内存的目的。也就是说,分配到的内存不会释放,而是

12

idv2.com 第2章 理解memcached的内存存储

重复利用。

Slab Allocation的主要术语

Page

分配给Slab的内存空间,默认是1MB。分配给Slab之后根据slab的大小切分成chunk。

Chunk

用于缓存记录的内存空间。

Slab Class

特定大小的chunk的组。

2.2 在Slab中缓存记录的原理

下面说明memcached如何针对客户端发送的数据选择slab并缓存到chunk中。

memcached根据收到的数据的大小,选择最适合数据大小的slab(图2.2)。memcached中保存着

slab内空闲chunk的列表,根据该列表选择chunk,然后将数据缓存于其中。

图2.2:选择存储记录的组的方法

实际上,Slab Allocator也是有利也有弊。下面介绍一下它的缺点。

2.3 Slab Allocator的缺点

Slab Allocator解决了当初的内存碎片问题,但新的机制也给memcached带来了新的问题。

这个问题就是,由于分配的是特定长度的内存,因此无法有效利用分配的内存。例如,将100字节

的数据缓存到128字节的chunk中,剩余的28字节就浪费了(图2.3)。

13

idv2.com 第2章 理解memcached的内存存储

图2.3:chunk空间的使用

对于该问题目前还没有完美的解决方案,但在文档中记载了比较有效的解决方案。

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.

就是说,如果预先知道客户端发送的数据的公用大小,或者仅缓存大小相同的数据的情况下,只要

使用适合数据大小的组的列表,就可以减少浪费。

但是很遗憾,现在还不能进行任何调优,只能期待以后的版本了。但是,我们可以调节slab class

的大小的差别。接下来说明growth factor选项。

2.4 使用Growth Factor进行调优

memcached在启动时指定Growth Factor因子(通过f

选项),就可以在某种程度上控制slab之间的

差异。默认值为1.25。但是,在该选项出现之前,这个因子曾经固定为2,称为“powers of 2”策略。

让我们用以前的设置,以verbose模式启动memcached试试看:

$ memcached f

2 vv

下面是启动后的verbose输出:

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

可见,从128字节的组开始,组的大小依次增大为原来的2倍。 这样设置的问题是,slab之间的差

别比较大,有些情况下就相当浪费内存。 因此,为尽量减少内存浪费,两年前追加了growth factor

这个选项。

来看看现在的默认设置(f=1.25)时的输出(篇幅所限,这里只写到第10组):

slab class 1: chunk size 88 perslab 11915

14

idv2.com 第2章 理解memcached的内存存储

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

可见,组间差距比因子为2时小得多,更适合缓存几百字节的记录。从上面的输出结果来看,可能

会觉得有些计算误差,这些误差是为了保持字节数的对齐而故意设置的。

将memcached引入产品,或是直接使用默认值进行部署时,最好是重新计算一下数据的预期平均长

度,调整growth factor,以获得最恰当的设置。内存是珍贵的资源,浪费就太可惜了。

接下来介绍一下如何使用memcached的stats命令查看slabs的利用率等各种各样的信息。

2.5 查看memcached的内部状态

memcached有个名为stats的命令,使用它可以获得各种各样的信息。执行命令的方法很多,用

telnet最为简单:

$ telnet 主机名 端口号

连接到memcached之后,输入stats再按回车,即可获得包括资源利用率在内的各种信息。此外,

输入"stats slabs"或"stats items"还可以获得关于缓存记录的信息。结束程序请输入quit。

这些命令的详细信息可以参考memcached软件包内的protocol.txt文档。

$ 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

15

idv2.com 第2章 理解memcached的内存存储

quit

另外,如果安装了libmemcached这个面向C/C++语言的客户端库,就会安装memstat这个命令。使

用方法很简单,可以用更少的步骤获得与telnet相同的信息,还能一次性从多台服务器获得信息。

$ memstat servers=

server1,server2,server3,...

libmemcached可以从下面的地址获得:

• http://tangent.org/552/libmemcached.html

2.6 查看slabs的使用状况

使用memcached的创造着Brad写的名为memcachedtool

的Perl脚本,可以方便地获得slab的使用

情况(它将memcached的返回值整理成容易阅读的格式)。可以从下面的地址获得脚本:

• http://code.sixapart.com/svn/memcached/trunk/server/scripts/memcachedtool

使用方法也极其简单:

$ memcachedtool

主机名:端口 选项

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

$ memcachedtool

主机名:端口

获得的信息如下所示:

# 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

16

idv2.com 第2章 理解memcached的内存存储

各列的含义为:

列含义

# slab class编号

Item_Size Chunk大小

Max_age LRU内最旧的记录的生存时间

1MB_pages 分配给Slab的页数

Count Slab内的记录数

Full? Slab内是否含有空闲chunk

从这个脚本获得的信息对于调优非常方便,强烈推荐使用。

2.7 总结

本次简单说明了memcached的缓存机制和调优方法。希望读者能理解memcached的内存管理原理

及其优缺点。

下次将继续说明LRU和Expire等原理,以及memcached的最新发展方向——可扩充体系

(pluggable architecher))。

17

idv2.com 第3 章 memcached的删除机制和发展方向

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

memcached是缓存,所以数据不会永久保存在服务器上,这是向系统中引入memcached的前提。

本次介绍memcached的数据删除机制,以及memcached的最新发展方向——二进制协议(Binary

Protocol)和外部引擎支持。

3.1 memcached在数据删除方面有效利用资源

数据不会真正从memcached中消失

上一章介绍过,memcached不会释放已分配的内存。记录超时后,客户端就无法再看见该记录

(invisible,透明),其存储空间即可重复使用。

Lazy Expiration

memcached内部不会监视记录是否过期,而是在get时查看记录的时间戳,检查记录是否过期。这

种技术被称为lazy(惰性)expiration。因此,memcached不会在过期监视上耗费CPU时间。

3.2 LRU:从缓存中有效删除数据的原理

memcached会优先使用已超时的记录的空间,但即使如此,也会发生追加新记录时空间不足的情况,

此时就要使用名为Least Recently Used(LRU)机制来分配空间。顾名思义,这是删除“最近最少

使用”的记录的机制。因此,当memcached的内存空间不足时(无法从slab class 获取到新的空间

时),就从最近未被使用的记录中搜索,并将其空间分配给新的记录。从缓存的实用角度来看,该

模型十分理想。

不过,有些情况下LRU机制反倒会造成麻烦。memcached启动时通过“M”

参数可以禁止LRU,如

下所示:

$ memcached M

m

1024

启动时必须注意的是,小写的“m”

选项是用来指定最大内存大小的。不指定具体数值则使用默认

值64MB。

指定“M”

参数启动后,内存用尽时memcached会返回错误。话说回来,memcached毕竟不是存储

器,而是缓存,所以推荐使用LRU。

3.3 memcached的最新发展方向

memcached的roadmap上有两个大的目标。一个是二进制协议的策划和实现,另一个是外部引擎的

加载功能。

18

idv2.com 第3 章 memcached的删除机制和发展方向

关于二进制协议

使用二进制协议的理由是它不需要文本协议的解析处理,使得原本高速的memcached的性能更上一

层楼,还能减少文本协议的漏洞。目前已大部分实现,开发用的代码库中已包含了该功能。

memcached的下载页面上有代码库的链接。

• http://danga.com/memcached/download.bml

二进制协议的格式

协议的包为24字节的帧,其后面是键和无结构数据(Unstructured Data)。实际的格式如下(引自

协议文档):

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/ COMMANDSPECIFIC

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

如上所示,包格式十分简单。需要注意的是,占据了16字节的头部(HEADER)分为请求头

(Request Header)和响应头(Response Header)两种。头部中包含了表示包的有效性的Magic字

节、命令种类、键长度、值长度等信息,格式如下:

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 |

19

idv2.com 第3 章 memcached的删除机制和发展方向

++

+

+

+

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 |

| |

++

+

+

+

如希望了解各个部分的详细内容,可以checkout出memcached的二进制协议的代码树,参考其中的

docs文件夹中的protocol_binary.txt文档。

HEADER中引人注目的地方

看到HEADER格式后我的感想是,键的上限太大了!现在的memcached规格中,键长度最大为

250字节,但二进制协议中键的大小用2字节表示。因此,理论上最大可使用65536字节(216)长

的键。尽管250字节以上的键并不会太常用,二进制协议发布之后就可以使用巨大的键了。

二进制协议从下一版本1.3系列开始支持。

3.4 外部引擎支持

我去年曾经试验性地将memcached的存储层改造成了可扩展的(pluggable)。

• http://alpha.mixi.co.jp/blog/?p=129

MySQL的Brian Aker看到这个改造之后,就将代码发到了memcached的邮件列表。memcached的

开发者也十分感兴趣,就放到了roadmap中。现在由我和memcached的开发者Trond Norbye协同开

发(规格设计、实现和测试)。和国外协同开发时时差是个大问题,但抱着相同的愿景,最后终于

可以将可扩展架构的原型公布了。代码库可以从 memcached 的下载页面 上访问。

外部引擎支持的必要性

世界上有许多memcached的派生软件,其理由是希望永久保存数据、实现数据冗余等,即使牺牲一

些性能也在所不惜。我在开发memcached之前,在mixi的研发部也曾经考虑过重新发明

memcached。

20

idv2.com 第3 章 memcached的删除机制和发展方向

外部引擎的加载机制能封装memcached的网络功能、事件处理等复杂的处理。因此,现阶段通过强

制手段或重新设计等方式使memcached和存储引擎合作的困难就会烟消云散,尝试各种引擎就会变

得轻而易举了。

简单API设计的成功的关键

该项目中我们最重视的是API设计。函数过多,会使引擎开发者感到麻烦;过于复杂,实现引擎的

门槛就会过高。因此,最初版本的接口函数只有13个。具体内容限于篇幅,这里就省略了,仅说

明一下引擎应当完成的操作:

• 引擎信息(版本等)

• 引擎初始化

• 引擎关闭

• 引擎的统计信息

• 在容量方面,测试给定记录能否保存

• 为item(记录)结构分配内存

• 释放item(记录)的内存

• 删除记录

• 保存记录

• 回收记录

• 更新记录的时间戳

• 数学运算处理

• 数据的flush

对详细规格有兴趣的读者,可以checkout engine项目的代码,阅读器中的engine.h。

重新审视现在的体系

memcached支持外部存储的难点是,网络和事件处理相关的代码(核心服务器)与内存存储的代码

紧密关联。这种现象也称为tightly coupled(紧密耦合)。必须将内存存储的代码从核心服务器中

独立出来,才能灵活地支持外部引擎。因此,基于我们设计的API,memcached被重构成下面的样

子:

21

idv2.com 第3 章 memcached的删除机制和发展方向

图3.1:新的memcached架构

重构之后,我们与1.2.5版、二进制协议支持版等进行了性能对比,证实了它不会造成性能影响。

在考虑如何支持外部引擎加载时,让memcached进行并行控制(concurrency control)的方案是最

为容易的,但是对于引擎而言,并行控制正是性能的真谛,因此我们采用了将多线程支持完全交给

引擎的设计方案。

以后的改进,会使得memcached的应用范围更为广泛。

3.5 总结

本次介绍了memcached的超时原理、内部如何删除数据等,在此之上又介绍了二进制协议和外部引

擎支持等memcached的最新发展方向。这些功能要到1.3版才会支持,敬请期待!

这是我在本文中的最后一篇。感谢大家阅读我的文章!

下一章由长野来介绍memcached的应用知识和应用程序兼容性等内容。

22

idv2.com 第4 章 memcached的分布式算法

第4章 memcached的分布式算法

我是Mixi的长野。第 2 章 、第 3 章 由前坂介绍了memcached的内部情况。本次不再介绍

memcached的内部结构,开始介绍memcached的分布式。

4.1 memcached的分布式

正如第 1 章 中介绍的那样,memcached虽然称为“分布式”缓存服务器,但服务器端并没有“分布

式”功能。服务器端仅包括第 2 章 、第 3 章 前坂介绍的内存存储功能,其实现非常简单。至于

memcached的分布式,则是完全由客户端程序库实现的。这种分布式是memcached的最大特点。

memcached的分布式是什么意思?

这里多次使用了“分布式”这个词,但并未做详细解释。现在开始简单地介绍一下其原理,各个客

户端的实现基本相同。

下面假设memcached服务器有node1~node3三台,应用程序要保存键名为

“tokyo”、“kanagawa”、“chiba”、“saitama”、“gunma”的数据。

图4.1:分布式简介:准备

23

idv2.com 第4 章 memcached的分布式算法

首先向memcached中添加“tokyo”。将“tokyo”传给客户端程序库后,客户端实现的算法就会根据

“键”来决定保存数据的memcached服务器。服务器选定后,即命令它保存“tokyo”及其值。

图4.2:分布式简介:添加时

同样,“kanagawa”、“chiba”、“saitama”、“gunma”都是先选择服务器再保存。

接下来获取保存的数据。获取时也要将要获取的键“tokyo”传递给函数库。函数库通过与数据保存

时相同的算法,根据“键”选择服务器。使用的算法相同,就能选中与保存时相同的服务器,然后

发送get命令。只要数据没有因为某些原因被删除,就能获得保存的值。

24

idv2.com 第4 章 memcached的分布式算法

图4.3:分布式简介:获取时

这样,将不同的键保存到不同的服务器上,就实现了memcached的分布式。memcached服务器增多

后,键就会分散,即使一台memcached服务器发生故障无法连接,也不会影响其他的缓存,系统依

然能继续运行。

接下来介绍第 1 章 中提到的Perl客户端函数库Cache::Memcached实现的分布式方法。

4.2 Cache::Memcached的分布式方法

Perl的memcached客户端函数库Cache::Memcached是memcached的作者Brad Fitzpatrick的作品,

可以说是原装的函数库了。

• Cache::Memcached search.

cpan.org

该函数库实现了分布式功能,是memcached标准的分布式方法。

根据余数计算分散

Cache::Memcached的分布式方法简单来说,就是“根据服务器台数的余数进行分散”。求得键的整

数哈希值,再除以服务器台数,根据其余数来选择服务器。

下面将Cache::Memcached简化成以下的Perl脚本来进行说明。

use strict;

use warnings;

use String::CRC32;

25

idv2.com 第4 章 memcached的分布式算法

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

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

foreach my $key (@keys) {

my $crc = crc32($key); # CRC値

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

my $server = $nodes[ $mod ]; # 根据余数选择服务器

printf "%s => %s\n", $key, $server;

}

Cache::Memcached在求哈希值时使用了CRC。

• String::CRC32 search.

cpan.org

首先求得字符串的CRC值,根据该值除以服务器节点数目得到的余数决定服务器。上面的代码执

行后输入以下结果:

tokyo => node2

kanagawa => node3

chiba => node2

saitama => node1

gunma => node1

根据该结果,“tokyo”分散到node2,“kanagawa”分散到node3等。多说一句,当选择的服务器无

法连接时,Cache::Memcached会将连接次数添加到键之后,再次计算哈希值并尝试连接。这个动作

称为rehash。不希望rehash时可以在生成Cache::Memcached对象时指定“rehash => 0”选项。

根据余数计算分散的缺点

余数计算的方法简单,数据的分散性也相当优秀,但也有其缺点。那就是当添加或移除服务器时,

缓存重组的代价相当巨大。添加服务器后,余数就会产生巨变,这样就无法获取与保存时相同的服

务器,从而影响缓存的命中率。用Perl写段代码来验证其代价。

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} };

}

这段Perl脚本演示了将“a”到“z”的键保存到memcached并访问的情况。将其保存为mod.pl并执行。

首先,当服务器只有三台时:

26

idv2.com 第4 章 memcached的分布式算法

$ 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

结果如上,node1保存a、c、d、e……,node2保存g、i、k……,每台服务器都保存了8个到10个

数据。

接下来增加一台memcached服务器。

$ 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

添加了node4。可见,只有d、i、k、p、r、y命中了。像这样,添加节点后键分散到的服务器会发

生巨大变化。26个键中只有六个在访问原来的服务器,其他的全都移到了其他服务器。命中率降

低到23%。在Web应用程序中使用memcached时,在添加memcached服务器的瞬间缓存效率会大

幅度下降,负载会集中到数据库服务器上,有可能会发生无法提供正常服务的情况。

mixi的Web应用程序运用中也有这个问题,导致无法添加memcached服务器。但由于使用了新的

分布式方法,现在可以轻而易举地添加memcached服务器了。这种分布式方法称为Consistent

Hashing。

4.3 Consistent Hashing

关于Consistent Hashing的思想,mixi株式会社的开发blog等许多地方都介绍过,这里只简单地说

明一下。

• mixi Engineers' Blog ス

マートな分散で快適キャッシュライフ

• ConsistentHashing コ

ンシステント ハッシュ法

Consistent Hashing的简单说明

Consistent Hashing如下所示:首先求出memcached服务器(节点)的哈希值,并将其配置到0~232

的圆(continuum)上。然后用同样的方法求出存储数据的键的哈希值,并映射到圆上。然后从数

据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器上。如果超过232仍然找不到

服务器,就会保存到第一台memcached服务器上。

27

idv2.com 第4 章 memcached的分布式算法

图4.4:Consistent Hashing:基本原理

从上图的状态中添加一台memcached服务器。余数分布式算法由于保存键的服务器会发生巨大变化

而影响缓存的命中率,但Consistent Hashing中,只有在continuum上增加服务器的地点逆时针方向

的第一台服务器上的键会受到影响。

图4.5:Consistent Hashing:添加服务器

28

idv2.com 第4 章 memcached的分布式算法

因此,Consistent Hashing最大限度地抑制了键的重新分布。而且,有的Consistent Hashing的实现方

法还采用了虚拟节点的思想。使用一般的hash函数的话,服务器的映射地点的分布非常不均匀。

因此,使用虚拟节点的思想,为每个物理节点(服务器)在continuum上分配100~200个点。这样

就能抑制分布不均匀,最大限度地减小服务器增减时的缓存重新分布。

通过下文中介绍的使用Consistent Hashing算法的memcached客户端函数库进行测试的结果是,由

服务器台数(n)和增加的服务器台数(m)计算增加服务器后的命中率计算公式如下:

(1 n/(

n+m)) * 100

支持Consistent Hashing的函数库

本文中多次介绍的Cache::Memcached虽然不支持Consistent Hashing,但已有几个客户端函数库支

持了这种新的分布式算法。第一个支持Consistent Hashing和虚拟节点的memcached客户端函数库

是名为libketama的PHP库,由last.fm开发。

• libketama a

consistent hashing algo for memcache clients – RJ ブログ Users

at Last.fm

至于Perl客户端,第 1 章 中介绍过的Cache::Memcached::Fast和Cache::Memcached::libmemcached支

持Consistent Hashing。

• Cache::Memcached::Fast search.

cpan.org

• Cache::Memcached::libmemcached search.

cpan.org

两者的接口都与Cache::Memcached几乎相同,如果正在使用Cache::Memcached,那么就可以方便

地替换过来。Cache::Memcached::Fast重新实现了libketama,使用Consistent Hashing创建对象时可

以指定ketama_points选项。

my $memcached = Cache::Memcached::Fast>

new({

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

ketama_points => 150

});

另外,Cache::Memcached::libmemcached是一个使用了Brain Aker开发的C函数库libmemcached的

Perl模块。libmemcached本身支持几种分布式算法,也支持Consistent Hashing,其Perl绑定也支持

Consistent Hashing。

• Tangent Software: libmemcached

4.4 总结

本次介绍了memcached的分布式算法,主要有memcached的分布式是由客户端函数库实现,以及

高效率地分散数据的Consistent Hashing算法。下次将介绍mixi在memcached应用方面的一些经验,

和相关的兼容应用程序。

29

idv2.com 第5 章 memcached的应用和兼容程序

第5章 memcached的应用和兼容程序

我是Mixi的长野。本文终于要结束了。到第 4 章 为止,我们介绍了与memcached直接相关的话题,

本次介绍一些mixi的案例和实际应用上的话题,并介绍一些与memcached兼容的程序。

5.1 mixi案例研究

mixi在提供服务的初期阶段就使用了memcached。随着网站访问量的急剧增加,单纯为数据库添加

slave已无法满足需要,因此引入了memcached。此外,我们也从增加可扩展性的方面进行了验证,

证明了memcached的速度和稳定性都能满足需要。现在,memcached已成为mixi服务中非常重要

的组成部分。

图5.1:现在的系统组件

服务器配置和数量

mixi使用了许许多多服务器,如数据库服务器、应用服务器、图片服务器、反向代理服务器等。单

单memcached就有将近200台服务器在运行。memcached服务器的典型配置如下:

• CPU:Intel Pentium 4 2.8GHz

30

idv2.com 第5 章 memcached的应用和兼容程序

• 内存: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对象

保持在类变量中,以保证持久连接。

31

idv2.com 第5 章 memcached的应用和兼容程序

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无法连接,就会产生巨大的问题。

#5. 第 4 章 memcached 的分布式算法 |outline 中提到,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

服务器故障不再产生其他影响。

5.2 memcached应用经验

到此为止介绍了memcached内部构造和函数库,接下来介绍一些其他的应用经验。

32

idv2.com 第5 章 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

fi

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服务器。

33

idv2.com 第5 章 memcached的应用和兼容程序

图5.2:请求数

图5.3:流量

图5.4:TCP连接数

从上至下依次为请求数、流量和TCP连接数。请求数最大为15000qps,流量达到400Mbps,这时

的连接数已超过了10000个。该服务器没有特别的硬件,就是开头介绍的普通的memcached服务器。

此时的CPU利用率为:

34

idv2.com 第5 章 memcached的应用和兼容程序

图5.5:CPU利用率

可见,仍然有idle的部分。因此,memcached的性能非常高,可以作为Web应用程序开发者放心地

保存临时数据或缓存数据的地方。

5.3 兼容应用程序

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即可,这也是优点之一。关于Tokyo Tyrant

分享到:
评论

相关推荐

    memcached全面剖析.pdf

    ### Memcached全面剖析 #### memcached概述与基本概念 **memcached**是一种高性能的分布式内存对象缓存系统,主要用于缓解数据库负载,加快动态Web应用的速度并提升其可扩展性。其核心理念在于通过缓存数据库查询...

    memcached全面剖析.zip

    memcached全面剖析–2. 理解memcached的内存存储 memcached全面剖析–3. memcached的删除机制和发展方向 memcached全面剖析–4. memcached的分布式算法 memcached全面剖析–5. memcached的应用和兼容程序 可关注...

    MemCached 全面剖析 memcached.pdf(中文)

    ### MemCached 全面剖析 #### 一、MemCached 基础介绍 **1.1 MemCached 是什么?** MemCached 是一个高性能、分布式内存对象缓存系统,旨在减轻数据库负担,加速动态Web应用的速度。它通过在内存中缓存数据和对象...

    基于模糊故障树的工业控制系统可靠性分析与Python实现

    内容概要:本文探讨了模糊故障树(FFTA)在工业控制系统可靠性分析中的应用,解决了传统故障树方法无法处理不确定数据的问题。文中介绍了模糊数的基本概念和实现方式,如三角模糊数和梯形模糊数,并展示了如何用Python实现模糊与门、或门运算以及系统故障率的计算。此外,还详细讲解了最小割集的查找方法、单元重要度的计算,并通过实例说明了这些方法的实际应用场景。最后,讨论了模糊运算在处理语言变量方面的优势,强调了在可靠性分析中处理模糊性和优化计算效率的重要性。 适合人群:从事工业控制系统设计、维护的技术人员,以及对模糊数学和可靠性分析感兴趣的科研人员。 使用场景及目标:适用于需要评估复杂系统可靠性的场合,特别是在面对不确定数据时,能够提供更准确的风险评估。目标是帮助工程师更好地理解和预测系统故障,从而制定有效的预防措施。 其他说明:文中提供的代码片段和方法可用于初步方案验证和技术探索,但在实际工程项目中还需进一步优化和完善。

    风力发电领域双馈风力发电机(DFIG)Simulink模型的构建与电流电压波形分析

    内容概要:本文详细探讨了双馈风力发电机(DFIG)在Simulink环境下的建模方法及其在不同风速条件下的电流与电压波形特征。首先介绍了DFIG的基本原理,即定子直接接入电网,转子通过双向变流器连接电网的特点。接着阐述了Simulink模型的具体搭建步骤,包括风力机模型、传动系统模型、DFIG本体模型和变流器模型的建立。文中强调了变流器控制算法的重要性,特别是在应对风速变化时,通过实时调整转子侧的电压和电流,确保电流和电压波形的良好特性。此外,文章还讨论了模型中的关键技术和挑战,如转子电流环控制策略、低电压穿越性能、直流母线电压脉动等问题,并提供了具体的解决方案和技术细节。最终,通过对故障工况的仿真测试,验证了所建模型的有效性和优越性。 适用人群:从事风力发电研究的技术人员、高校相关专业师生、对电力电子控制系统感兴趣的工程技术人员。 使用场景及目标:适用于希望深入了解DFIG工作原理、掌握Simulink建模技能的研究人员;旨在帮助读者理解DFIG在不同风速条件下的动态响应机制,为优化风力发电系统的控制策略提供理论依据和技术支持。 其他说明:文章不仅提供了详细的理论解释,还附有大量Matlab/Simulink代码片段,便于读者进行实践操作。同时,针对一些常见问题给出了实用的调试技巧,有助于提高仿真的准确性和可靠性。

    基于西门子S7-200 PLC和组态王的八层电梯控制系统设计与实现

    内容概要:本文详细介绍了基于西门子S7-200 PLC和组态王软件构建的八层电梯控制系统。首先阐述了系统的硬件配置,包括PLC的IO分配策略,如输入输出信号的具体分配及其重要性。接着深入探讨了梯形图编程逻辑,涵盖外呼信号处理、轿厢运动控制以及楼层判断等关键环节。随后讲解了组态王的画面设计,包括动画效果的实现方法,如楼层按钮绑定、轿厢移动动画和门开合效果等。最后分享了一些调试经验和注意事项,如模拟困人场景、防抖逻辑、接线艺术等。 适合人群:从事自动化控制领域的工程师和技术人员,尤其是对PLC编程和组态软件有一定基础的人群。 使用场景及目标:适用于需要设计和实施小型电梯控制系统的工程项目。主要目标是帮助读者掌握PLC编程技巧、组态画面设计方法以及系统联调经验,从而提高项目的成功率。 其他说明:文中提供了详细的代码片段和调试技巧,有助于读者更好地理解和应用相关知识点。此外,还强调了安全性和可靠性方面的考量,如急停按钮的正确接入和硬件互锁设计等。

    CarSim与Simulink联合仿真:基于MPC模型预测控制实现智能超车换道

    内容概要:本文介绍了如何将CarSim的动力学模型与Simulink的智能算法相结合,利用模型预测控制(MPC)实现车辆的智能超车换道。主要内容包括MPC控制器的设计、路径规划算法、联合仿真的配置要点以及实际应用效果。文中提供了详细的代码片段和技术细节,如权重矩阵设置、路径跟踪目标函数、安全超车条件判断等。此外,还强调了仿真过程中需要注意的关键参数配置,如仿真步长、插值设置等,以确保系统的稳定性和准确性。 适合人群:从事自动驾驶研究的技术人员、汽车工程领域的研究人员、对联合仿真感兴趣的开发者。 使用场景及目标:适用于需要进行自动驾驶车辆行为模拟的研究机构和企业,旨在提高超车换道的安全性和效率,为自动驾驶技术研发提供理论支持和技术验证。 其他说明:随包提供的案例文件已调好所有参数,可以直接导入并运行,帮助用户快速上手。文中提到的具体参数和配置方法对于初学者非常友好,能够显著降低入门门槛。

    基于单片机的鱼缸监测设计(51+1602+AD0809+18B20+UART+JKx2)#0107

    包括:源程序工程文件、Proteus仿真工程文件、论文材料、配套技术手册等 1、采用51单片机作为主控; 2、采用AD0809(仿真0808)检测"PH、氨、亚硝酸盐、硝酸盐"模拟传感; 3、采用DS18B20检测温度; 4、采用1602液晶显示检测值; 5、检测值同时串口上传,调试助手监看; 6、亦可通过串口指令对加热器、制氧机进行控制;

    风电领域双馈永磁风电机组并网仿真及短路故障分析与MPPT控制

    内容概要:本文详细介绍了双馈永磁风电机组并网仿真模型及其短路故障分析方法。首先构建了一个9MW风电场模型,由6台1.5MW双馈风机构成,通过升压变压器连接到120kV电网。文中探讨了风速模块的设计,包括渐变风、阵风和随疾风的组合形式,并提供了相应的Python和MATLAB代码示例。接着讨论了双闭环控制策略,即功率外环和电流内环的具体实现细节,以及MPPT控制用于最大化风能捕获的方法。此外,还涉及了短路故障模块的建模,包括三相电压电流特性和离散模型与phasor模型的应用。最后,强调了永磁同步机并网模型的特点和注意事项。 适合人群:从事风电领域研究的技术人员、高校相关专业师生、对风电并网仿真感兴趣的工程技术人员。 使用场景及目标:适用于风电场并网仿真研究,帮助研究人员理解和优化风电机组在不同风速条件下的性能表现,特别是在短路故障情况下的应对措施。目标是提高风电系统的稳定性和可靠性。 其他说明:文中提供的代码片段和具体参数设置有助于读者快速上手并进行实验验证。同时提醒了一些常见的错误和需要注意的地方,如离散化步长的选择、初始位置对齐等。

    空手道训练测试系统BLE106版本

    适用于空手道训练和测试场景

    【音乐创作领域AI提示词】AI音乐提示词(deepseek,豆包,kimi,chatGPT,扣子空间,manus,AI训练师)

    内容概要:本文介绍了金牌音乐作词大师的角色设定、背景经历、偏好特点、创作目标、技能优势以及工作流程。金牌音乐作词大师凭借深厚的音乐文化底蕴和丰富的创作经验,能够为不同风格的音乐创作歌词,擅长将传统文化元素与现代流行文化相结合,创作出既富有情感又触动人心的歌词。在创作过程中,会严格遵守社会主义核心价值观,尊重用户需求,提供专业修改建议,确保歌词内容健康向上。; 适合人群:有歌词创作需求的音乐爱好者、歌手或音乐制作人。; 使用场景及目标:①为特定主题或情感创作歌词,如爱情、励志等;②融合传统与现代文化元素创作独特风格的歌词;③对已有歌词进行润色和优化。; 阅读建议:阅读时可以重点关注作词大师的创作偏好、技能优势以及工作流程,有助于更好地理解如何创作出高质量的歌词。同时,在提出创作需求时,尽量详细描述自己的情感背景和期望,以便获得更贴合心意的作品。

    linux之用户管理教程.md

    linux之用户管理教程.md

    基于单片机的搬运机器人设计(51+1602+L298+BZ+KEY6)#0096

    包括:源程序工程文件、Proteus仿真工程文件、配套技术手册等 1、采用51/52单片机作为主控芯片; 2、采用1602液晶显示设置及状态; 3、采用L298驱动两个电机,模拟机械臂动力、移动底盘动力; 3、首先按键配置-待搬运物块的高度和宽度(为0不能开始搬运); 4、按下启动键开始搬运,搬运流程如下: 机械臂先把物块抓取到机器车上, 机械臂减速 机器车带着物块前往目的地 机器车减速 机械臂把物块放下来 机械臂减速 机器车回到物块堆积处(此时机器车是空车) 机器车减速 蜂鸣器提醒 按下复位键,结束本次搬运

    基于下垂控制的三相逆变器电压电流双闭环仿真及MATLAB/Simulink/PLECS实现

    内容概要:本文详细介绍了基于下垂控制的三相逆变器电压电流双闭环控制的仿真方法及其在MATLAB/Simulink和PLECS中的具体实现。首先解释了下垂控制的基本原理,即有功调频和无功调压,并给出了相应的数学表达式。随后讨论了电压环和电流环的设计与参数整定,强调了两者带宽的差异以及PI控制器的参数选择。文中还提到了一些常见的调试技巧,如锁相环的响应速度、LC滤波器的谐振点处理、死区时间设置等。此外,作者分享了一些实用的经验,如避免过度滤波、合理设置采样周期和下垂系数等。最后,通过突加负载测试展示了系统的动态响应性能。 适合人群:从事电力电子、微电网研究的技术人员,尤其是有一定MATLAB/Simulink和PLECS使用经验的研发人员。 使用场景及目标:适用于希望深入了解三相逆变器下垂控制机制的研究人员和技术人员,旨在帮助他们掌握电压电流双闭环控制的具体实现方法,提高仿真的准确性和效率。 其他说明:本文不仅提供了详细的理论讲解,还结合了大量的实战经验和调试技巧,有助于读者更好地理解和应用相关技术。

    光伏并网逆变器全栈开发资料:硬件设计、控制算法及实战经验

    内容概要:本文详细介绍了光伏并网逆变器的全栈开发资料,涵盖了从硬件设计到控制算法的各个方面。首先,文章深入探讨了功率接口板的设计,包括IGBT缓冲电路、PCB布局以及EMI滤波器的具体参数和设计思路。接着,重点讲解了主控DSP板的核心控制算法,如MPPT算法的实现及其注意事项。此外,还详细描述了驱动扩展板的门极驱动电路设计,特别是光耦隔离和驱动电阻的选择。同时,文章提供了并联仿真的具体实现方法,展示了环流抑制策略的效果。最后,分享了许多宝贵的实战经验和调试技巧,如主变压器绕制、PWM输出滤波、电流探头使用等。 适合人群:从事电力电子、光伏系统设计的研发工程师和技术爱好者。 使用场景及目标:①帮助工程师理解和掌握光伏并网逆变器的硬件设计和控制算法;②提供详细的实战经验和调试技巧,提升产品的可靠性和性能;③适用于希望深入了解光伏并网逆变器全栈开发的技术人员。 其他说明:文中不仅提供了具体的电路设计和代码实现,还分享了许多宝贵的实际操作经验和常见问题的解决方案,有助于提高开发效率和产品质量。

    机器人轨迹规划中粒子群优化与3-5-3多项式结合的时间最优路径规划

    内容概要:本文详细介绍了粒子群优化(PSO)算法与3-5-3多项式相结合的方法,在机器人轨迹规划中的应用。首先解释了粒子群算法的基本原理及其在优化轨迹参数方面的作用,随后阐述了3-5-3多项式的数学模型,特别是如何利用不同阶次的多项式确保轨迹的平滑过渡并满足边界条件。文中还提供了具体的Python代码实现,展示了如何通过粒子群算法优化时间分配,使3-5-3多项式生成的轨迹达到时间最优。此外,作者分享了一些实践经验,如加入惩罚项以避免超速,以及使用随机扰动帮助粒子跳出局部最优。 适合人群:对机器人运动规划感兴趣的科研人员、工程师和技术爱好者,尤其是有一定编程基础并对优化算法有初步了解的人士。 使用场景及目标:适用于需要精确控制机器人运动的应用场合,如工业自动化生产线、无人机导航等。主要目标是在保证轨迹平滑的前提下,尽可能缩短运动时间,提高工作效率。 其他说明:文中不仅给出了理论讲解,还有详细的代码示例和调试技巧,便于读者理解和实践。同时强调了实际应用中需要注意的问题,如系统的建模精度和安全性考量。

    【KUKA 机器人资料】:kuka机器人压铸欧洲标准.pdf

    KUKA机器人相关资料

    光子晶体中BIC与OAM激发的模拟及三维Q值计算

    内容概要:本文详细探讨了光子晶体中的束缚态在连续谱中(BIC)及其与轨道角动量(OAM)激发的关系。首先介绍了光子晶体的基本概念和BIC的独特性质,随后展示了如何通过Python代码模拟二维光子晶体中的BIC,并解释了BIC在光学器件中的潜在应用。接着讨论了OAM激发与BIC之间的联系,特别是BIC如何增强OAM激发效率。文中还提供了使用有限差分时域(FDTD)方法计算OAM的具体步骤,并介绍了计算本征态和三维Q值的方法。此外,作者分享了一些实验中的有趣发现,如特定条件下BIC表现出OAM特征,以及不同参数设置对Q值的影响。 适合人群:对光子晶体、BIC和OAM感兴趣的科研人员和技术爱好者,尤其是从事微纳光子学研究的专业人士。 使用场景及目标:适用于希望通过代码模拟深入了解光子晶体中BIC和OAM激发机制的研究人员。目标是掌握BIC和OAM的基础理论,学会使用Python和其他工具进行模拟,并理解这些现象在实际应用中的潜力。 其他说明:文章不仅提供了详细的代码示例,还分享了许多实验心得和技巧,帮助读者避免常见错误,提高模拟精度。同时,强调了物理离散化方式对数值计算结果的重要影响。

    C#联合Halcon 17.12构建工业视觉项目的配置与应用

    内容概要:本文详细介绍了如何使用C#和Halcon 17.12构建一个功能全面的工业视觉项目。主要内容涵盖项目配置、Halcon脚本的选择与修改、相机调试、模板匹配、生产履历管理、历史图像保存以及与三菱FX5U PLC的以太网通讯。文中不仅提供了具体的代码示例,还讨论了实际项目中常见的挑战及其解决方案,如环境配置、相机控制、模板匹配参数调整、PLC通讯细节、生产数据管理和图像存储策略等。 适合人群:从事工业视觉领域的开发者和技术人员,尤其是那些希望深入了解C#与Halcon结合使用的专业人士。 使用场景及目标:适用于需要开发复杂视觉检测系统的工业应用场景,旨在提高检测精度、自动化程度和数据管理效率。具体目标包括但不限于:实现高效的视觉处理流程、确保相机与PLC的无缝协作、优化模板匹配算法、有效管理生产和检测数据。 其他说明:文中强调了框架整合的重要性,并提供了一些实用的技术提示,如避免不同版本之间的兼容性问题、处理实时图像流的最佳实践、确保线程安全的操作等。此外,还提到了一些常见错误及其规避方法,帮助开发者少走弯路。

Global site tag (gtag.js) - Google Analytics