柠檬墨绿色 发表于 2016/10/15 13:40

Memcache技术分享:介绍、使用、存储、算法、优化、命中率

1、memcached 介绍
1.1 memcached 是什么?
memcached 是以LiveJournal旗下Danga Interactive 公司的Brad Fitzpatric 为首开发的一款软件。现在已成为mixi、hatena、Facebook、Vox、LiveJournal 等众多服务中提高Web应用扩展性的重要因素。许多Web 应用都将数据保存到RDBMS 中,应用服务器从中读取数据并在浏览器中显示。但随着数据量的增大、访问的集中,就会出现RDBMS 的负担加重、数据库响应恶化、网站显示延迟等重大影响。这时就该memcached 大显身手了。memcached 是高性能的分布式内存缓存服务器。一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web 应用的速度、提高可扩展性。

内置内存存储方式
研究memcached这个产品,首先从它的内存模型开始:我们知道c++里分配内存有两种方式,预先分配和动态分配,显然,预先分配内存会使程序比较快,但是它的缺点是不能有效利用内存,而动态分配可以有效利用内存,但是会使程序运行效率下降,memcached的内存分配就是基于以上原理,显然为了获得更快的速度,有时候我们不得不以空间换时间。
Memcached的高性能源于两阶段哈希(two-stage hash)结构。Memcached就像一个巨大的、存储了很多<key,value>对的哈希表。通过key,可以存储或查询任意的数据。 客户端
可以把数据存储在多台memcached上。当查询数据时,客户端首先参考节点列表计算出key的哈希值(阶段一哈希),进而选中一个节点;客户端将请求发送给选中的节点,然后
memcached节点通过一个内部的哈希算法(阶段二哈希),查找真正的数据(item)并返回给客户端。从实现的角度看,memcached是一个非阻塞的、基于事件的服务器程序。
为了提高性能,memcached 中保存的数据都存储在memcached 内置的内存存储空间中。由于数据仅存在于内存中,因此重启memcached、重启操作系统会导致全部数据消失。另外,内容容量达到指定值之后,就基于LRU(Least Recently Used)算法自动删除不使用的缓存。memcached 本身是为缓存而设计的服务器,因此并没有过多考虑数据的永久性问题
memcached 不互相通信的分布式
memcached 尽管是“分布式”缓存服务器,但服务器端并没有分布式功能。各个
memcached 不会互相通信以共享信息。那么,怎样进行分布式呢?这完全取决于客户端的实现。

2.2 memcached 启动
memcached 启动的命令在安装目录的bin 二级目录下,如/home/test/app/memcahced-1.4.2/bin/memcached -p 11222 -m 128–d
常用的一些启动选项介绍选项说明
-p 侦听的端口,默认为11211
-m 使用内存大小,默认的64m
-d 作为daemon 在后台启动
-vv 用very vrebose 模式启动,调试信息和错误输出到控制台
-l 侦听的地址,默认为所有可以访问的地址
-M 用于在内存溢出的时候,返回一个错误,禁止自动的移出数
据,替代的是返回一个error
-P Pid 文件存在的路径,仅限加上-d 参数是用
-c 最大同时的连接数,默认为1024
其它的一些选项,可以通过–h 命令来进行查看
2.3命令行访问memcached
下面假设memcached 启动时的-p 参数为11311,命令操作在启动memcached
本机首先telnet 连接到memcached 服务器
telnet 127.0.0.1 11311
telnet 成功之后,大概会显示下面的信息
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
各种状态(stats)
STAT <name> <value>\r\n
如:stats命令,则返回以下信息:
stats
STAT pid 26804
STAT uptime 182783
STAT time 1404973716
STAT version 1.4.13
STAT libevent 2.0.11-stable
STAT pointer_size 64
STAT rusage_user 2.320647
STAT rusage_system 5.411177
STAT curr_connections 34
STAT total_connections 558
STAT connection_structures 37
STAT reserved_fds 20
STAT cmd_get 127292
STAT cmd_set 60056
STAT cmd_flush 145
STAT cmd_touch 0
STAT get_hits 83811
STAT get_misses 43481
STAT delete_misses 15970
STAT delete_hits 11992
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 14300156
STAT bytes_written 11507140
STAT limit_maxbytes 134217728      #分配给memcache的内存大小(字节)
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 expired_unfetched 16884
STAT evicted_unfetched 0
STAT bytes 609350    # 当前服务器存储items占用的字节数
STAT curr_items 4668    # 服务器当前存储的items数量
STAT total_items 60056
STAT evictions 0   # 分配给memcache的空间用满后需要删除旧的items数,踢出。
STAT reclaimed 27160#回收再利用,已过期的数据条目来存储新数据。
END
存储命令(set ,add ,replace)
客户端会发送一行像这样的命令:
<command name> <key> <flags> <exptime> <bytes>\r\n
如:
set key1 0 600 5\r\nvalue\r\n
add key2 0 500 2\r\n
replace key1 0 600 6\r\nvalue1\r\n
详细的命令说明,可以见附录的memcached 中英文协议内容
读取命令(get)
命令如下:get <key>*\r\nhttp://www.9ask.cn/suzhou/
- <key>* 表示一个或多个键值,由空格隔开的字串
如:
get key1
VALUE key1 0 7
value12
删除命令(delete)
命令如:delete <key> <time>\r\n
<key> 是客户端希望服务器删除的内容的键名
- <time> 是一个单位为秒的时间(或代表直到某一刻的Unix时间),在该时间内服务器会拒绝对于此键名的“add”和“replace”命令。此时内容被放入delete队列,无法再通过“get”得到该内容,也无法是用“add”和“replace”命令(但是“set”命令可用)。直到指定时间,这些内容被最终从服务器的内存中彻底清除
<time>参数是可选的,缺省为0(表示内容会立刻清除,并且随后的存储命令均可用
如:delete key1
退出命令(quit)
如:quit
4、理解memcached 的内存存储
Memcache内存分配机制
Memcache使用了Slab Allocator的内存分配机制:按照预先规定的大小,将分配的内存分割成特定长度的块,以完全解决内存碎片问题
Memcache的存储涉及到slab,page,chunk三个概念
1.Chunk为固定大小的内存空间,默认为96Byte。
2.page对应实际的物理空间,1个page为1M。
3.同样大小的chunk又称为slab。
4.1Slab Allocation 机制:整理内存以便重复使用
最近的memcached 默认情况下采用了名为Slab Allocator 的机制分配、管理内存。在该机制出现以前,内存的分配是通过对所有记录简单地进行malloc和free 来进行的。但是,这种方式会导致内存碎片,加重操作系统内存管理器的负担,最坏的情况下,会导致操作系统比memcached 进程本身还慢。Slab Allocator 就是为解决该问题而诞生的
Slab Allocation 的原理相当简单。将分配的内存分割成各种尺寸的块
(chunk),并把尺寸相同的块分成组(chunk 的集合)

而且,slab allocator 还有重复使用已分配的内存的目的。也就是说,分配到的内存不会释放,而是重复利用。
Slab Allocation 的主要术语
Page
分配给Slab 的内存空间,默认是1MB。分配给Slab 之后根据slab 的大小切分成chunk。
Chunk
用于缓存记录的内存空间。
Slab Class
特定大小的chunk 的组
4.2 在Slab中缓存记录的原理
memcached 根据收到的数据的大小,选择最适合数据大小的slab,memcached 中保存着slab 内空闲chunk 的列表,根据该列表选择chunk,然
后将数据缓存于其中
页: [1]
查看完整版本: Memcache技术分享:介绍、使用、存储、算法、优化、命中率