安装
1.服务器端安装(用于数据存储)memcached
2.客户端安装(作为扩展添加到某一开发环境)memcache
定义
高性能分布式内存缓存系统。通过缓存数据库的查询结果降低数据库的访问压力,提高动态web应用的稳定性和可扩展性。
实质:存储键值对的hashmap。
高性能来源:1k-v存储 o(1);2一致性hash实现分布式;3支持并发访问
工作流程
1.先检查客户端请求数据在不在m中;
2.若不在,查询数据库,同时将数据缓存到m中(需要程序实现);
3.每次更新数据库的同时更新m中数据;
4.分配给m的内存空间用完后,使用LRU(最近最少算法)+到期失效策略,先用后者。
缓存命令
set add(不能添加已经存在的键名) get replace delete(m提供的一些方法)
应用场景
1.完整数据缓存 如电商商品分类功能
2.热点数据缓存
优点
1.部分容灾
假设只用一台memcache,如果这台memcache服务器挂掉了,那么请求将不断的冲击数据库,这样有可能搞死数据库,从而引发”雪崩“。
如果使用多台memcache服务器,由于memcache使用一致性哈希算法,万一其中一台挂掉了,部分请求还是可以在memcache中命中,为修复系统赢得一些时间。
2.容量问题
一台memcache服务器的容量毕竟有限,可以使用多台memcache服务器,增加缓存容量。
3. 均衡请求
使用多台memcache服务器,可以均衡请求,避免所有请求都冲进一台memcache服务器,导致服务器挂掉。
4.利用memcache分布式特性
使用一台memcache服务器,并没有利用memcache的数据分布式特性。
缺点
1.不能持久化存储
2.存储数据有限制:1M 【大于1M,认为就行分割】(内存碎片)
3.存储数据只能key-value
4.集群数据没有复制和同步机制 【崩溃不会影响程序,会从数据库中取数据
内存管理机制
前言:高效的内存管理方案不会直接使用malloc free调用,容易造成内存泄漏,频繁调用会产生内存碎片。
Mencached:拿空间换时间,因为是预先分配内存,而不是动态分配。
Slab allocation机制管理内存,将分配的内存分割成特定的长度的块以存储相应长度的key-value数据记录。Chunk是存储数据的最小单位。
分配流程:判断数据大小>>查看空闲chunk列表,找到可以存下数据的列表
缺点:会导致空间浪费,因为每个chunk都分配了特定长度的内存空间,无法充分利用。
Memcached集群实现机制(只能通过客户端实现分布式存储)
在客户端通过一致性哈希算法实现分布式存储。客户端发送数据之前,首先根据算法计算数据的目标节点,然后数据被发送到相应的节点保存;
当需要读取数据时,先查询出数据所在的节点,然后向节点发送查询请求以获取数据。
与Redis对比
1.性能
Redis使用单线程的IO复用模型。由于Redis只使用单核,而Memcached可以使用多核,所以在比较上,平均每一个核上Redis在存储小数据时比Memcached性能更高。
而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。
2.数据一致性
M:保证多个并发访问,乐观锁;R:单线程,事务功能,数据可按顺序提交
3.可靠性
R:数据备份,Master-slave主从复制,数据缓存具有持久性
4.分布式存储
R:m-s主从复制 M:一致性hash
5.数据支持类型
R:支持除K-V之外的更多类型
一致性Hash算法
存在问题:普通取模方法,当机器节点进行增减时,数据缓存命不中,缓存要重新建立甚至数据整体迁移。
目的:key的分布均衡+cache的迁移做到最少。当一个节点失效的时候,其他节点数据不会受到破坏,这个节点的数据被分流到另一个节点。
解决方法:
环形hash空间>把对象映射到hash空间>把cache映射到hash空间>把对象映射到cache(顺时针移动)>考虑cache的变动(需要移动的对象相对较少)
Hash算法的平衡性改进—虚拟节点
目的:使得哈希的结果尽可能分布到所有的缓冲中去。
LRU删除机制详解
-
数据过期时,m不会从内存中删除数据,get数据时检查时间戳是否过期,如果过期,客户端就不可见。
-
每个slab数据存放在链表上,head最老 tail最新数据,lru机制启动,首先检查失效数据,若没有,就删除最近最少使用的数据。只有在slab不能分配新的page页才会调用lru。
https://blog.csdn.net/huithe/article/details/8006186源码分析(还没看)