您的位置:首页 > 运维架构 > 网站架构

深度剖析CloudFoundry的架构设计

2012-08-14 10:28 225 查看
1、概述
Memcached是一个C语言编写的高性能分布式的内存对象缓存系统,用于减少Web应用直接跟数据库交互,从而减轻数据库负载压力,将一些经常访问的数据对象以K/V(键/值)对的形式存放在内存中作为缓存数据。缓存是一种加速应用向后端服务器读取数据的优化手段,其思想是用对内存的读取换取直接对磁盘数据库中数据的操作,以提高web应用程序的访问速度,从而实现web动态页面高性能、高并发的访问。
Memcached是通过C语言Danga Interactive开发编写的,使用libevent框架实现底层的TCP/IP通信,只要支持Socket操作的语言都可以编写自己的客户端,与Memcached Server端进行通信,从而使用Memcached提供的功能。
因为应用程序链接memcached仅通过(IP+端口)的形式,所以memcached有内存泄露的风险,因此它不会在web前段或公网上部署。它的部署一般位于web和数据库之间,用于缓解数据库的压力。
原文:memcached is a flexible memory object caching daemon designed to alleviate database load in dynamic web applications by storing objects in memory. It's based on libevent to scale to any size needed, and is specifically optimized to avoid swap-ping and always use non-blocking I/O.
译文:memcached 是一个灵活的内存对象缓存守护进程。它通过将对象缓存在内存中,从而降低WEB应用对数据库的压力。它基于 libevent 库,可以伸缩到任意大小,并永远使用非阻塞的网络I/O。因此在使用 memcached 的机器上应避免使用虚拟内存(swap)。

2、memcached的安装部署
2.1、源码获取
[root@mysqldb1 ~]# wget http://memcached.org/files/memcached-1.4.24.tar.gz [root@mysqldb1 ~]# wget http://nchc.dl.sourceforge.net/project/levent/libevent/libevent-2.0/libevent-2.0.22-stable.tar.gz[/code]2.2、安装libevent库 因为memcached是基于libevent库,所以我们在安装memcached之前得先安装libevent,下面是安装libevent的步骤方法:
[root@mysqldb1 ~]# tar xf libevent-2.0.22-stable.tar.gz
[root@mysqldb1 ~]# cd libevent-2.0.22-stable
[root@mysqldb1 libevent-2.0.22-stable]#  ./configure --prefix=/usr/local
[root@mysqldb1 libevent-2.0.22-stable]#  make && make install
[root@mysqldb1 libevent-2.0.22-stable]#  cd ..
[root@mysqldb1 ~]#


2.3、安装memcached缓存服务器
[root@mysqldb1 ~]# tar xf memcached-1.4.24.tar.gz
[root@mysqldb1 memcached-1.4.24]# cd memcached-1.4.24
[root@mysqldb1 memcached-1.4.24]# ./configure --with-libevent=/usr/local
[root@mysqldb1 memcached-1.4.24]# make && make install
[root@mysqldb1 memcached-1.4.24]# cd ..
[root@mysqldb1 ~]#


2.4、查看安装结果
[root@mysqldb1 ~]# ls -al /usr/local/bin/mem*
-rwxr-xr-x. 1 root root 360873 Oct 22 00:22 /usr/local/bin/memcached


3、memcached参数详解
-s file
指定在那个文件上监听 Unix socket (不使用TCP/IP网络)
-a perms
指定"-s"选项创建的 Unix socket 文件的权限(八进制)
-l ip_addr
在指定的 ip_addr 上监听,默认是所有可用地址(INADDR_ANY)。
这是一个重要的选项,因为没有其它更多的访问控制方法。
出于安全考虑,建议绑定到内网接口或者有防火墙保护的网络接口。
-d
以守护进程的方式运行(后台运行)
-u username
指定以 username 用户的身份运行,该选项仅在以root用户启动时有效。
-m num
使用 num MB 大小的内存作为缓冲区,默认值是 64MB
-c num
最大允许 num 个并发连接,默认值是 1024
-R num
这是一个为了防止某些客户端被饿死而设置的选项。num 的默认值是"20"。
参数 num 表示服务器在同一个连接内最多连续处理 num 个请求。
一旦某连接连续处理的请求数超过了 num 的限制,服务器将会转而去处理其他连接的请求,
直到其他连接的请求全部处理完毕(或者也达到了上限)之后,才会回过头来继续处理此连接上剩余的请求。
-k
锁定所有分页内存(paged memory)。这个选项在缓冲区比较大的时候使用可能会有些危险。
-p num
在TCP端口 num 上监听,默认值是 11211
-U num
在UDP端口 num 上监听,默认值是 11211 ,0 表示关闭
-M
禁止在缓冲区不够用的时候自动移除缓存对象。这样将会导致缓冲区满时无法添加新对象。
-r
将核心文件尺寸限制加大到最大值
-f factor
将 factor 用作计算每个缓存项所占内存块大小的乘数(multiplier)。默认值是"1.25"。
也许较小的乘数会减少内存的浪费,但实际效果取决于可用内存总量以及不同缓存项大小的分布状况。
-n size
最少为每个缓存对象的"key, value, flags"分配 size 字节。默认值为 48 。
如果你有大量的小"key,value"对,减小此值将会大大提高内存的利用效率。
另一方面,如果你使用"-f"选项指定了较大的块膨胀系数(chunk growth factor),
那么你应当增加此值以让更高比例的缓存项更适合稠密的压缩内存块。
-C
禁止使用CAS(可以为每个缓存项节约8个字节的空间)
-h
显示版本号和选项列表后退出
-v
在事件循环过程中打印详细的错误和警告消息
-vv
显示更加详细的消息,也就是在"-v"的基础上打印客户端命令和应答
-i
打印 memcached 和 libevent 的许可证
-P filename
将进程号(PID)保存在 filename 中,仅在使用了"-d"选项后才有意义。
-t threads
使用 threads 个线程来处理接入请求。将此值设置为超过总的CPU核心数只会弄巧成拙。默认值是 4 。
-D char
使用 char 作为key前缀和ID之间的分隔符,这将用于每一个前缀状态报告。默认值是冒号(:)。
明确指定此选项后状态收集器将被自动打开,否则可以通过向服务器发送"stats detail on"命令来开启。
-L
尽量使用大内存页(如果可用)。使用大内存页可以增大TLB缓存命中概率,从而提升内存性能。
此选项仅在内核支持大内存页(CONFIG_TRANSPARENT_HUGEPAGE,CONFIG_HUGETLBFS)的系统上有意义。
-B proto
指定要使用的绑定协议。默认值"auto"表示由服务器与客户端进行协商。
而"ascii"和"binary"则明确表示仅允许使用确定的协议。
-I size
指定每个slab/slub页的默认大小。默认值是"1m"。允许的最小值是"1k",允许的最大值是"128m"。
改变此项同时也改变了每个缓存项的尺寸上限。
增大此项的同时也增大了slab/slub页的数量(可以使用 -v 查看),以及 memcached 的内存总使用量。
-F
禁用"flush_all"命令。
cmd_flush 计数器仍然会增加,但是客户端将会收到"刷新动作未被执行"的错误消息。
-o options
逗号分隔的扩展或实验性选项的列表。参见 -h 或 wiki 以获取这些选项。


4、memcached启动、停止及服务脚本的编写
4.1、启动
[root@mysqldb1 ~]# /usr/local/bin/memcached -d -m 10 -u root -p 12011 -c 512 -P /var/run/memcached.pid


4.2、查看memcached进程运行状态:

[root@mysqldb1 ~]# . /etc/init.d/functions ; status memcached
memcached (pid  2599) is running...


4.3、查看memcached进程id:
[root@mysqldb1 ~]# cat /var/run/memcached.pid
2478


4.4、停止memcached各种方法:
方法一、用kill命令
[root@mysqldb1 ~]# kill -9 2478
[root@mysqldb1 ~]# ps -ef | grep memcached | grep -v grep


方法二、用pkill命令
[root@mysqldb1 ~]# /usr/local/bin/memcached -d -m 10 -u root -p 12011 -c 512 -P /var/run/memcached.pid
[root@mysqldb1 ~]# # . /etc/init.d/functions ; status memcached
memcached (pid  2599) is running...
[root@mysqldb1 ~]# pkill memcached
[root@mysqldb1 ~]# . /etc/init.d/functions ; status memcached
memcached dead but pid file exists


方法三、使用/etc/init.d/funtions函数集合中的killproc函数
[root@mysqldb1 ~]# . /etc/init.d/functions ; killproc memcached ; echo "kill memcached ......"
kill memcached ......                                      [  OK  ]


5、memcached启动脚本编写及测试

5.1、编写memcached
[root@mysqldb1 ~]# vim /etc/init.d/memcached
#!/bin/bash
proc="memcached"                 #memcached 进程名
mem="/usr/local/bin/memcached" #memcached 安装的位置
user="root"   #memcached 启动用户
port="11211"#memcached 启动端口号
pid="/var/run/memcached.pid"#memcached启动后进程id存放的位置
conn="512"#memcached 并发数设置
mem_size="256"  #memcached 内存缓冲区的设置,默认值是 64MB
. /etc/init.d/functions
start()
{
action "Started memcached......" /usr/local/bin/memcached -d -m $mem_size -u $user -p $port -c $conn -P $pid
}
stop()
{
killproc $proc
printf "Stopped memcached ......\n"
}
restart()
{
stop
start
}
memstatus()
{
status $proc
[ $? != 0 ] && echo "memcached is stopped"
}
case $1 in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
memstatus
;;
*)
echo "Usage: $0 {start|stop|restart|status}";;
esac
5.2、memcached脚本的测试

5.2.1、memcached的脚本启动
[root@mysqldb1 ~]# /etc/init.d/memcached start
Started memcached......                                   [  OK  ]
[root@mysqldb1 ~]# /etc/init.d/memcached status
memcached (pid  2893) is running...
[root@mysqldb1 ~]# ps -ef | grep memcached | grep -v "grep"
root      2864     1  0 02:38 ?        00:00:00 /usr/local/bin/memcached -d -m 256 -u root -p 11211 -c 512 -P /var/run/memcached.pid
[root@mysqldb1 ~]# netstat -tlunp | grep 11211
tcp        0      0 0.0.0.0:11211               0.0.0.0:*                   LISTEN      2864/memcached
tcp        0      0 :::11211                    :::*                        LISTEN      2864/memcached
udp        0      0 0.0.0.0:11211               0.0.0.0:*                               2864/memcached
udp        0      0 :::11211                    :::*                                    2864/memcached
5.2.2、memcached的脚本重启
[root@mysqldb1 ~]# /etc/init.d/memcached restart
Stopped memcached ......                                  [  OK  ]
Started memcached......                                   [  OK  ]
[root@mysqldb1 ~]# /etc/init.d/memcached status
memcached (pid  2929) is running...
[root@mysqldb1 ~]# ps aux | grep memcached | grep -v "grep"
root      2893  0.0  0.1 331196  3108 ?        Ssl  02:42   0:00 /usr/local/bin/memcached -d -m 256 -u root -p 11211 -c 512 -P /var/run/memcached.pid
[root@mysqldb1 ~]# netstat -tlunp | grep memcached
tcp        0      0 0.0.0.0:11211               0.0.0.0:*                   LISTEN      2893/memcached
tcp        0      0 :::11211                    :::*                        LISTEN      2893/memcached
udp        0      0 0.0.0.0:11211               0.0.0.0:*                               2893/memcached
udp        0      0 :::11211                    :::*                                    2893/memcached
5.2.3、memcached的脚本停止

[root@mysqldb1 ~]# /etc/init.d/memcached stop
Stopped memcached ......                                  [  OK  ]
[root@mysqldb1 ~]# /etc/init.d/memcached status
memcached is stopped
memcached is stopped
[root@mysqldb1 ~]# ps aux | grep memcached | grep -v "grep"
[root@mysqldb1 ~]# netstat -tlunp | grep memcached
[root@mysqldb1 ~]#


6、使用shell对memcached进行简单CRUD操作
6.1、memcached命令说明
key  key 用于查找缓存值
flags       可以包括键值对的整型参数,客户机使用它存储关于键值对的额外信息
expiration time       在缓存中保存键值对的时间长度(以秒为单位,0 表示永远)
bytes       在缓存中存储的字节点
value       存储的值(始终位于第二行) 例子:
set key 0 0 7 \r\nliangge\r\n

6.2、set: 用于向缓存添加新的键值对。如果键已经存在,则之前的值将被替换。
给key设置值
[root@mysqldb1 ~]# printf "set key 0 0 7 \r\nliangge\r\n" | nc 192.168.1.2 11211
STORED
・
获取key中的值
[root@mysqldb1 ~]# printf "get key\r\n" | nc 192.168.1.2 11211
VALUE key 0 7
liangge
END

6.3、add :仅当缓存中不存在键时,add 命令才会向缓存中添加一个键值对。如果缓存中已经存在键,则之前的值将仍然保持相同,并且您将获得响应NOT_STORED 。
给number键添加1000值
[root@mysqldb1 ~]# printf "add number 0 0 4 \r\n1000\r\n" | nc 192.168.1.2 11211
STORED
[root@mysqldb1 ~]# printf "get number\r\n" | nc 192.168.1.2 11211
VALUE number 0 4
1000
END
把number中的值加5
[root@mysqldb1 ~]# printf "incr number 5\r\n" | nc 192.168.1.2 11211
1005
把number中的值减去3
[root@mysqldb1 ~]# printf "decr number 3\r\n" | nc 192.168.1.2 11211
1002


6.4、replace:仅当键已经存在时,replace 命令才会替换缓存中键相对应值。如果缓存中不存在键,那么您将从memcached 服务器接受到一条NOT_STORED 响应。
[root@mysqldb1 ~]# printf "replace number 0 0 4 \r\n2000\r\n" | nc 192.168.1.2 11211
STORED
[root@mysqldb1 ~]# printf "get number\r\n" | nc 192.168.1.2 11211
VALUE number 0 4
2000
END

6.5、delete:用于删除memcached 中的任何现有值。您将使用一个键调用delete ,如果该键存在于缓存中,则删除该值。如果不存在,则返回一条NOT_FOUND 消息。
[root@mysqldb1 ~]# printf "delete number\r\n" | nc 192.168.1.2 11211
DELETED
[root@mysqldb1 ~]# printf "get number\r\n" | nc 192.168.1.2 11211
END

6.7、get及gets:两个命令使用及其之间的差异比较。
[root@mysqldb1 ~]# printf "get key\r\n" | nc 192.168.1.2 11211
VALUE key 0 7
liangge
END
[root@mysqldb1 ~]# printf "gets key\r\n" | nc 192.168.1.2 11211
VALUE key 0 7 1
liangge
END

6.8、memcached状态信息的查看
[root@mysqldb1 ~]# printf "stats\r\n" | nc 192.168.1.2 11211
STAT pid 1999
STAT uptime 37
STAT time 1446323288
STAT version 1.4.24
STAT libevent 2.0.22-stable
STAT pointer_size 64
STAT rusage_user 0.000000
STAT rusage_system 0.039993
STAT curr_connections 10
STAT total_connections 13
STAT connection_structures 11
STAT reserved_fds 20
STAT cmd_get 0
STAT cmd_set 0
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 0
STAT get_misses 0
STAT delete_misses 0
STAT delete_hits 0
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 21
STAT bytes_written 14
STAT limit_maxbytes 268435456
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT malloc_fails 0
STAT bytes 0
STAT curr_items 0
STAT total_items 0
STAT expired_unfetched 0
STAT evicted_unfetched 0
STAT evictions 0
STAT reclaimed 0
STAT crawler_reclaimed 0
STAT crawler_items_checked 0
STAT lrutail_reflocked 0
END


7、Memcached多实例演示

#分别以12012、12013、12014这三个端口启动Memcached多实例缓存服务器
[root@mysqldb1 ~]# /usr/local/bin/memcached -d -m 10 -u root -p 12012 -c 512 -P /var/run/memcached1.pid
[root@mysqldb1 ~]# /usr/local/bin/memcached -d -m 10 -u root -p 12013 -c 512 -P /var/run/memcached2.pid
[root@mysqldb1 ~]# /usr/local/bin/memcached -d -m 10 -u root -p 12014 -c 512 -P /var/run/memcached3.pid

#用ps命令查看Memcached多实例服务进程的开启状态
[root@mysqldb1 ~]# ps -ef | grep memcached | grep -v grep
root      1999     1  0 04:27 ?        00:00:00 /usr/local/bin/memcached -d -m 256 -u root -p 11211 -c 512 -P /var/run/memcached.pid
root      2354     1  0 06:18 ?        00:00:00 /usr/local/bin/memcached -d -m 10 -u root -p 12012 -c 512 -P /var/run/memcached1.pid
root      2361     1  0 06:18 ?        00:00:00 /usr/local/bin/memcached -d -m 10 -u root -p 12013 -c 512 -P /var/run/memcached2.pid
root      2369     1  0 06:19 ?        00:00:00 /usr/local/bin/memcached -d -m 10 -u root -p 12014 -c 512 -P /var/run/memcached3.pid

#用netstat查看Memcached的服务端口号的开启状态
[root@mysqldb1 ~]# netstat -tulnp | grep memcached
tcp        0      0 0.0.0.0:11211               0.0.0.0:*                   LISTEN      1999/memcached
tcp        0      0 0.0.0.0:12012               0.0.0.0:*                   LISTEN      2354/memcached
tcp        0      0 0.0.0.0:12013               0.0.0.0:*                   LISTEN      2361/memcached
tcp        0      0 0.0.0.0:12014               0.0.0.0:*                   LISTEN      2369/memcached
tcp        0      0 :::11211                    :::*                        LISTEN      1999/memcached
tcp        0      0 :::12012                    :::*                        LISTEN      2354/memcached
tcp        0      0 :::12013                    :::*                        LISTEN      2361/memcached
tcp        0      0 :::12014                    :::*                        LISTEN      2369/memcached
udp        0      0 0.0.0.0:12012               0.0.0.0:*                               2354/memcached
udp        0      0 0.0.0.0:12013               0.0.0.0:*                               2361/memcached
udp        0      0 0.0.0.0:12014               0.0.0.0:*                               2369/memcached
udp        0      0 0.0.0.0:11211               0.0.0.0:*                               1999/memcached
udp        0      0 :::12012                    :::*                                    2354/memcached
udp        0      0 :::12013                    :::*                                    2361/memcached
udp        0      0 :::12014                    :::*                                    2369/memcached
udp        0      0 :::11211                    :::*                                    1999/memcached


8、Memcached一些特性和限制

在 Memcached 中可以保存的 item 数据量是没有限制的,只要你的内存足够大。
Memcached 单进程最大使用内存为 2G ,要使用更多内存,可以分多个端口开启多个 , Memcached进程:
最大 30 天的数据过期时间 , 设置为永久的也会在这个时间过期,常量 REALTIME_MAXDELTA 60 * 60 *24 *30
最大键长为 250 字节,大于该长度无法存储,常量 KEY_MAX_LENGTH 250
单个 item最大数据是1MB ,超过1MB 数据不予存储,常量 POWER_BLOCK 1048576 进行控制,它是默认的 slab 大小
最大同时连接数是200 ,通过conn_init() 中的freetotal 进行控制,最大软连接数是 1024,通过 settings.maxconns=1024进行
跟空间占用相关的参数: settings.factor=1.25, settings.chunk_size=48, 影响 slab的数据占用和步进方式
关于Memcached的使用,应当在需要的情况下才使用Memcached,比如需要实现分布式缓存系统,否则,如果是类似单台缓存服务器,那么建议最好不要用Memcached,改用其他缓存系统。

以上是我学习memcached整理的文档,希望对大家有帮助。呵呵,不早了,晚安。

本文出自 “放牛娃” 博客,请务必保留此出处http://fangniuwa.blog.51cto.com/10209030/1750720
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: