`
ema856rj
  • 浏览: 12985 次
社区版块
存档分类
最新评论

memcached完全剖析

 
阅读更多

memcached完全剖析
2011年05月14日
  memcached完全剖析 
  2008-07-28 13:42:15 业界 | 评论(9) | 浏览(3205) 作者:长野雅广(Masahiro Nagano) 原文链接:http://gihyo.jp/dev/feature/01/memcached/0001 我是mixi株式会社开发部系统运营组的长野。日常负责程序的运营。从今天开始,将分几次针对最近在Web应用的可扩展性领域的热门话题memcached,与我公司开发部研究开发组的前坂一起,说明其内部结构和使用。 ??memcached是什么? ??memcached的特征 ??协议简单 ??基于libevent的事件处理 ??内置内存存储方式 ??memcached不互相通信的分布式 ??安装memcached ??memcached的安装 ??memcached的启动 ??用客户端连接 ??使用Cache::Memcached ??使用Cache::Memcached连接memcached ??保存数据 ??获取数据 ??删除数据 ??增一和减一操作 ??总结 memcached是什么?memcached是以LiveJournal旗下Danga Interactive公司的Brad Fitzpatric为首开发的一款软件。现在已成为mixi、hatena、Facebook、Vox、LiveJournal等众多服务中提高Web应用扩展性的重要因素。许多Web应用都将数据保存到RDBMS中,应用服务器从中读取数据并在浏览器中显示。但随着数据量的增大、访问的集中,就会出现RDBMS的负担加重、数据库响应恶化、网站显示延迟等重大影响。这时就该memcached大显身手了。memcached是高性能的分布式内存缓存服务器。一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展性。 图1 一般情况下memcached的用途 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本身是为缓存而设计的服务器,因此并没有过多考虑数据的永久性问题。关于内存存储的详细信息,本连载的第二讲以后前坂会进行介绍,请届时参考。 memcached不互相通信的分布式memcached尽管是"分布式"缓存服务器,但服务器端并没有分布式功能。各个memcached不会互相通信以共享信息。那么,怎样进行分布式呢?这完全取决于客户端的实现。本连载也将介绍memcached的分布式。 图2 memcached的分布式接下来简单介绍一下memcached的使用方法。安装memcachedmemcached的安装比较简单,这里稍加说明。 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 libevent-develmemcached的源代码可以从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/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下。 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 内存使用量为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的各种行为,推荐读一读。用客户端连接许多语言都实现了连接memcached的客户端,其中以Perl、PHP为主。仅仅memcached网站上列出的语言就有 ??Perl ??PHP ??Python ??Ruby ??C# ??C/C++ ??Lua 等等。 ??memcached客户端API:http://www.danga.com/memcached/apis.bml 这里介绍通过mixi正在使用的Perl库链接memcached的方法。使用Cache::MemcachedPerl的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/Cache-Memcached/ 使用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中。保存数据向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时的行为进行检查。总结这次简单介绍了memcached,以及它的安装方法、Perl客户端Cache::Memcached的用法。只要知道,memcached的使用方法十分简单就足够了。下次由前坂来说明memcached的内部结构。了解memcached的内部构造,就能知道如何使用memcached才能使Web应用的速度更上一层楼。 下面是《memcached全面剖析》的第二部分。发表日:2008/7/9 作者:前坂彻(Toru Maesaka) 原文链接:http://gihyo.jp/dev/feature/01/memcached/0002 ??Slab Allocation机制:整理内存以便重复使用 ??Slab Allocation的主要术语 ??在Slab中缓存记录的原理 ??Slab Allocator的缺点 ??使用Growth Factor进行调优 ??查看memcached的内部状态 ??查看slabs的使用状况 ??内存存储的总结 我是mixi株式会社研究开发组的前坂彻。上次的文章介绍了memcached是分布式的高速缓存服务器。本次将介绍memcached的内部构造的实现方式,以及内存的管理方式。另外,memcached的内部构造导致的弱点也将加以说明。 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 toeliminate memory fragmentation issues totally by using fixed-sizememory chunks coming from a few predetermined size classes. 也就是说,Slab Allocator的基本原理是按照预先规定的大小,将分配的内存分割成特定长度的块,以完全解决内存碎片问题。 Slab Allocation的原理相当简单。 将分配的内存分割成各种尺寸的块(chunk),并把尺寸相同的块分成组(chunk的集合)(图1)。 图1 Slab Allocation的构造图而且,slab allocator还有重复使用已分配的内存的目的。也就是说,分配到的内存不会释放,而是重复利用。 Slab Allocation的主要术语Page 分配给Slab的内存空间,默认是1MB。分配给Slab之后根据slab的大小切分成chunk。 Chunk 用于缓存记录的内存空间。 Slab Class 特定大小的chunk的组。在Slab中缓存记录的原理下面说明memcached如何针对客户端发送的数据选择slab并缓存到chunk中。 memcached根据收到的数据的大小,选择最适合数据大小的slab(图2)。memcached中保存着slab内空闲chunk的列表,根据该列表选择chunk,然后将数据缓存于其中。 图2 选择存储记录的组的方法实际上,Slab Allocator也是有利也有弊。下面介绍一下它的缺点。 Slab Allocator的缺点Slab Allocator解决了当初的内存碎片问题,但新的机制也给memcached带来了新的问题。这个问题就是,由于分配的是特定长度的内存,因此无法有效利用分配的内存。例如,将100字节的数据缓存到128字节的chunk中,剩余的28字节就浪费了(图3)。 图3 chunk空间的使用对于该问题目前还没有完美的解决方案,但在文档中记载了比较有效的解决方案。 The most efficient way to reduce the waste is to use a list of sizeclasses that closely matches (if that's at all possible) common sizesof objects that the clients of this particular installation ofmemcached are likely to store. 就是说,如果预先知道客户端发送的数据的公用大小,或者仅缓存大小相同的数据的情况下,只要使用适合数据大小的组的列表,就可以减少浪费。但是很遗憾,现在还不能进行任何调优,只能期待以后的版本了。但是,我们可以调节slab class的大小的差别。接下来说明growth factor选项。使用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 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的利用率等各种各样的信息。查看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 quit另外,如果安装了libmemcached这个面向C/C++语言的客户端库,就会安装 memstat 这个恶命令。使用方法很简单,可以用更少的步骤获得与telnet相同的信息,还能一次性从多台服务器获得信息。 $ memstat --servers=server1,server2,server3,...libmemcached可以从下面的地址获得: ??http://tangent.org/552/libmemcached.html 查看slabs的使用状况使用memcached的创造着Brad写的名为memcached-tool的Perl脚本,可以方便地获得slab的使用情况(它将memcached的返回值整理成容易阅读的格式)。可以从下面的地址获得脚本: ??http://code.sixapart.com/svn/memcached/trunk /server/scripts/memcached-tool 使用方法也极其简单: $ memcached-tool 主机名:端口 选项查看slabs使用状况时无需指定选项,因此用下面的命令即可: $ memcached-tool 主机名:端口获得的信息如下所示: # 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各列的含义为:列 含义 # slab class编号 Item_Size Chunk大小 Max_age LRU内最旧的记录的生存时间 1MB_pages 分配给Slab的页数 Count Slab内的记录数 Full? Slab内是否含有空闲chunk 从这个脚本获得的信息对于调优非常方便,强烈推荐使用。内存存储的总结本次简单说明了memcached的缓存机制和调优方法。希望读者能理解memcached的内存管理原理及其优缺点。下次将继续说明LRU和Expire等原理,以及memcached的最新发展方向--可扩充体系(pluggable architecher))。下面是《memcached全面剖析》的第三部分。发表日:2008/7/16 作者:前坂彻(Toru Maesaka) 原文链接:http://gihyo.jp/dev/feature/01/memcached/0003 ??memcached在数据删除方面有效利用资源 ??数据不会真正从memcached中消失 ??Lazy Expiration ??LRU:从缓存中有效删除数据的原理 ??memcached的最新发展方向 ??关于二进制协议 ??二进制协议的格式 ??HEADER中引人注目的地方 ??外部引擎支持 ??外部引擎支持的必要性 ??简单API设计的成功的关键 ??重新审视现在的体系 ??总结 memcached是缓存,所以数据不会永久保存在服务器上,这是向系统中引入memcached的前提。本次介绍memcached的数据删除机制,以及memcached的最新发展方向--二进制协议(Binary Protocol)和外部引擎支持。 memcached在数据删除方面有效利用资源数据不会真正从memcached中消失上次介绍过,memcached不会释放已分配的内存。记录超时后,客户端就无法再看见该记录(invisible,透明),其存储空间即可重复使用。 Lazy Expirationmemcached内部不会监视记录是否过期,而是在get时查看记录的时间戳,检查记录是否过期。这种技术被称为lazy(惰性)expiration。因此,memcached不会在过期监视上耗费CPU时间。 LRU:从缓存中有效删除数据的原理memcached会优先使用已超时的记录的空间,但即使如此,也会发生追加新记录时空间不足的情况,此时就要使用名为 Least Recently Used(LRU)机制来分配空间。顾名思义,这是删除"最近最少使用"的记录的机制。因此,当memcached的内存空间不足时(无法从slab class获取到新的空间时),就从最近未被使用的记录中搜索,并将其空间分配给新的记录。从缓存的实用角度来看,该模型十分理想。不过,有些情况下LRU机制反倒会造成麻烦。memcached启动时通过"-M"参数可以禁止LRU,如下所示: $ memcached -M -m 1024启动时必须注意的是,小写的"-m"选项是用来指定最大内存大小的。不指定具体数值则使用默认值64MB。指定"-M"参数启动后,内存用尽时memcached会返回错误。话说回来,memcached毕竟不是存储器,而是缓存,所以推荐使用LRU。 memcached的最新发展方向memcached的roadmap上有两个大的目标。一个是二进制协议的策划和实现,另一个是外部引擎的加载功能。关于二进制协议使用二进制协议的理由是它不需要文本协议的解析处理,使得原本高速的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/ 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如上所示,包格式十分简单。需要注意的是,占据了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 | +---------------+---------------+---------------+- --------------+ 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系列开始支持。外部引擎支持我去年曾经试验性地将memcached的存储层改造成了可扩展的(pluggable)。 ??http://alpha.mixi.co.jp/blog/?p=129 MySQL的Brian Aker看到这个改造之后,就将代码发到了memcached的邮件列表。memcached的开发者也十分感兴趣,就放到了roadmap中。现在由我和memcached的开发者Trond Norbye协同开发(规格设计、实现和测试)。和国外协同开发时时差是个大问题,但抱着相同的愿景,最后终于可以将可扩展架构的原型公布了。代码库可以从memcached的下载页面上访问。外部引擎支持的必要性世界上有许多memcached的派生软件,其理由是希望永久保存数据、实现数据冗余等,即使牺牲一些性能也在所不惜。我在开发memcached之前,在mixi的研发部也曾经考虑过重新发明memcached。外部引擎的加载机制能封装memcached的网络功能、事件处理等复杂的处理。因此,现阶段通过强制手段或重新设计等方式使memcached和存储引擎合作的困难就会烟消云散,尝试各种引擎就会变得轻而易举了。简单API设计的成功的关键该项目中我们最重视的是API设计。函数过多,会使引擎开发者感到麻烦;过于复杂,实现引擎的门槛就会过高。因此,最初版本的接口函数只有13个。具体内容限于篇幅,这里就省略了,仅说明一下引擎应当完成的操作: ??引擎信息(版本等) ??引擎初始化 ??引擎关闭 ??引擎的统计信息 ??在容量方面,测试给定记录能否保存 ??为item(记录)结构分配内存 ??释放item(记录)的内存 ??删除记录 ??保存记录 ??回收记录 ??更新记录的时间戳 ??数学运算处理 ??数据的flush 对详细规格有兴趣的读者,可以checkout engine项目的代码,阅读器中的engine.h。重新审视现在的体系memcached支持外部存储的难点是,网络和事件处理相关的代码(核心服务器)与内存存储的代码紧密关联。这种现象也称为tightly coupled(紧密耦合)。必须将内存存储的代码从核心服务器中独立出来,才能灵活地支持外部引擎。因此,基于我们设计的API,memcached被重构成下面的样子: 重构之后,我们与1.2.5版、二进制协议支持版等进行了性能对比,证实了它不会造成性能影响。在考虑如何支持外部引擎加载时,让memcached进行并行控制(concurrency control)的方案是最为容易的,但是对于引擎而言,并行控制正是性能的真谛,因此我们采用了将多线程支持完全交给引擎的设计方案。以后的改进,会使得memcached的应用范围更为广泛。总结本次介绍了memcached的超时原理、内部如何删除数据等,在此之上又介绍了二进制协议和外部引擎支持等memcached的最新发展方向。这些功能要到1.3版才会支持,敬请期待!这是我在本连载中的最后一篇。感谢大家阅读我的文章!下次由长野来介绍memcached的应用知识和应用程序兼容性等内容。发表日:2008/7/23 作者:长野雅广(Masahiro Nagano) 原文链接:http://gihyo.jp/dev/feature/01/memcached/0004 我是Mixi的长野。第2次、第3次由前坂介绍了memcached的内部情况。本次不再介绍memcached的内部结构,开始介绍memcached的分布式。 ??memcached的分布式 ??memcached的分布式是什么意思? ??Cache::Memcached的分布式方法 ??根据余数计算分散 ??根据余数计算分散的缺点 ??Consistent Hashing ??Consistent Hashing的简单说明 ??支持Consistent Hashing的函数库 ??总结 memcached的分布式正如第1次中介绍的那样,memcached虽然称为"分布式"缓存服务器,但服务器端并没有"分布式"功能。服务器端仅包括第2次、第3次前坂介绍的内存存储功能,其实现非常简单。至于memcached的分布式,则是完全由客户端程序库实现的。这种分布式是memcached的最大特点。 memcached的分布式是什么意思?这里多次使用了"分布式"这个词,但并未做详细解释。现在开始简单地介绍一下其原理,各个客户端的实现基本相同。下面假设memcached服务器有node1~node3三台,应用程序要保存键名为"tokyo""kanagawa""chiba""saitama""gunma"的数据。 图1 分布式简介:准备首先向memcached中添加"tokyo"。将"tokyo"传给客户端程序库后,客户端实现的算法就会根据"键"来决定保存数据的memcached服务器。服务器选定后,即命令它保存"tokyo"及其值。 图2 分布式简介:添加时同样,"kanagawa""chiba""saitama""gunma"都是先选择服务器再保存。接下来获取保存的数据。获取时也要将要获取的键"tokyo"传递给函数库。函数库通过与数据保存时相同的算法,根据"键"选择服务器。使用的算法相同,就能选中与保存时相同的服务器,然后发送get命令。只要数据没有因为某些原因被删除,就能获得保存的值。 图3 分布式简介:获取时这样,将不同的键保存到不同的服务器上,就实现了memcached的分布式。memcached服务器增多后,键就会分散,即使一台memcached服务器发生故障无法连接,也不会影响其他的缓存,系统依然能继续运行。接下来介绍第1次中提到的Perl客户端函数库Cache::Memcached实现的分布式方法。 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; my @nodes = ('node1','node2','node3'); my @keys = ('tokyo', 'kanagawa', 'chiba', 'saitama', 'gunma'); foreach my $key (@keys) { my $crc = crc32($key); # CRC
分享到:
评论

相关推荐

    Memcached完全剖析(转)

    NULL 博文链接:https://jzkangta.iteye.com/blog/981304

    memcached完全剖析 翻译整理

    memcached完全剖析 翻译整理

    memcached完全剖析(1-5)整理.docx

    memcached完全剖析(1-5)整理

    memcached完全剖析ehcache memcached redis 缓存技术总结

    NULL 博文链接:https://aperise.iteye.com/blog/2296219

    memcached全面剖析.zip

    memcached完全剖析–1. memcached的基础 memcached全面剖析–2. 理解memcached的内存存储 memcached全面剖析–3. memcached的删除机制和发展方向 memcached全面剖析–4. memcached的分布式算法 memcached全面...

    网上收集最新的Memcached学习资料

    Memcached原理和使用详解.pdf memcached完全剖析–1._memcached的基础.pdf memcached全面剖析.pdf Memcached内存分析、调优、集群.pptx

    memcached完全剖析–1.memcached的基础

    从今天开始,将分几次针对最近在Web应用的可扩展性领域的热门话题memcached,与我公司开发部研究开发组的前坂一起,说明其内部结构和使用。memcached是以LiveJournal旗下DangaInteractive公司的BradFitzpatric为首...

    memcache源码分析

    包含资源:memcached代码分析详解 memcached命令参数大全 memcached深度分析 memcached完全剖析(1-5)整理 memcached源码分析(自己整理 未完) Memcached源码剖析笔记 分布式存储系统架构

    memcached全面剖析–4.memcached的分布式算法

    至于memcached的分布式,则是完全由客户端程序库实现的。这种分布式是memcached的最大特点。这里多次使用了“分布式”这个词,但并未做详细解释。现在开始简单地介绍一下其原理,各个客户端的实现基本相同。下面假设...

    php模块memcache和memcached区别分析

    1.目前大多数php环境里使用的都是不带d的memcache版本,这个版本出的比较早,是一个原生版本,完全在php框架内开发的。与之对应的带d的memcached是建立在libmemcached的基础上,所以相对来说,memcached版本的功能更...

    大数据下的数据分析平台架构.pdf

    不要⼩看今天内存的容量,Facebook缓存在内存的Memcached中的数据⾼达 320TB,⽽⽬前的PC服务器,内存也可以超过百GB。因此可以采⽤⼀些内存数据库,将热点数据常驻内存之中,从⽽取得⾮常快速的分析 能⼒,⾮常适合...

    集群好书《高性能Linux服务器构建实战》 试读章节下载

    3.2 剖析Memcached的工作原理 3.2.1 Memcached的工作过程 3.2.2 Slab Allocation的工作机制 3.2.3 Memcached的删除机制 3.2.4 Memcached的分布式算法 3.3 Memcached的管理与性能监控 3.3.1 如何管理...

    UPUPW PHP v5.2.17 经典怀旧版套装 c1.zip

    4、完全兼容IIS,独具代理虚拟主机功能,可与IIS相辅相成并驾齐驱 ;  5、默认开启Gzip网页压缩传输,支持伪静态等设置; 6、支持虚拟主机可在任意磁盘建立网站目录,并且每个目录可单独绑定多级域名或泛域名 ;  ...

    中易广告联盟程序3.2

    本软件采用负载均衡的结构体系设计,只要硬件、宽带资源充足,可满足任何规模的网络广告宣传服务,前台采用Memcached用于提升系统访问速度,Memcached将数据库负载大幅度降低,以及图片、广告代码、统计代码服务器...

Global site tag (gtag.js) - Google Analytics