Memcached深入剖析

简介:

Memcached基础


What is Memcached ?


Free & open source, high-performance, distributed memory object caching system


一个开源,免费的高性能,分布式内存缓存系统。


在我们的应用程序中,一般会将数据库的一些经常需要查询用到的数据缓存至Memcached,以提高动态Web应用的响应速度。如下图所示:


wKiom1SmQaGTfoRKAAE4oHmqY6s517.jpg



快速体验Memcached


由于Memcached使用到了基于libevent的事件处理机制,因此安装之前需要确保已经安装libevent库。由于我用的是最新稳定版1.4.22(下载网址:http://memcached.org/),对libevent的版本还有要求,如果版本过低,还不能启动Memcached,可以到http://libevent.org/ 下载较新的libevent版本使用。


【关于libevent的简要说明:libevent就是一个程序库,他将Linux的epoll、BSD系统的kqueue等事件处理机制封装成统一的接口,即使对服务器的连接增加,也能发挥0(1)的性能。Memcached使用这个库,可以在Linux平台上发挥其高性能。】


过程如下:

1
2
3
4
5
6
7
8
9
tar  -xf libevent-2.0.20-stable. tar .gz
cd  libevent-2.0.20-stable
. /configure  --prefix= /usr/local/libevent
make
make  install
tar  -xf memcached-1.4.22. tar .gz
cd  memcached-1.4.22
. /configure  --prefix= /usr/local/memached  --with-libevent= /usr/local/libevent/
make  &&  make  install


启动Memcached

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[root@www bin] # ./memcached -p 11211 -m 64 -f 1.5 -u nobody -vvv -d
slab class   1: chunk size        80 perslab   13107
slab class   2: chunk size       120 perslab    8738
slab class   3: chunk size       184 perslab    5698
slab class   4: chunk size       280 perslab    3744
slab class   5: chunk size       424 perslab    2473
slab class   6: chunk size       640 perslab    1638
slab class   7: chunk size       960 perslab    1092
slab class   8: chunk size      1440 perslab     728
slab class   9: chunk size      2160 perslab     485
slab class  10: chunk size      3240 perslab     323
slab class  11: chunk size      4864 perslab     215
slab class  12: chunk size      7296 perslab     143
slab class  13: chunk size     10944 perslab      95
slab class  14: chunk size     16416 perslab      63
slab class  15: chunk size     24624 perslab      42
slab class  16: chunk size     36936 perslab      28
slab class  17: chunk size     55408 perslab      18
slab class  18: chunk size     83112 perslab      12
slab class  19: chunk size    124672 perslab       8
slab class  20: chunk size    187008 perslab       5
slab class  21: chunk size    280512 perslab       3
slab class  22: chunk size    420768 perslab       2
slab class  23: chunk size    631152 perslab       1
slab class  24: chunk size   1048576 perslab       1


可以利用./memcached -h的方式来了解一些选项的作用:


-p <num>      TCP port number to listen on (default: 11211)  指定端口


-l <addr>     interface to listen on (default: INADDR_ANY, all addresses)

监听地址,想一想,如果我们的机器上有多个网卡我们监听在哪个网卡上呢?


-d            run as a daemon  表示以一个后台服务的方式运行


-u <username> assume identity of <username> (only when run as root)  

以哪个用户的身份运行


-m <num>      max memory to use for items in megabytes (default: 64 MB) 

以M为单位指定最大的内存空间


-f <factor>   chunk size growth factor (default: 1.25)  

指定增长因子


-n <bytes>    minimum space allocated for key+value+flags (default: 48)  

最小存储单位。实际上,这里指定的是最小的slab chunk大小


在上面启动过程中,我们使用了-vvv的方式输出了启动过程的详细信息,那么slab class , chunk这些是什么呢?增长因子又是干什么的?


端口验证:

1
2
3
[root@www ~] # netstat -tnlp | grep 11211
tcp        0      0 0.0.0.0:11211         0.0.0.0:*    LISTEN      3292 /memcached      
tcp        0      0 :::11211              :::*         LISTEN      3292 /memcached


Memcached启动后,我们怎么连接进行操作呢?


要知道Memcached是基于Client/Server架构的,上面的是启动Server端,表示Memcached已经有64M内存空间来进行缓存数据管理。至于设置哪些缓存数据,数据有效期是多少等这些都是客户端的事情。很多语言都实现了Memcached客户端,比如Java/PHP等。需要注意的是,Memcached的一个重要特征--协议简单。比如,我们就可以使用telnet来操作Memcached:

1
2
3
4
5
[root@www ~] # telnet 192.168.204.88 11211
Trying 192.168.204.88...
Connected to www.zfz2.com (192.168.204.88).
Escape character is  '^]' .
stats

stats命令可以获取到Memcached运行时相关信息。




一些常用命令:


add命令  添加新键

add keyname flag timeout datasize

1
2
3
add name 0 30 5
hello
STORED


get命令  取得键值

get keyname

1
2
3
4
get name
VALUE name 0 5
hello
END


set 无条件设置一个键

说白了,就是有键则覆盖,无键则添加。

set keyname flag timeout datasize



replace 替换已经存在的KEY

replace keyname flag timeout datasize



append keyname flag timeout append_datasize

prepend keyname flag timeout prepend_datasize

1
2
3
4
5
6
7
8
9
10
11
12
13
14
add name 0 60 5
hello
STORED
get name
VALUE name 0 5
hello
END
append name 0 60 2
aa
STORED
get name
VALUE name 0 7
helloaa
END


incr keyname increments  对键值增长

decr keyname decrements  对键值减少

1
2
3
4
5
6
7
8
add score 0 120 1
1
STORED
incr score 2
3
get score
VALUE score 0 1
3


delete keyname  删除指定键

flush_all       清理所有键

stats           状态信息

quit            表示退出

version         查看版本



Memcached的内存存储和删除机制


Memcached是一个缓存服务器,并且它认为自己缓存的数据并不是关键性数据,也就是如果Memcached重启,缓存数据会丢失,需要重新建立。Memcached对高可用的支持不是很好,但是对分布式提供了很好的支持。下面我们来分析下Memcached的内存存储机制:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[root@www bin] # ./memcached -p 11211 -m 64 -f 1.5 -u nobody -vvv -d
slab class   1: chunk size        80 perslab   13107
slab class   2: chunk size       120 perslab    8738
slab class   3: chunk size       184 perslab    5698
slab class   4: chunk size       280 perslab    3744
slab class   5: chunk size       424 perslab    2473
slab class   6: chunk size       640 perslab    1638
slab class   7: chunk size       960 perslab    1092
slab class   8: chunk size      1440 perslab     728
slab class   9: chunk size      2160 perslab     485
slab class  10: chunk size      3240 perslab     323
slab class  11: chunk size      4864 perslab     215
slab class  12: chunk size      7296 perslab     143
slab class  13: chunk size     10944 perslab      95
slab class  14: chunk size     16416 perslab      63
slab class  15: chunk size     24624 perslab      42
slab class  16: chunk size     36936 perslab      28
slab class  17: chunk size     55408 perslab      18
slab class  18: chunk size     83112 perslab      12
slab class  19: chunk size    124672 perslab       8
slab class  20: chunk size    187008 perslab       5
slab class  21: chunk size    280512 perslab       3
slab class  22: chunk size    420768 perslab       2
slab class  23: chunk size    631152 perslab       1
slab class  24: chunk size   1048576 perslab       1

Memcached的内存存储机制采用了Slab Allocator的方式,按照预先规定的大小,将分配的内存分割成特定长度的块,以减少内存碎片问题。Slab Allocator可以重复使用以分配的内存。如下图所示:


wKioL1SnTinAkEbvAAFO-dwM2f8650.jpg

有多个Slab Class类别,每一个Slab Class里面有多个相同大小的Chunk,而Chunk就是Memcached存储数据的最小单元。当Memcached接受到数据需要缓存时,会选择最适合数据大小的Slab,然后从Slab中选择空闲的Chunk进行存储。当然这种方式是无法避免内存浪费的。


在启动Memcached时,我们指定了-f选项,其实是在指定Slab中Chunk大小的增长因子,这是Memcached为我们提供的一个可以进行调优的选项。我们可以根据客户端缓存数据的大小,做一个预估,通过增长因子来调整Slab的差别,以获得最恰当的设置。


在Memcached中缓存数据的时候,我们可以指定数据的失效期,可以指定到秒。那么如果时间到了,Memcached会怎么做呢?


Memcached并不会释放已经分配的内存,超时后,客户端就无法在看到该记录了。Memcached的删除机制思想如下:


LAZY机制

Memcached内部不会去监控记录是否过期,而是在get的时候去判断一下时间戳,这样就知道是不是过期了。这样的话,Memcached因为LAZY的机制不会在这个方面去占用CPU。


LRU算法

最近最少使用原理,当Memcached空间不足时,要清理,怎么清理呢?就是清理那些最近未被使用的记录的空间,将这些空间重新分配给新的记录。





Memcached的分布式机制与一致性哈希算法


当我们使用多台Memcached来缓存数据时,就利用到了Memcached的分布式。Memcached的分布式的最大特点是不相互通信。在分布式的情况下,当我们要保存一个键时,可以简单的根据键计算一个值,从而决定存储至哪个Memcached中,当要get这个键的时候,利用同样的方式到对应的Memcached服务器中去取。比如,我们有10台Memcached(编号0-9),现在要保存一个key,通过对key进行计算,比如取得它的HASH值,然后对10取余,假设得到8,我们就将这个KEY存储至编号为8的服务器中。这样的话,虽然算法上简单,存取上实现了分布式,但是有一个明显的缺点,就是如果增加或者减少了Memcached的节点个数,我们的大部分缓存就失效了,需要重新建立了。【原因在于取余的结果发生了巨变】那么有没有一种方式,当我们增加或者减少Memcached节点个数时,带来的影响最小呢?


关于一致性HASH算法(Consistent Hashing)


wKiom1SnVK6A-pyRAAFR1OdEa2U133.jpg



基本原理说明:


有一个HASH环,分布着2的32次方个点,然后求出各个Memcached服务器的HASH值,将其置于环上的各个点上。用相同的方式计算需要保存的数据的键的HASH值,并映射到环上的位置,从映射处开始顺时针开始查找最近的Memcached,找到后就保存至这个服务器。如果要取得数据,也采用相同的方式定位服务器。


这种算法就是一致性HASH算法,通过这样可以在添加、删除服务器时,最大限度的抑制键的重新分布。


本文转自zfz_linux_boy 51CTO博客,原文链接:http://blog.51cto.com/zhangfengzhe/1598626,如需转载请自行联系原作者


相关文章
|
PHP
php-fpm的重启方法
php-fpm的重启方法
1740 0
|
机器学习/深度学习 人工智能 算法
【AI系统】AI系统概述与设计目标
本文介绍了AI系统的全栈架构,涵盖设计目标、组成和生态。AI系统旨在连接硬件与应用,提供高效的模型服务和开发支持。文中探讨了高效编程语言、开发框架、工具链的重要性,以及AI任务系统级支持、自动编译优化和云原生自动分布式化等关键设计目标。此外,还详细讨论了AI训练与推理框架、AI编译与计算架构、AI硬件与体系结构等组成部分,以及AI算法和框架、更广泛的生态系统等。
646 1
|
存储 JavaScript 前端开发
学习vuex和localstorage . cookie的作用与区别
探讨Vuex、LocalStorage与Cookie:三种关键技术在现代Web开发中的角色。Vuex作为Vue的状态管理工具,提供集中、响应式且可预测的状态变更机制,适用于复杂应用。LocalStorage为客户端提供大容量、持久化的数据存储方案,适合保存用户偏好等静态信息。Cookie则擅长会话跟踪与认证管理,数据虽小却能在客户端与服务器间传递。每种技术针对不同场景各有优势,合理选用是关键。
|
设计模式 Java Android开发
安卓应用开发中的内存泄漏检测与修复
【9月更文挑战第30天】在安卓应用开发过程中,内存泄漏是一个常见而又棘手的问题。它不仅会导致应用运行缓慢,还可能引发应用崩溃,严重影响用户体验。本文将深入探讨如何检测和修复内存泄漏,以提升应用性能和稳定性。我们将通过一个具体的代码示例,展示如何使用Android Studio的Memory Profiler工具来定位内存泄漏,并介绍几种常见的内存泄漏场景及其解决方案。无论你是初学者还是有经验的开发者,这篇文章都将为你提供实用的技巧和方法,帮助你打造更优质的安卓应用。
|
设计模式 自然语言处理 Java
递归下降解析器的设计与实现
递归下降解析器的设计与实现
|
存储 缓存 算法
优化 ChunkServer 的存储性能
【8月更文第30天】在分布式文件系统中,ChunkServer 是负责存储数据块的关键组件。为了提高ChunkServer的存储性能,可以通过多种技术手段进行优化,如缓存、压缩、并行处理等。本文将详细讨论这些技术的应用,并提供具体的代码示例。
191 0
|
关系型数据库 MySQL 数据库
|
存储 安全 定位技术
云计算中的数据备份与恢复策略:确保数据安全与业务连续性的关键
【7月更文挑战第1天】本文探讨了云计算中数据备份与恢复策略的关键性,强调了它们在保障数据安全和业务连续性中的作用。备份策略的重要性包括防止数据丢失、满足合规要求和提升效率。核心原理涉及冗余存储、数据压缩加密、分片与分散存储及增量备份。实施步骤涵盖制定备份和恢复计划、选择工具、执行操作及测试恢复能力。未来趋势将向智能化、分布式存储、增强安全性及高效恢复发展。构建这样的体系对确保企业业务稳定至关重要。
|
XML Java 数据格式
Spring IOC—基于XML配置和管理Bean 万字详解(通俗易懂)
Spring 第二节 IOC—基于XML配置和管理Bean 万字详解!。
1133 5