Memcached那些事

Stella981
• 阅读 759

#Memcached那些事 本文不是为了介绍Memcached是什么,而是讨论在使用Memcached的时候你必须知道的一些事情。以便于方便排查和更好的使用Memcached。本文主要围绕两个方面来讨论这个话题:Memcached的使用和监控。 ##如何更好的使用Memcached 这部分讨论的是如何能够合理有效的让Memcached为我们服务,通过什么方式来调控Memcached,让它工作的更好。下面进入这部分的内容: ###Memcached如何存储我们的数据? 要很好的使用Memcached,那么必须知道我们的数据交给Memcached,它是怎么处理它们的。为了说明这个,需要先了解几个名词:slab class,page,chunk。它们三者之间的关系如下: Memcached那些事

  1. slab class :memcached会自动根据设置的chunk size以及当前分配给memcached创建一系列slab class,单个slab class中的chunk大小是一样的,而每个slab class中的chunk大小根据设置设置的chunk_size*growth_factor^(i-1),其中i表示第几个slab class(这里需要注意这里的chunk_size不只是item的数据大小,还包含memcached内部的一个item结构体大小,这个值一般是48byte,默认的growth_factor是1.25)。
  2. chunk:可以理解为memcached中存储数据的最小单元,每个存储在memcached中的item都会分配一个符合它大小的chunk,chunk的数量决定了memcached存储item的数量,默认的chunk为48byte。
  3. page:memcached中的内存是已page为单位分配给每个slab class,然后每个slab class根据它的chunk大小,计算出各自能够存储的item的数量,默认page大小为1M。而每一页能够存放多少个item,这取决于chunk_size的大小。

通过上面可以看到slab class 1中一个page能够存储的item数量是最多的,而最后一个slab class一个page只能存储一个item。这是由于第一个slab class 1的chunk大小是所有slab class中最小的,那么对于就导致了slab class 1的能够存储的item最多了。

memcached这样做的好处什么呢?memcached这样做将数据存储根据能够存储的大小归为几类,并且内存按照固定的大小来划分。相比于随机分配内存大小,导致内存碎片难于回收来说,这种内存方案对内存的利用率更高,而且便于管理。这就是memcached的slab allocation。

对于memcached来说,如果一个item申请写入数据,会计算当前item的大小然后加上memcached的item结构体大小,判断具体是存储在哪个slab class上面。判断的条件是item_size+item_structure_size<=某个slab class上的chunk大小。以上面的图来说,比如我需要写入一个54byte的数据(key+value),由于memcached的item结构体大小是48,那么memcached对于这个item需要写入的总数据大小是100byte,于是就会写入slab class2的某个chunk里面。于是就会存在下面的情况:

Memcached那些事

由于slab class2的chunk大小是112byte,那么写入100byte数据,就会有12byte空间浪费。这就是下一个话题,如何能够让memcached充分使用内存。 ###让Memcached充分使用内存。 上面列举的例子可以看出如何chunk大小设置不合适会导致内存空间的浪费,如何让memcached合理的使用内存呢?下面将介绍设置哪些参数来达到根据具体的业务合理的使用内存。

  1. 通过上面可以知道,slab class 1中能够存储的item数量是所有slab class中最多的,那么如果能够调整slab class 1的chunk大小,就能够提高memcached存储的数据量,并且对内存的利用率也有很大的提高。可以通过在memcached的启动参数-n来设置的slab class 1的chunk大小。由于后面的slab class都是在这个基础上递增,那么其实的slab class的chunk大小比较重要。比如你发现你们的业务存入memcached都是100byte的大小数据,那么可以将起始slab class的chunk设置为148byte(还要加上48byte的item结构体大小),例如memcached -n 148。这样就可以将数据基本上都会分布在slab class 1上面,而且在每一页上面能够创建的chunk数量也是最大的。
  2. 上面说通过调整slab class 1的chunk大小来提供能够存储的item数量,那么只是对于item大小比较固定的情况。如果对于item大小存在差异的时候呢?那么可以通过设置growth_factor来控制后面的slab class中chunk递增的速度,可以控制slab class中chunk大小变化幅度,来提高memcached的利用率。比如你现在的数据基本上在100-200byte之间,如果让这些数据全部存储在slab class 1那么有些item会只是占用chunk中的一半,这样对内存浪费比较大。所以可以条件growth_factor大小,来控制整个chunk大小在slab class递增的速度。可以通过启动参数-f来指定growth_factor大小,比如memcached -f 1.01 -n 100 (growth_factor值必须大于1)这样可以让memcached在chunk为100的基础上增长速度比较缓慢,能够有多个slab class的chunk大小分布在100-200byte之间。具体设置什么,可以根据你的业务或者一定的公式来获得这个值。
  3. 除了上面几个参数之外,可以调节页面的大小,以及分配给memcached的总内存大小来控制memcached分配内存的策略。通过启动参数-m调节memcached总内存大小,以及-I调节页面的大小。

##监控Memcached 如何监控memcached内存使用情况,以及每个slab classs当前状态这个对优化memcached也是一种重要的手段。memcached自身提供了对它监控的手段,也很简单。可以通过telnet链接到memcached即可查看当前的memcached。下面是在我本机上通过telnet观察memcached的一个实例,下面主要是对返回的几个参数进行说明。

<!--lang:shell-->
dev@codinglife:~$ telnet localhost 11211
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
stats items
STAT items:1:number 64708
STAT items:1:age 32067
STAT items:1:evicted 0
STAT items:1:evicted_nonzero 0
STAT items:1:evicted_time 0
STAT items:1:outofmemory 0
STAT items:1:tailrepairs 0
STAT items:1:reclaimed 32828
STAT items:1:expired_unfetched 29979
STAT items:1:evicted_unfetched 0
END
stats slabs
STAT 1:chunk_size 688
STAT 1:chunks_per_page 1524
STAT 1:total_pages 43
STAT 1:total_chunks 65532
STAT 1:used_chunks 64708
STAT 1:free_chunks 824
STAT 1:free_chunks_end 0
STAT 1:mem_requested 5888428
STAT 1:get_hits 0
STAT 1:cmd_set 101909
STAT 1:delete_hits 0
STAT 1:incr_hits 0
STAT 1:decr_hits 0
STAT 1:cas_hits 0
STAT 1:cas_badval 0
STAT 1:touch_hits 0
STAT active_slabs 1
STAT total_malloced 45086016
END

上面主要执行了两个命令,一个是stats items和stats slabs。stats items是对当前memcached当前存储的item进行一个统计,可以看到item的数量,一些item的一些状态,比如是否有item被移除,是否有超时等,注意上面更在STAT items后面的数字表示是在第几个slab class上,上面表示数据都是在slab class 1上面。而stats slabs是观察各个slab class的情况,比如某个slab class使用了多少page,当前slab class的chunk_size,以及使用了多少个chunk,剩余多少chunk,以及内存的使用情况,同时可以看到整个memcached但钱有多少个slab class处于使用激活状态,以及总共使用了多少内存,重要的是可以看到某个slab class对数据的操作历史累计统计(比如get_hits,cmd_set,delete_hits等等),从而可以看到哪个slab class存储的数据是热点数据,从而可以更具上面的方法调整memcached参数,来提高memcached对内存的使用情况。

上面主要是对memcached使用内存方面调优的参数以及对memcached运行状态的监控进行了讨论,这两者其实是一个相互反馈的过程。通过调整好了memcached相关参数,监控一下memcached运行情况,是否达到预期的效果,从而再对memcached进行调整,再进行监控。只有反复进行调整才能将memcached对内存方面的使用达到最佳的效果。当然可以通过其他参数对memcached进行其他方面的调整,不然能够支持的最大连接数量,处理请求的线程数量等,来提高memcached的整体处理能力。由于不是本文讨论的主题,所以这里就不做过多的描述,具体有哪些参数可以通过memcached -h来获取所有参数列表。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这