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,即可轻松.快速入门并学会应用. ...
随机推荐
- 解决 Elasticsearch 超过 10000 条无法查询的问题
解决 Elasticsearch 超过 10000 条无法查询的问题 问题描述 分页查询场景,当查询记录数超过 10000 条时,会报错. 使用 Kibana 的 Dev Tools 工具查询 从第 ...
- mpVue学习笔记整理
第一章: mpVue(Vue in Mini Program) 1.1 简介 美团工程师推出的基于Vue.js封装的用于开发小程序的框架 融合了原生小程序和Vue.js的特点 可完全组件化开发 1.2 ...
- HTTP 请求中的 Form Data 与 Request Payload 的区别
HTTP 请求中的 Form Data 与 Request Payload 的区别 前端开发中经常会用到 AJAX 发送异步请求,对于 POST 类型的请求会附带请求数据.而常用的两种传参方式为:Fo ...
- C#与Unity 数据存储
使用Json存储数据 1.创建Json文件,直接创建txt文件,将后缀名改为xx.json 2.Json文件的数据格式,中括号表示列表,即中括号下的每个逗号隔开的内容都是列表的每个元素,花括号表示对象 ...
- 用户及用户组管理(week1_day4)
本节内容 useradd userdel usermod groupadd groupdel 用户管理 为什么需要有用户? 1. linux是一个多用户系统 2. 权限管理(权限最 ...
- 【神经网络与深度学习】YOLO windows 配置《Darknet配置》
作者配置时的环境 visual studio 2013 显卡 GTX 960M CUDA 7.5 OpenCV 2.4.9 pthreadpthread 下载地址 YOLO官网 [http:// ...
- amh 操作
挂在分区到/home 迁移数据库/usr/local/mysql/data 到/home/data目录 504 卡死 进入kangle后台,选扩展,再选中扩展里的命令选项,修改PHP-NTS的协议为f ...
- (转)python基础学习-----生成器和迭代器
在Python中,很多对象都是可以通过for语句来直接遍历的,例如list.string.dict等等,这些对象都可以被称为可迭代对象.至于说哪些对象是可以被迭代访问的,就要了解一下迭代器相关的知识了 ...
- mongodb 数据操作(1)
切换/创建数据库 use test 添加数据db.student.save({name:"J33ack",age:25}) 查看数据库show dbs 删除当前数据库 db.dro ...
- 使用antd List组件实现轮播图
import { List, Avatar, Carousel } from 'antd'; import { connect } from 'dva'; import './lamp.less' c ...