简述memcached的工作原理
1 NoSQL介绍
NoSQL是对 Not Only SQL、非传统关系型数据库的统称。
NoSQL的分类:
- Key-value Store k/v数据库
- 性能好 O(1) , 如redis、memcached
- Document Store 文档数据库
- Column Store 列存数据库,Column-Oriented DB
- HBase、Cassandra,大数据领域应用广泛
- Graph DB 图数据库
- Time Series 时序数据库
2 Memcached
Memcached 只支持能序列化的数据类型,不支持持久化,基于Key-Value的内存缓存系统
memcached 虽然没有像redis所具备的数据持久化功能,比如RDB和AOF都没有,但是可以通过做集群同步的方式,让各memcached服务器的数据进行同步,从而实现数据的一致性,即保证各memcached的数据是一样的,即使有任何一台 memcached 发生故障,只要集群中有一台 memcached 可用就不会出现数据丢失,当其他memcached 重新加入到集群的时候,可以自动从有数据的memcached 当中自动获取数据并提供服务。
Memcached 借助了操作系统的 libevent 工具做高效的读写。libevent是个程序库,它将Linux的epoll、BSD类操作系统的kqueue等事件处理功能封装成统一的接口。即使对服务器的连接数增加,也能发挥高性能。memcached使用这个libevent库,因此能在Linux、BSD、Solaris等操作系统上发挥其高性能
Memcached 支持最大的内存存储对象为1M,超过1M的数据可以使用客户端压缩或拆分报包放到多个key中,比较大的数据在进行读取的时候需要消耗的时间比较长,memcached 最适合保存用户的session实现session共享
Memcached存储数据时, Memcached会去申请1MB的内存,把该块内存称为一个slab,也称为一个page Memcached 支持多种开发语言,包括:JAVA,C,Python,PHP,C#,Ruby,Perl等
3 Memcached 和 Redis 比较
比较类别 | Redis | Memcached |
---|
支持的数据结构 | 哈希、列表、集合、有序集合 | 纯kev-value | 持久化支持 | 有 | 无 | 高可用支持 | redis支持集群功能,可以实现主动复制,读写分离。官方也提供了sentinel集群管理工具,能够实现主从服务监控,故障自动转移,这一切,对于客户端都是透明的,无需程序改动,也无需人工介入 | 需要二次开发 | 存储value容量 | 最大512M | 最大1M | 内存分配 | 临时申请空间,可能导致碎片 | 预分配内存池的方式管理内存,能够省去内存分配时间 | 虚拟内存使用 | 有自己的VM机制,理论上能够存储比物理内存更多的数据,当数据超量时,会引发swap,把冷数据刷到磁盘上 | 所有的数据存储在物理内存里 | 网络模型 | 非阻塞IO复用模型,提供一些非KV存储之外的排序,聚合功能,在执行这些功能时,复杂的CPU计算,会阻塞整个IO调度 | 非阻塞IO复用模型 | 水平扩展的支持 | redis cluster 可以横向扩展 | 暂无 | 多线程 | Redis6.0之前是只支持单线程 | Memcached支持多线程,CPU利用方面Memcache优于Redis | 过期策略 | 有专门线程,清除缓存数据 | 懒淘汰机制:每次往缓存放入数据的时候,都会存一个时间,在读取的时候要和设置的时间做TTL比较来判断是否过期 | 单机QPS | 约10W | 约60W | 源代码可读性 | 代码清爽简洁 | 可能是考虑了太多的扩展性,多系统的兼容性,代码不清爽 | 适用场景 | 复杂数据结构、有持久化、高可用需求、value存储内容较大 | 纯KV,数据量非常大,并发量非常大的业务 |
4 Memcache与Redis的区别
- 存储方式 Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。 Redis有部份存在硬盘上,redis可以持久化其数据
- 数据支持类型 memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型,提供list,set,zset,hash等数据结构的存储
- 使用底层模型不同 它们之间底层实现方式 以及与客户端之间通信的应用协议不一样。 Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。
- value 值大小不同:Redis 最大可以达到 512M;memcache 只有 1M。
- redis的速度比memcached快很多
- Redis支持数据的备份,即master-slave模式的数据备份。
5 Memcached 工作机制
5.1 内存分配机制
应用程序运行需要使用内存存储数据,但对于一个缓存系统来说,申请内存、释放内存将十分频繁,非常容易导致大量内存碎片,最后导致无连续可用内存可用。
Memcached采用了Slab Allocator机制来分配、管理内存。
- Page:分配给Slab的内存空间,默认为1MB,分配后就得到一个Slab。Slab分配之后内存按照固定字节大小等分成chunk。
- Chunk:用于缓存记录k/v值的内存空间。Memcached会根据数据大小选择存到哪一个chunk中,假设chunk有128bytes、64bytes等多种,数据只有100bytes存储在128bytes中,存在少许浪费。
- Chunk最大就是Page的大小,即一个Page中就一个Chunk
- Slab Class:Slab按照Chunk的大小分组,就组成不同的Slab Class,第一个Chunk大小为 96B的Slab为Class1,Chunk 120B为Class 2,如果有100bytes要存,那么Memcached会选择SlabClass 2 存储,因为它是120bytes的Chunk。Slab之间的差异可以使用Growth Factor 控制,默认1.25。
5.2 懒过期 Lazy Expiration
memcached不会监视数据是否过期,而是在取数据时才看是否过期,如果过期,把数据有效期限标识为0,并不清除该数据。以后可以覆盖该位置存储其它数据。
5.3 LRU
当内存不足时,memcached会使用LRU(Least Recently Used)机制来查找可用空间,分配给新记录使用。
5.4 集群
Memcached集群,称为基于客户端的分布式集群,即由客户端实现集群功能,即Memcached本身不支持集群
Memcached集群内部并不互相通信,一切都需要客户端连接到Memcached服务器后自行组织这些节点,并决定数据存储的节点。
6 memcache 服务特点
- 完全基于内存缓存的
- 节点之间相互独立
- C/S模式架构,C语言编写,总共2000行代码。
- 异步I/O 模型,使用libevent作为事件通知机制。
- 被缓存的数据以key/value键值对形式存在的。
- 全部数据存放于内存中,无持久性存储的设计,重启服务器,内存里的数据会丢失。
- 当内存中缓存的数据容量达到启动时设定的内存值时,就自动使用LRU算法删除过期的缓存数据。
- 可以对存储的数据设置过期时间,这样过期后的数据自动被清除,服务本身不会监控过期,而是在访问的时候查看key的时间戳,判断是否过期。
- memcache会对设定的内存进行分块,再把块分组,然后再提供服务
7 memcache的工作原理
memcache是以key-value形式存储的,key会通过一个hash表转换成hash的key,便于查找对比。客户端通过key的hash值确定数据的位置,然后向服务端发出请求,获取真实的数据
|