24.03.2015 Views

Memcached Memcached 原理和使用详解

Memcached Memcached 原理和使用详解

Memcached Memcached 原理和使用详解

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Memcached</strong> 原 理 和 使 用 详 解<br />

作 者 :heiyeluren( 黑 夜 路 人 )<br />

博 客 :http://blog.csdn.net/heiyeshuwu<br />

2009-01


Tech Talk 目 录 索 引<br />

• <strong>Memcached</strong> 介 绍<br />

• <strong>Memcached</strong> 安 装 和 使 用<br />

• 一 些 技 巧<br />

• Q&A<br />

2


<strong>Memcached</strong> 介 绍 :<br />

什 么 是 <strong>Memcached</strong>?<br />

<strong>Memcached</strong> 是 国 外 社 区 网 站 LiveJournal 的 开 发 团 队 开 发 的 高 性 能 的 分 布 式 内<br />

存 缓 存 服 务 器 。 一 般 的 使 用 目 的 是 , 通 过 缓 存 数 据 库 查 询 结 果 , 减 少 数 据 库 访<br />

问 次 数 , 以 提 高 动 态 Web 应 用 的 速 度 、 提 高 可 扩 展 性 。<br />

LiveJournal 团 队 开 发 了 包 括 <strong>Memcached</strong>、MogileFS<br />

MogileFS、Perlbal<br />

等 不 错 的 开<br />

源 项 目 。<br />

官 方 网 站 :http://www.danga.com/memcached/<br />

:<br />

3


<strong>Memcached</strong> 介 绍<br />

<strong>Memcached</strong> 运 行 图<br />

4


<strong>Memcached</strong> 介 绍<br />

谁 在 用 <strong>Memcached</strong>?<br />

国 外<br />

国 内<br />

5


<strong>Memcached</strong> 介 绍<br />

与 <strong>Memcached</strong> 类 似 的 还 有 什 么 ?<br />

国 外<br />

Tokyo Cabinet:http://tokyocabinet.sourceforge.net/index.html ( 日 本<br />

mixi.jp 公 司 开 发 )<br />

国 内<br />

MemcacheDB:http://memcachedb.org http://memcachedb.org ( 新 浪 开 源 Team 开 发 )<br />

tmcache: http://heiyeluren.googlecode.com ( 偶 开 发 的 ^_^)<br />

6


<strong>Memcached</strong> 介 绍<br />

<strong>Memcached</strong> 的 主 要 特 点<br />

• 基 于 C/S 架 构 , 协 议 简 单<br />

• 基 于 libevent 的 事 件 处 理<br />

• 自 主 内 存 存 储 处 理<br />

• 基 于 客 户 端 的 <strong>Memcached</strong> 分 布 式<br />

7


<strong>Memcached</strong> 介 绍<br />

基 于 C/S 架 构 , 协 议 简 单<br />

8


<strong>Memcached</strong> 介 绍<br />

基 于 libevent 的 事 件 处 理<br />

libevent 是 一 套 跨 平 台 的 事 件 处 理 接 口 的 封 装 , 能 够 兼 容 包 括 这 些 操 作 系 统 :<br />

Windows/Linux/BSD/Solaris 等 操 作 系 统 的 的 事 件 处 理 。<br />

包 装 的 接 口 包 括 :<br />

poll、select(Windows)<br />

select(Windows)、epoll(Linux)<br />

epoll(Linux)、kqueue(BSD)<br />

kqueue(BSD)、/dev/pool(Solaris)<br />

<strong>Memcached</strong> 使 用 libevent 来 进 行 网 络 并 发 连 接 的 处 理 , 能 够 保 持 在 很 大 并 发 情<br />

况 下 , 仍 旧 能 够 保 持 快 速 的 响 应 能 力 。<br />

libevent: http://www.monkey.org/~provos/libevent/<br />

9


<strong>Memcached</strong> 介 绍<br />

自 主 的 内 存 存 储 处 理<br />

• 数 据 存 储 方 式 :Slab:<br />

Allocation<br />

• 数 据 过 期 方 式 :Lazy:<br />

Expiration + LRU<br />

10


<strong>Memcached</strong> 介 绍<br />

数 据 存 储 方 式 :Slab:<br />

Allocation<br />

Slab Alloction 构 造 图<br />

Slab Allocator 的 基 本 原 理 是 按 照 预 先<br />

规 定 的 大 小 , 将 分 配 的 内 存 分 割 成 特 定<br />

长 度 的 块 , 以 完 全 解 决 内 存 碎 片 问 题 。<br />

Slab Allocation 的 原 理 相 当 简 单 。 将<br />

分 配 的 内 存 分 割 成 各 种 尺 寸 的 块<br />

(chunk), 并 把 尺 寸 相 同 的 块 分 成 组<br />

(chunk<br />

的 集 合 )<br />

11


<strong>Memcached</strong> 介 绍<br />

数 据 存 储 方 式 :Slab:<br />

Allocation<br />

Slab Classes 分 配 图<br />

Page: 分 配 给 Slab 的 内 存 空 间 , 默 认 是<br />

1MB。 。 分 配 给 Slab 之 后 根 据 slab 的 大 小<br />

切 分 成 chunk。<br />

Chunk: 用 于 缓 存 记 录 的 内 存 空 间 。<br />

Slab Class: 特 定 大 小 的 chunk 的 组 。<br />

memcached 根 据 收 到 的 数 据 的 大 小 , 选<br />

择 最 适 合 数 据 大 小 的 slab。<br />

memcached 中 保 存 着 slab 内 空 闲 chunk 的<br />

列 表 , 根 据 该 列 表 选 择 chunk, , 然 后 将<br />

数 据 缓 存 于 其 中 。<br />

12


<strong>Memcached</strong> 介 绍 :<br />

数 据 存 储 方 式 :Slab:<br />

Allocation<br />

Slab Alloction 缺 点<br />

这 个 问 题 就 是 , 由 于 分 配 的 是 特 定 长 度 的 内 存 , 因 此 无 法 有 效 利 用 分<br />

配 的 内 存 。 例 如 , 将 100 字 节 的 数 据 缓 存 到 128 字 节 的 chunk 中 , 剩 余<br />

的 28 字 节 就 浪 费 了 。<br />

13


<strong>Memcached</strong> 介 绍 :<br />

数 据 过 期 方 式<br />

• Lazy Expiration<br />

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

期 。 这 种 技 术 被 称 为 lazy( ( 惰 性 )expiration)<br />

expiration。 。 因 此 ,memcached,<br />

不 会 在 过 期 监 视 上 耗 费<br />

CPU 时 间 。<br />

• LRU<br />

memcached 会 优 先 使 用 已 超 时 的 记 录 的 空 间 , 但 即 使 如 此 , 也 会 发 生 追 加 新 记 录 时 空 间 不<br />

足 的 情 况 , 此 时 就 要 使 用 名 为 Least Recently Used(LRU<br />

LRU) ) 机 制 来 分 配 空 间 。 顾 名 思<br />

义 , 这 是 删 除 “ 最 近 最 少 使 用 ” 的 记 录 的 机 制 。 因 此 , 当 memcached 的 内 存 空 间 不 足 时<br />

( 无 法 从 slab class 获 取 到 新 的 空 间 时 ), 就 从 最 近 未 被 使 用 的 记 录 中 搜 索 , 并 将 其 空<br />

间 分 配 给 新 的 记 录 。 从 缓 存 的 实 用 角 度 来 看 , 该 模 型 十 分 理 想 。<br />

14


<strong>Memcached</strong> 介 绍 :<br />

基 于 客 户 端 的 <strong>Memcached</strong> 分 布 式<br />

15


<strong>Memcached</strong> 介 绍 :<br />

基 于 客 户 端 的 <strong>Memcached</strong> 分 布 式<br />

// 按 照 Key 值 , 获 取 一 个 服 务 器 ID<br />

int getServerId<br />

Id(char<br />

*key, int serverTotal) {<br />

int c, hash = 0;<br />

while (c = *key++) {<br />

hash += c;<br />

}<br />

return hash % serverTotal;<br />

}<br />

// 服 务 器 列 表<br />

node[0] => 192.168.0.1:11211<br />

node[1] => 192.168.0.2:11211<br />

node[2] => 192.168.0.3:11211<br />

// 获 取 key 是 tokyo 的 节 点 ID( 服 务 器 ID)<br />

int id = getServerId("test<br />

test",<br />

3);<br />

// 得 出 的 结 果 是 1, , 那 么 对 应 的 机 器 就 是<br />

node[id] == node[1]<br />

16


<strong>Memcached</strong> 介 绍 :<br />

基 于 客 户 端 的 <strong>Memcached</strong> 分 布 式<br />

写 入 操 作<br />

读 取 操 作<br />

17


<strong>Memcached</strong> 安 装 和 使 用 :<br />

• <strong>Memcached</strong> 安 装<br />

• <strong>Memcached</strong> 与 PHP 结 合 使 用<br />

• <strong>Memcached</strong> 与 C/C++ 结 合 使 用<br />

18


<strong>Memcached</strong> 安 装 和 使 用 :<br />

<strong>Memcached</strong> 安 装<br />

安 装 步 骤 :<br />

• 先 安 装 libevent<br />

• 再 安 装 <strong>Memcached</strong> 主 程 序<br />

源 码 下 载 :(:<br />

最 新 版 )<br />

libevent 官 网 :http://monkey.org/~provos/libevent/<br />

:<br />

libevent 下 载 :http://monkey.org/~provos/libevent-1.4.9-stable.tar.gz<br />

:<br />

<strong>Memcached</strong> 官 网 :http://www.danga.com/memcached:<br />

<strong>Memcached</strong> 下 载 :http://www.danga.com/memcached/dist/memcached-1.2.6.tar.gz<br />

:<br />

19


<strong>Memcached</strong> 安 装 和 使 用 :<br />

<strong>Memcached</strong> 安 装<br />

• 安 装 libevent<br />

# tar zxvf libevent-1.4.9-stable.tar.gz<br />

# cd libevent-1.4.9-stable<br />

# ./configure --prefix=/usr<br />

# make<br />

# make install<br />

• 安 装 <strong>Memcached</strong><br />

# tar zxvf memcached-1.2.6.tar.gz<br />

# cd memcached-1.2.6<br />

# ./configure --prefix=/usr/local<br />

# make<br />

# make install<br />

20


<strong>Memcached</strong> 安 装 和 使 用 :<br />

<strong>Memcached</strong> 运 行<br />

• 试 运 行 <strong>Memcached</strong><br />

# /usr/local/bin/memcached -u hualiangxie<br />

21


<strong>Memcached</strong> 安 装 和 使 用 :<br />

<strong>Memcached</strong> 运 行<br />

查 看 <strong>Memcached</strong> 帮 助 信 息<br />

# /usr/local/bin/memcached -h<br />

22


<strong>Memcached</strong> 安 装 和 使 用 :<br />

<strong>Memcached</strong> 运 行<br />

关 注 基 本 选 项<br />

-p 监 听 的 TCP 端 口 ( 缺 省 : 11211)<br />

-d 以 守 护 进 程 方 式 运 行 <strong>Memcached</strong><br />

-u 运 行 <strong>Memcached</strong> 的 账 户 , 非 root 用 户<br />

-m 最 大 的 内 存 使 用 , 单 位 是 MB, 缺 省 是 64 MB<br />

-c 软 连 接 数 量 , 缺 省 是 1024<br />

-v 输 出 警 告 和 错 误 信 息<br />

-vv<br />

打 印 客 户 端 的 请 求 和 返 回 信 息<br />

-h 打 印 帮 助 信 息<br />

-i 打 印 memcached 和 libevent 的 版 权 信 息<br />

运 行 <strong>Memcached</strong><br />

目 标 : 使 用 11211 端 口 、hualiangxie、<br />

用 户 、 最 大 占 用 512M 内 存 、1024、<br />

1024 个 软 连 接 , 输 出<br />

客 户 端 请 求 , 以 守 护 进 程 方 式 运 行<br />

# /usr/local/bin/memcached -p 11211 -d -u hualiangxie -m 512 -c 1024 -vvv<br />

23


<strong>Memcached</strong> 安 装 和 使 用 :<br />

<strong>Memcached</strong> 运 行<br />

检 查 是 否 正 常 启 动<br />

# pa auxxww | grep memcached<br />

1001 4402 0.0 0.0 2296 900 pts/0 S+ 19:24 0:00 /usr/local/bin/memcached -u hualiangxie<br />

root 4547 0.0 0.0 1892 668 pts/3 S+ 19:42 0:00 grep memcached<br />

# telnet localhost 11211<br />

Trying 127.0.0.1...<br />

Connected to localhost.<br />

Escape character is '^]'.<br />

stats<br />

STAT pid 4402<br />

STAT uptime 1032<br />

STAT time 1231155683<br />

STAT version 1.2.6<br />

STAT pointer_size 32<br />

...<br />

END<br />

24


<strong>Memcached</strong> 安 装 和 使 用 :<br />

<strong>Memcached</strong> 基 本 协 议<br />

数 据 存 取<br />

数 字 加 减<br />

set key1 0 180 3<br />

abc<br />

STORED<br />

add key1 0 180 3<br />

xyz<br />

NOT_STORED<br />

get key1<br />

VALUE key1 0 3<br />

abc<br />

END<br />

replace key1 0 180 3<br />

xyz<br />

STORED<br />

get key1<br />

VALUE key1 0 3<br />

xyz<br />

END<br />

delete key1<br />

DELETED<br />

set key2 0 180 4<br />

1234<br />

STORED<br />

incr key2 3<br />

1237<br />

get key2<br />

VALUE key2 0 4<br />

1237<br />

END<br />

decr key2 1<br />

1236<br />

get key2<br />

VALUE key2 0 4<br />

1236<br />

END<br />

25


<strong>Memcached</strong> 安 装 和 使 用 :<br />

<strong>Memcached</strong> 和 PHP 结 合 使 用<br />

安 装 PHP Memcache 扩 展<br />

扩 展 官 网 :http://pecl.php.net/package/memcache:<br />

扩 展 下 载 :http://pecl.php.net/get/memcache-2.2.4.tgz:<br />

Memcache 扩 展 安 装 :<br />

# tar zxvf memcache-2.2.4.tgz<br />

# cd memcache-2.2.4<br />

# /usr/local/php/bin/phpize<br />

# ./configure --with-php-config=/usr/local/php/bin/php-config<br />

# make<br />

# make install<br />

配 置<br />

# ls -l /usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/memcache.so<br />

# vim /usr/local/php/lib/php.ini<br />

新 增 配 置 内 容 :<br />

extension_dir = "/usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/"<br />

extension = memcache.so<br />

检 查 安 装 结 果<br />

# /usr/local/php/bin/php -m<br />

# /usr/local/apache2/bin/apachectl restart<br />

26


<strong>Memcached</strong> 安 装 和 使 用 :<br />

<strong>Memcached</strong> 与 PHP 结 合 使 用<br />

PHP 与 Memcache 结 合 测 试 代 码<br />

<br />

27


<strong>Memcached</strong> 安 装 和 使 用 :<br />

<strong>Memcached</strong> 与 PHP 结 合 使 用<br />

PHP 与 Memcache 分 布 式<br />

在 一 台 或 者 多 台 机 器 启 用 一 个 或 者 多 个 进 程 , 这 里 是 在 一 台 机 器 启<br />

用 两 个 进 程 , 使 用 两 个 端 口 :<br />

# /usr/local/bin/memcached -p 11211 -d -u hualiangxie<br />

# /usr/local/bin/memcached -p 11212 -d -u hualiangxie<br />

PHP 测 试 代 码<br />

<br />

注 意 : 实 际 上 Key1 保 存 在 11211 端 口 机 器 ,<br />

Key2 保 存 在 11212 端 口 机 器 上<br />

// 保 存 数 组 数 据<br />

$arr = array('aaa', 'bbb', 'ccc', 'ddd');<br />

$mem->set('key2', $arr, 0, 60);<br />

$val2 = $mem->get('key2');<br />

echo "Get key2 value: ";<br />

print_r($val2);<br />

echo "";<br />

28


<strong>Memcached</strong> 安 装 和 使 用 :<br />

<strong>Memcached</strong> 和 C/C++<br />

C++ 结 合 使 用<br />

安 装 C/C++ C++ <strong>Memcached</strong> 客 户 端 库 :libmemcached:<br />

开 发 库 官 网 :http://tangent.org/552/libmemcached.html:<br />

开 发 库 下 载 :http://download.tangent.org/libmemcached-0.25.tar.gz:<br />

libmemcached<br />

库 安 装 :<br />

# tar zxvf libmemcached-0.25.tar.gz<br />

# cd libmemcached-0.25<br />

# ./configure --prefix=/usr<br />

# make<br />

# make install<br />

检 查 安 装 结 果<br />

# ls /usr/lib/libmemcache* // 库 文 件<br />

# ls /usr/include/libmemcached/* // 头 文 件<br />

# ls /usr/bin/mem* // 命 令 行 工 具<br />

参 考 libmenmcached 开 发 示 例 代 码<br />

# man libmemcached_examples<br />

29


<strong>Memcached</strong> 安 装 和 使 用 :<br />

<strong>Memcached</strong> 与 C/C++ 结 合 使 用<br />

C/C++ 与 <strong>Memcached</strong> 结 合 测 试 代 码<br />

#include <br />

#include <br />

#include <br />

#include <br />

int main(int argc, char *argv[]) {<br />

memcached_st *memc;<br />

memcached_return rc;<br />

memcached_server_st *servers;<br />

char value[8191];<br />

//connect server<br />

memc = memcached_create(NULL);<br />

servers = memcached_server_list_append(NULL, "localhost",<br />

11211, &rc);<br />

rc = memcached_server_push(memc, servers);<br />

memcached_server_free(servers);<br />

//Save data<br />

strcpy(value, "This is c first value");<br />

rc = memcached_set(memc, "key1", 4, value, strlen(value),<br />

(time_t)180, (uint32_t)0);<br />

if (rc == MEMCACHED_SUCCESS) {<br />

printf("Save key:key1 data:\"%s\" success.\n", value);<br />

}<br />

//Fetch data<br />

char return_key[MEMCACHED_MAX_KEY];<br />

size_t return_key_length;<br />

char *return_value;<br />

size_t return_value_length;<br />

char *keys[]= {"key1"};<br />

size_t key_length[]= {4};<br />

uint32_t flags;<br />

rc = memcached_mget(memc, keys, key_length, 1);<br />

return_value = memcached_fetch(memc, return_key,<br />

&return_key_length, &return_value_length, &flags, &rc);<br />

if (rc == MEMCACHED_SUCCESS) {<br />

printf("Fetch key:%s data:%s\n", return_key, return_value);<br />

}<br />

//Delete data<br />

rc = memcached_delete(memc, "key1", 4, (time_t)0);<br />

if (rc == MEMCACHED_SUCCESS) {<br />

printf("Delete Key key1 success.\n");<br />

}<br />

//free<br />

memcached_free(memc);<br />

return 0;<br />

}<br />

30


<strong>Memcached</strong> 安 装 和 使 用 :<br />

<strong>Memcached</strong> 与 C/C++ 结 合 使 用<br />

C/C++ 与 <strong>Memcached</strong> 结 合 测 试 结 果<br />

编 译 执 行 以 上 代 码 :<br />

# gcc -o c_test1 c_test1.c -lmemcached<br />

# ./c_test1<br />

输 出 结 果 :<br />

Save key:key1 data:"This is c first value" success.<br />

Fetch key:key1 data:This is c first value<br />

Delete Key key1 success.<br />

31


<strong>Memcached</strong> 安 装 和 使 用 :<br />

<strong>Memcached</strong> 与 C/C++ 结 合 使 用<br />

C/C++ 与 <strong>Memcached</strong> 分 布 式 结 合 测 试 代 码 1<br />

#include <br />

#include <br />

#include <br />

#include <br />

int main(int argc, char *argv[]) {<br />

memcached_st *memc;<br />

memcached_return rc;<br />

memcached_server_st *servers;<br />

char value[8191];<br />

//connect multi server<br />

memc = memcached_create(NULL);<br />

servers = memcached_server_list_append(NULL, "localhost", 11211, &rc);<br />

servers = memcached_server_list_append(servers, "localhost", 11212, &rc);<br />

rc = memcached_server_push(memc, servers);<br />

memcached_server_free(servers);<br />

//Save multi data<br />

size_t i;<br />

char *keys[]= {"key1", "key2", "key3"};<br />

size_t key_length[]= {4, 4, 4};<br />

char *values[] = {"This is c first value", "This is c<br />

second value", "This is c third value"};<br />

size_t val_length[]= {21, 22, 21};<br />

for (i=0; i


<strong>Memcached</strong> 安 装 和 使 用 :<br />

<strong>Memcached</strong> 与 C/C++ 结 合 使 用<br />

C/C++ 与 <strong>Memcached</strong> 分 布 式 结 合 测 试 代 码 2<br />

//Fetch multi data<br />

char return_key[MEMCACHED_MAX_KEY];<br />

size_t return_key_length;<br />

char *return_value;<br />

size_t return_value_length;<br />

uint32_t flags;<br />

rc = memcached_mget(memc, keys, key_length, 3);<br />

while ((return_value = memcached_fetch(memc, return_key,<br />

&return_key_length, &return_value_length, &flags, &rc))) {<br />

if (rc == MEMCACHED_SUCCESS) {<br />

printf("Fetch key:%s data:%s\n", return_key, return_value);<br />

}<br />

}<br />

//Delete multi data<br />

for (i=0; i


<strong>Memcached</strong> 安 装 和 使 用 :<br />

<strong>Memcached</strong> 与 C/C++ 结 合 使 用<br />

C/C++ 与 <strong>Memcached</strong> 分 布 式 结 合 测 试 结 果<br />

编 译 执 行 以 上 代 码 :<br />

# gcc -o c_test2 c_test2.c -lmemcached<br />

# ./c_test2<br />

输 出 结 果 :<br />

Save key:key1 data:"This is c first value" success.<br />

Save key:key2 data:"This is c second value" success.<br />

Save key:key3 data:"This is c third value" success.<br />

Fetch key:key1 data:This is c first value<br />

Fetch key:key2 data:This is c second value<br />

Fetch key:key3 data:This is c third value<br />

Delete key1 success<br />

Delete key2 success<br />

Delete key3 success<br />

34


一 些 经 验 和 技 巧 :<br />

<strong>Memcached</strong> 一 些 特 性 和 限 制<br />

• 在 <strong>Memcached</strong> 中 可 以 保 存 的 item 数 据 量 是 没 有 限 制 的 , 只 有 内 存 足 够<br />

• <strong>Memcached</strong> 单 进 程 最 大 使 用 内 存 为 2G, , 要 使 用 更 多 内 存 , 可 以 分 多 个 端 口 开 启 多 个 <strong>Memcached</strong> 进 程<br />

• 最 大 30 天 的 数 据 过 期 时 间 , 设 置 为 永 久 的 也 会 在 这 个 时 间 过 期 , 常 量 REALTIME_MAXDELTA<br />

60*60<br />

60*24*30<br />

控 制<br />

• 最 大 键 长 为 250 字 节 , 大 于 该 长 度 无 法 存 储 , 常 量 KEY_MAX_LENGTH 250 控 制<br />

• 单 个 item 最 大 数 据 是 1MB, , 超 过 1MB 数 据 不 予 存 储 , 常 量 POWER_BLOCK 1048576 进 行 控 制 ,<br />

它 是 默 认 的 slab 大 小<br />

• 最 大 同 时 连 接 数 是 200, , 通 过 conn_init() 中 的 freetotal 进 行 控 制 , 最 大 软 连 接 数 是 1024, , 通 过<br />

settings.maxconns=1024 进 行 控 制<br />

• 跟 空 间 占 用 相 关 的 参 数 :settings.factor=1.25,:<br />

settings.chunk_size=48, 影 响 slab 的 数 据 占 用 和 步 进 方 式<br />

35


一 些 经 验 和 技 巧 :<br />

查 看 <strong>Memcached</strong> 内 部 工 作 状 态<br />

访 问 <strong>Memcached</strong>:telnet<br />

主 机 名 端 口 号<br />

查 看 总 状 态 :stats:<br />

stats<br />

查 看 某 项 状 态 :stats:<br />

stats curr_connections<br />

禁 止 LRU<br />

有 些 情 况 下 LRU 机 制 反 倒 会 造 成 麻 烦 。memcached。<br />

启 动 时 通 过 “-M” 参 数 可 以 禁 止 LRU,<br />

如 下 所 示 :<br />

$ memcached -M -m 1024<br />

启 动 时 必 须 注 意 的 是 , 小 写 的 “-m” 选 项 是 用 来 指 定 最 大 内 存 大 小 的 。 不 指 定 具 体 数 值 则<br />

使 用 默 认 值 64MB。<br />

指 定 “-M” 参 数 启 动 后 , 内 存 用 尽 时 memcached 会 返 回 错 误 。 话 说 回 来 ,memcached,<br />

毕<br />

竟 不 是 存 储 器 , 而 是 缓 存 , 所 以 推 荐 使 用 LRU。<br />

36


一 些 经 验 和 技 巧 :<br />

<strong>Memcached</strong> 使 用 线 程 模 式 工 作<br />

在 安 装 的 时 候 必 须 打 开 :./configure:<br />

--enable-threads<br />

安 装 完 之 后 , 启 动 的 时 候 看 看 帮 助 信 息 有 没 有 这 条 :<br />

-t number of threads to use, default 4<br />

如 果 存 在 该 选 项 , 说 明 已 经 支 持 了 线 程 , 就 可 以 在 启 动 的 时 候 使 用 -t 选 项 来 启 动 多 线 程<br />

然 后 启 动 的 时 候 必 须 加 上 你 需 要 支 持 的 线 程 数 量 :<br />

/usr/local/memcache/bin/memcached -t 1024<br />

37


一 些 经 验 和 技 巧 :<br />

调 优 Slab 和 内 存 分 配 1<br />

memcached 在 启 动 时 指 定 Growth Factor 因 子 ( 通 过 -f 选 项 ), 就 可 以 在 某 种 程 度 上 控 制 slab 之 间 的 差 异 。<br />

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

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

$ memcached -f 2 -vv<br />

slab class 1: chunk size 128 perslab 8192<br />

slab class 2: chunk size 256 perslab 4096<br />

slab class 3: chunk size 512 perslab 2048<br />

slab class 4: chunk size 1024 perslab 1024<br />

slab class 5: chunk size 2048 perslab 512<br />

slab class 6: chunk size 4096 perslab 256<br />

slab class 7: chunk size 8192 perslab 128<br />

slab class 8: chunk size 16384 perslab 64<br />

slab class 9: chunk size 32768 perslab 32<br />

slab class 10: chunk size 65536 perslab 16<br />

slab class 11: chunk size 131072 perslab 8<br />

slab class 12: chunk size 262144 perslab 4<br />

slab class 13: chunk size 524288 perslab 2<br />

38


一 些 经 验 和 技 巧 :<br />

调 优 Slab 和 内 存 分 配 2<br />

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

slab 之 间 的 差 别 比 较<br />

大 , 有 些 情 况 下 就 相 当 浪 费 内 存 。 因 此 , 为 尽 量 减 少 内 存 浪 费 , 两 年 前 追 加 了 growth factor 这 个 选 项 。<br />

来 看 看 现 在 的 默 认 设 置 (f=1.25(<br />

f=1.25) ) 时 的 输 出 ( 篇 幅 所 限 , 这 里 只 写 到 第 10 组 ):<br />

slab class 1: chunk size 88 perslab 11915<br />

slab class 2: chunk size 112 perslab 9362<br />

slab class 3: chunk size 144 perslab 7281<br />

slab class 4: chunk size 184 perslab 5698<br />

slab class 5: chunk size 232 perslab 4519<br />

slab class 6: chunk size 296 perslab 3542<br />

slab class 7: chunk size 376 perslab 2788<br />

slab class 8: chunk size 472 perslab 2221<br />

slab class 9: chunk size 592 perslab 1771<br />

slab class 10: chunk size 744 perslab 1409<br />

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

有 些 计 算 误 差 , 这 些 误 差 是 为 了 保 持 字 节 数 的 对 齐 而 故 意 设 置 的 。<br />

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

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

39


一 些 经 验 和 技 巧 :<br />

参 考 文 档 和 延 伸 阅 读<br />

以 下 为 本 PPT 参 考 文 档 , 特 别 是 参 考 了 mixi.jp 公 司 编 写 的 《<strong>Memcached</strong>《<br />

全 面 剖 析 》<br />

<strong>Memcached</strong> 全 面 剖 析 :http://tech.idv2.com/2008/08/17/memcached-pdf/:<br />

<strong>Memcached</strong> 1.2 内 存 模 型 分 析 :http://phpcup.cn/viewthread.php?tid=45:<br />

<strong>Memcached</strong> 深 度 分 析 :http://funjackyone.javaeye.com/blog/128384:<br />

memcached server LRU 深 入 分 析 :http://www.javaeye.com/topic/225692:<br />

Memcache 使 用 详 解 : http://blog.csdn.net/heiyeshuwu/archive/2006/11/13/1380838.aspx<br />

40

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!