Posts Tagged ‘memcached’

为准备公司网站的重构,前端时间研究Memcached分布式集群 和 Hiphop-php(Facebook的一个开源项目)的搭建 ,花了不少时间和精力,下边进行一下整理。。。 一、Memcached客户端库算法研究 取模算法与一致性算法Memcached虽然被称为”分布式”缓存服务器,但是服务器 段并没有分布式功能,实现分布式主要是通过客户端库来实现。无论使用哪种语言实现的客户端库都会包含至少一种分布算法来实现Memcached分布式。 因此笼统来说客户端库是 通过一个分布算法和维护的一个服务器列表来实现Memcached分布式的,关于分布算法目前有两种选择:取模算法(modula hashing)和一致性算法(consistent hashing)。 取模算法(modula hashing)是当前多数客户端库默 认算法 [Hash($key) % $svrNum ],就是根据服务器节点数的余数来进行分散,就是通过hash函数求得的Key的整数哈希值再除以服 务器节点数并取余数来选择服务器。这种算法取余计算简单,分散效果好,但是缺点是如果某一台机器宕机,那么应该落在该机器的请求就无法得到正确的处理,这 时需要将当掉的服务器从算法从去除,此时候会有(N-1)/N的服务器的缓存数据需要重新进行计算;如果新增一台机器,会有N/(N+1)的服务器的缓存数据需 要进行重新计算。对于系统而言,这通常是不可接受的颠簸(因为这意味着大量缓存的失效或者数据需要转移)。 一致性算法(consistent hashing)来源于p2p网络的路由算法,算法描述:hash值一般为unsigned int型,因此对于hash函数的结果应该均匀分布在[0,2^32-1]间,把一个圆环用2^32  个 点来进行均匀切割,首先按照hash()函数算出服务器(节点)的哈希值, 并将其分布到0~2^32的圆上。用同样的hash()函数求出需要存储数据的键的哈希值,并映射到圆上。然后从数据 映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器(节点)上,新增一个节点的时候,只有在圆环上新增节点逆时针方向的第一个节点的数据会受到 影响。删除一个节点的时候,只有在圆环上原来删除节点顺时针方向的第一个节点的数据会受到影响,因此通过Consistent Hashing很好地解决了负载均衡 中由于新增节点、删除节点引起的hash值颠簸问题。 PHP的 Memcached客户端库目前有两个:PECL::memcache 和PECL::memcached,下边是两个库的比较: PECL::memcache PECL::memcached 第一个版本时间 2004-06-08 2009-01-29(beta) 外部依赖 无 libmemcached 二进制协议 3.0.0以上版本 可选 当前最新稳定版本 2.2.5 1.0.1 通讯超时支持 仅connect支持 多种选项 一致性算法 支持 支持 储存数值类型 [...]

Thursday, July 15th, 2010 at 11:52 | 0 comments
Categories: 技术

mixi案例研究 mixi在提供服务的初期阶段就使用了memcached。 随着网站访问量的急剧增加,单纯为数据库添加slave已无法满足需要,因此引入了memcached。 此外,我们也从增加可扩展性的方面进行了验证,证明了memcached的速度和稳定性都能满足需要。 现在,memcached已成为mixi服务中非常重要的组成部分。 图1 现在的系统组件 服务器配置和数量 mixi使用了许许多多服务器,如数据库服务器、应用服务器、图片服务器、 反向代理服务器等。单单memcached就有将近200台服务器在运行。 memcached服务器的典型配置如下: CPU:Intel Pentium 4 2.8GHz 内存:4GB 硬盘:146GB SCSI 操作系统:Linux(x86_64) 这些服务器以前曾用于数据库服务器等。随着CPU性能提升、内存价格下降, 我们积极地将数据库服务器、应用服务器等换成了性能更强大、内存更多的服务器。 这样,可以抑制mixi整体使用的服务器数量的急剧增加,降低管理成本。 由于memcached服务器几乎不占用CPU,就将换下来的服务器用作memcached服务器了。 memcached进程 每台memcached服务器仅启动一个memcached进程。分配给memcached的内存为3GB, 启动参数如下: /usr/bin/memcached -p 11211 -u nobody -m 3000 -c 30720 由于使用了x86_64的操作系统,因此能分配2GB以上的内存。32位操作系统中, 每个进程最多只能使用2GB内存。也曾经考虑过启动多个分配2GB以下内存的进程, 但这样一台服务器上的TCP连接数就会成倍增加,管理上也变得复杂, 所以mixi就统一使用了64位操作系统。 另外,虽然服务器的内存为4GB,却仅分配了3GB,是因为内存分配量超过这个值, 就有可能导致内存交换(swap)。连载的第2次中 前坂讲解过了memcached的内存存储“slab allocator”,当时说过,memcached启动时 指定的内存分配量是memcached用于保存数据的量,没有包括“slab allocator”本身占用的内存、 以及为了保存数据而设置的管理空间。因此,memcached进程的实际内存分配量要比 指定的容量要大,这一点应当注意。 mixi保存在memcached中的数据大部分都比较小。这样,进程的大小要比 指定的容量大很多。因此,我们反复改变内存分配量进行验证, 确认了3GB的大小不会引发swap,这就是现在应用的数值。 memcached使用方法和客户端 现在,mixi的服务将200台左右的memcached服务器作为一个pool使用。 每台服务器的容量为3GB,那么全体就有了将近600GB的巨大的内存数据库。 客户端程序库使用了本连载中多次提到车的Cache::Memcached::Fast, 与服务器进行交互。当然,缓存的分布式算法使用的是 [...]

Friday, February 12th, 2010 at 01:24 | 1 comment
Categories: TODO, 技术

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 = [...]

Friday, February 12th, 2010 at 01:19 | 0 comments
Categories: TODO, 技术

memcached是缓存,所以数据不会永久保存在服务器上,这是向系统中引入memcached的前提。 本次介绍memcached的数据删除机制,以及memcached的最新发展方向——二进制协议(Binary Protocol) 和外部引擎支持。 memcached在数据删除方面有效利用资源 数据不会真正从memcached中消失 上次介绍过, memcached不会释放已分配的内存。记录超时后,客户端就无法再看见该记录(invisible,透明), 其存储空间即可重复使用。 Lazy Expiration memcached内部不会监视记录是否过期,而是在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 | / | [...]

Friday, February 12th, 2010 at 00:06 | 0 comments
Categories: TODO, 技术

我是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 to eliminate memory fragmentation issues totally by using fixed-size memory chunks coming from a few predetermined size classes. 也就是说,Slab Allocator的基本原理是按照预先规定的大小,将分配的内存分割成特定长度的块, 以完全解决内存碎片问题。 Slab Allocation的原理相当简单。 将分配的内存分割成各种尺寸的块(chunk), 并把尺寸相同的块分成组(chunk的集合)(图1)。 图1 Slab Allocation的构造图 而且,slab allocator还有重复使用已分配的内存的目的。 [...]

Thursday, February 11th, 2010 at 23:57 | 0 comments
Categories: TODO, 技术

翻译一篇技术评论社的文章,是讲memcached的连载。fcicq同学说这个东西很有用,希望大家喜欢。 发表日:2008/7/2 作者:长野雅广(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等格式, [...]

Thursday, February 11th, 2010 at 23:45 | 0 comments
Categories: TODO, 技术
Tags:
TOP