Memcached快速入门
1.基本概念
基于高性能的key-value的内存数据库。单进程多线程,协议简单,使用文本行的协议,支持数据类型简单,不支持持久化,轻量级锁CAS机制,集群互不通信,缓存策略(LRU,FIFO,LFU)只支持LRU
2.与redis对比
redis: 线程模型-单进程单线程,QPS/TPS-10w+/10w-,数据支持类型-丰富,持久化-支持, 支持数据备份-支持, 能否集群-能,数据一致性-支持事务, list排序支持-支持, 缓存策略-LRU,FIFO,LFU,jcache支持-支持,单条数据约束-不同数据结构有不同约束
memcached: 线程模型-单进程多线程,QPS/TPS-10w+/10w-,数据支持类型-简单,持久化-不支持,支持数据备份-不支持,能否集群-能,数据一致性-轻量级CAS机制,list排序支持-不支持,缓存策略-LRU, jcache支持-支持,单条数据约束-默认值:key最大长度250字符,value容量<=1M
3.安装及使用
参考:http://www.runoob.com/memcached/memcached-install.html wget http://memcached.org/latest
tar -zxvf memcached-1.x.x.tar.gz
cd memcached-1.x.x
./configure && make && make test && sudo make install 启动:./memcached -p 11211 -d -c 1024 -u root (-p 表示端口,-d 表示后台运行, -u 指定用户)
停止:ps aux|grep memcached 查到进程id,然后 kill -9 pid 客户端:没有专门的客户端,使用telnet ip port 集群:在同一台机器上可以通过指定不同的端口来运行,如
./memcached -p 11211 -d -c 1024 -u root
./memcached -p 11212 -d -c 1024 -u root
./memcached -p 11213 -d -c 1024 -u root 4.memcached客户端使用
1.memcached-java-client
引入pom:
<!-- memcached-java-client -->
<!-- https://mvnrepository.com/artifact/com.whalin/Memcached-Java-Client -->
<dependency>
<groupId>com.whalin</groupId>
<artifactId>Memcached-Java-Client</artifactId>
<version>3.0.2</version>
</dependency> 详见:MemcachedJavaClientTest 2.spymemcached
引入pom:
<!--spymemcached-->
<!-- https://mvnrepository.com/artifact/net.spy/spymemcached -->
<dependency>
<groupId>net.spy</groupId>
<artifactId>spymemcached</artifactId>
<version>2.12.3</version>
</dependency> 详见:MemcachedJavaClientTest 3.xmemcached
引入pom:
<!-- xmemcached -->
<!-- https://mvnrepository.com/artifact/com.googlecode.xmemcached/xmemcached -->
<dependency>
<groupId>com.googlecode.xmemcached</groupId>
<artifactId>xmemcached</artifactId>
<version>2.4.5</version>
</dependency>
详见:MemcachedJavaClientTest 4.springcache与xmemcached 整合
引入pom:
<!-- xmemcached -->
<!-- https://mvnrepository.com/artifact/com.googlecode.xmemcached/xmemcached -->
<dependency>
<groupId>com.googlecode.xmemcached</groupId>
<artifactId>xmemcached</artifactId>
<version>2.4.5</version>
</dependency>
<!-- spring cache 与 xmemcached 整合 采用simple-spring-memcached实现 -->
<dependency>
<groupId>com.google.code.simple-spring-memcached</groupId>
<artifactId>simple-spring-memcached</artifactId>
<version>2.0.0</version>
</dependency>
配置:applicationContext-cache.xml 详见:SpringCacheMemcachedTest
5.原理(重点理解) 5.1.hash算法
memcached单节点是有存储局限的,所以可以使用集群的方式。这里就有分布式存取的问题。不管是写入还是读取,肯定要通过某种算法,这种算法负责定位到某个固定的节点 1.余数分散:m = hash(key) mod n (其中key为传入的数据,n为机器的个数 ,将计算得到的m值 就是对应第几台机器,将key存入改机器中)
优点:算法简单,分散性好
缺点:当新增或者删除机器时,缓存重组的代价很大。当新增或删除机器时,余数会有很大的变化,这样就无法获取与保存时同样的机器,从而导致缓存的命中率很低
代码详见:HashTest 2.一致性hash算法
一致性hash算法就是为了解决余数分散 增加或删除机器时命中率低的问题
步骤:1.构建hash环 2.把数据映射到hash环 3.把机器节点映射到hash环 4.把数据映射到机器节点
优点:解决了余数分散算法增加或删除节点命中率大幅下降的问题
缺点:算法实现比较复杂,需要构建hash环
代码详见:ConsistentHashTest ConsistentHashNodeServiceImpl 3.一致性hash算法 + 虚拟节点
一致性hash算法有个缺点:数据分布不均,有倾斜性,即有些节点存的数据很多,有些则很少。
为了解决这个问题,于是有了增加虚拟节点的方案:
可以在原来缓存的机器的基础上,增加相应的虚拟节点,这样数据就会均匀的打散到其他节点中。这个时候客户端进行数据存取的时候找的就是虚拟节点,而不是真实的物理节点服务器,这样增加节点会删除节点虽然命中率会降低,却很好的解决了数据倾斜问题
代码详见:ConsistentHashTest ConsistentHashNodeServiceImpl2 5.2内存管理策略
Memcached采用Slab Allocator(Slab分配器)进行内存管理
内存被拆分成多个Slab class
每个Slab class 有多个Slab,每个Slab=1M
每个Slab下有多个大小相等的Chunk
不同Slab中的Chunk的大小不一样
数据存储在Chunk中 使用./memcached -p 11211 -d -u root -vv 可以观察内存分配情况
客户端Telnet使用stats slabs查看内存分布情况 增长因子:
启动时指定增长(growth factor)因子(-f 2),就可以在某种程度上控制slab之间的差异,默认值为1.25
如果增加-f 2参数即 ./memcached -p 11211 -f 2 -d -u root -vv 那么表示每一个slab的chunk size 都比上一个slab大了一倍 注意:真实项目中,要均衡数据的大小,如果数据之间大小差别不大建议增长因子设置比较小,而数据之间大小悬殊,数据的增长因子可以考虑增大 5.3缓存过期策略
MC不会主动删除过期数据,而是采用lazy策略
Memcached不会释放已分配的内存,其存储空间可以重复使用
Memcached内部不会监视数据是否过期,而是在get时查看数据的时间戳,查看数据是否过期。被称为lazy expiration(惰性过期)
Memcached内存空间不足,即无法从slab class中获取到新的空间时,就从最近未被使用的数据中搜索,将其空间分配给新的数据。(如果要禁用LRU,使用-M参数,超出会报错) 6.问题 1.什么是一致性hash,他和普通hash有什么不同(hash环,虚拟节点干什么的)?
一致性hash是为了解决普通hash算法(余数分散算法)因增加或删除节点导致命中率大幅下降的问题 而产生的
与普通hash不同点:
1.构建hash环 2.将数据映射到hash环上 3.将节点映射到hash环上 4.将数据映射到节点上
虚拟节点:是为了解决一致性hash中节点个数少导致数据分布不均问题而产生的,通过增加虚拟节点,可以使得数据均匀的打散到其他节点。
2.一致性hash在上面情况下使用,单节点情况下用一致性hash是否合适?
单节点不适用,因为使用一致性hash算法性能比较低,单节点使用普通的hash算法就行了
3.slab内存模型是什么样的,对于增长因子来说,他对性能有什么影响?
slab内存模型:
内存被拆分成多个slab class
每个slab class 有多个slab,每个slab=1M
每个slab下有多个大小相等的chunk
不同slab中chunk大小不一样
数据存储在chunk中 增长因子:
用于控制slab之间的差异。默认是1.25,可以根据实际情况,设置增长因子(在启动memcached时加参数 -f 设置)
如果数据之间的大小差别不大,就设置小点,如果大小差别很大,就可以设置大点 4.增长因子对性能影响:
如果数据间隔小,而设置很大的话,就浪费空间。
如果数据间隔大,而设置很小的话,那就存不了数据,也是浪费空间
如果增长因子设置过大,代表的每个slab里面chunk大小跨度很大。 但数据却很小,经常导致只有一部分chunk被使用 而且经常导致内存的清理,导致性能降低,如果数据跨度不大,可以考虑把增长因子设置得小一点的 5.一致性hash环的大小为什么是2^32
因为,java中int的最大值是2^31-1最小值是-2^31,2^32刚好是无符号整形的最大值;
为什么java中int的最大值是2^31-1最小值是-2^31
int的最大值最小值范围设定是因为一个int占4个字节,一个字节占8位,二进制中刚好是32位
hash环:
把二的三十二次方想象成一个圆,圆环的正上方的点代表0,0点右侧的第一个点代表1,以此类推,2、3、4、5、6……直到2^32-1,也就是说0点左侧的第一个点代表2^32-1,我们把这个由2的32次方个点组成的圆环称为hash环 6.如果服务器计算出的hash值相同,那么数据不是被放在相同的服务器上了吗?
这个问题其实就是hash 碰撞,而在一致性hash里面hash碰撞的几率不大,理论上有hash碰撞的可能性,任何hash的有可能。
就像md5值,如果数据量足够大,足够长,算出的md5理论上可能重复,但并不影响它使用。 这是种出现概率极低的情况
7.每个slab大小是1M,为什么slab class有39个?
slab class有39个 只是显示它会这么分配,这个是由增长因子确定,但并没真的这么分配。具体的分配你应该在服务器运行的时候基于指定的内存分配,可以stats slabs命令查看 8.一致性hash算法应用场景:
memcached的客户端,redis中的hash slot(hash槽),nginx的负载均衡
hash一致性算法是为了在分布式环境下 动态增加或删除节点 而尽量减少对数据存取的影响即命中率低的问题 而产生,具体的算法在不同的应用场景中不太一样 9.缓存过期策略
FIFO(First In First Out):先见先出,淘汰最先近来的页面,新进来的页面最迟被淘汰,完全符合队列
LRU(least recently used):最近最少使用,淘汰最近不使用的页面
LFU(least frequently used):使用次数最少, 淘汰使用次数最少的页面
memcached 采用的是LRU
Memcached快速入门的更多相关文章
- Memcached 快速入门
Memcached简介 Memcached是一个专门用来做缓存的服务器,而且缓存的数据都在内存中.Memcached就相当于一个Dictionary键值对集合,保存的是键值对,然后根据key取valu ...
- 分布式缓存系统 Memcached 快速入门
Memcached介绍 官网地址 Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提 ...
- [你必须知道的NOSQL系列]专题二:Redis快速入门
一.前言 在前一篇博文介绍了MongoDB基本操作,本来打算这篇博文继续介绍MongoDB的相关内容的,例如索引,主从备份等内容的,但是发现这些内容都可以通过官方文档都可以看到,并且都非常详细,所以这 ...
- Redis快速入门:安装、配置和操作
本文是有关Redis的系列技术文章之一.在之前的文章中介绍了<Redis快速入门:初识Redis>,对Redis有了一个初步的了解.今天继续为大家介绍Redis如何安装.配置和操作. 系列 ...
- 二:Redis快速入门及应用
Redis的使用难吗?不难,Redis用好容易吗?不容易.Redis的使用虽然不难,但与业务结合的应用场景特别多.特别紧,用好并不容易.我们希望通过一篇文章及Demo,即可轻松.快速入门并学会应用. ...
- kolla-ansible快速入门
kolla-ansible快速入门 kolla-ansible是一个结构相对简单的项目,它通过一个shell脚本,根据用户的参数,选择不同的playbook和不同的参数调用ansible-playbo ...
- Redis快速入门及应用
Redis的使用难吗?不难,Redis用好容易吗?不容易.Redis的使用虽然不难,但与业务结合的应用场景特别多.特别紧,用好并不容易.我们希望通过一篇文章及Demo,即可轻松.快速入门并学会应用.一 ...
- 中小型研发团队架构实践五:Redis快速入门及应用
Redis的使用难吗?不难,Redis用好容易吗?不容易.Redis的使用虽然不难,但与业务结合的应用场景特别多.特别紧,用好并不容易.我们希望通过一篇文章及Demo,即可轻松.快速入门并学会应用. ...
- 中小型研发团队架构实践:Redis快速入门及应用
Redis的使用难吗?不难,Redis用好容易吗?不容易.Redis的使用虽然不难,但与业务结合的应用场景特别多.特别紧,用好并不容易.我们希望通过一篇文章及Demo,即可轻松.快速入门并学会应用. ...
随机推荐
- vscode开发ExtJs安装插件以及破解方法
https://blog.csdn.net/lovelyelfpop/article/details/69568995 1.官网下载vscode 插件. https://www.sencha.com/ ...
- spring 给容器中注册组件的几种方式
1.@Bean 导入第三方的类或包的组件 2.包扫描+组件的标注注解(@ComponentScan: @Controller,@service,@Reponsitory,@Componet), 自己写 ...
- Leetcode之广度优先搜索(BFS)专题-279. 完全平方数(Perfect Squares)
Leetcode之广度优先搜索(BFS)专题-279. 完全平方数(Perfect Squares) BFS入门详解:Leetcode之广度优先搜索(BFS)专题-429. N叉树的层序遍历(N-ar ...
- win7中文版 切换成 英文版
打开[控制面版]-->[更改显示语言] 2.点击[安装/卸载语言] 3.启用Windows Update 4.更新完后,打开可选更新,拉到底,选上 英语语言包 同时记得取消所有重要更新的,再 ...
- kindeditor-4.1.7
<script src="~/Scripts/jquery-1.10.2.min.js" type="text/javascript"></s ...
- SolidWorks学习笔记2草图
几何约束 显示和隐藏约束 单个直线的约束 绘制一个直线,点击左侧的中的水平或者竖直,, 如果要删除改约束,右键绿色的小矩形,相关被约束的对象变成分红,点击删除即可. 两个对象之间的约束 点击一个对象, ...
- ssh远程连接的故障排查详解
排查故障: 1.两个机器之间是否通畅,看物理网络(网线网卡,IP是不是正确) ping ip -t 来检测物理网络是否通畅 通 不通 不通: 1.客户端到服务器端物理链路有问题 网卡 ,IP , 网 ...
- mysql一个SQL案例
需求 : 测试数据 ),start1 int,end1 int); ,); ,); ,); ,); ,); ,); 解决: 解决2: 解决代码 核心思想,把符合逻辑条件的行,构造相同分组 select ...
- 小记--------spark-Wordcount经典案例之对结果根据词频进行倒序排序
还是以经典案例Wordcount为例: 逻辑思路: 1.先把文本按空格切分成每个单词 flatMap() 2.将每个单词都转换成Tuple2类型(hello ,1) map() 3.将 ...
- JsonObject、JsonArray操作json的个人总结
介绍 JsonObject.JsonArray之前,先介绍下JsonConfig JsonConfig: setClassMap(Map classMap)设置json属性类型,上json里的其中值为 ...