Memcache — 基础概念
📋 本文节选自《Memcache 面试题》,返回 查看全部章节
1. Memcached是什么,有什么作用?
Memcached是一个开源的,高性能的内存绶存软件,从名称上看Mem就是内存的意思,而Cache就是缓存的意思。Memcached的作用:通过在事先规划好的内存空间中临时绶存数据库中的各类数据,以达到减少业务对数据库的直接高并发访问,从而达到提升数据库的访问性能,加速网站集群动态应用服务的能力。
Memcached服务在企业集群架构中有哪些应用场景? 作为数据库的前端缓存应用 a、完整缓存(易),静态缓存例如:商品分类(京东),以及商品信息,可事先放在内存里,然后再对外提供数据访问,这种先放到内存,我们称之为预热,(先把数据存缓存中),用户访问时可以只读取memcached)缓存,不读取数据库了。
b、执点缓存(难)需要前端web程序配合,只缓存热点的数据,即缓存经常被访问的数据。先预热数据库里的基础数据,然后在动态更新,选读取缓存,如果缓存里没有对应的数据,程序再去读取数据库,然后程序把读取的新数据放入缓存存储。
特殊说明 :
如果碰到电商秒杀等高并发的业务,一定要事先预热,或者其它思想实现,例如:称杀只是获取资格,而不是瞬间秒杀到手商品。那么什么是获取资格?就是在数据库中,把0标成1.就有资格啦。再慢慢的去领取商品订单。因为秒杀过程太长会占用服务器资源。
如果数据更新,同时触发缓存更新,防止给用户过期数据。
c、对于持久化缓存存储系统,例如:redis,可以替代一部分数据库的存储,一些简单的数据业务,投票,统计,好友关注,商品分类等。nosql= not only sql
二、作业集群的session会话共享存储。
Memcached服务在不同企业业务应用场景中的工作流程;a、当web程序需要访问后端数据库获取数据时会优先访问Memcached内存缓存,如果缓存中有数据就直接获取返回前端服务及用户,如果没有数据(没有命中),在由程序请求后端的数据库服务器,获取到对应的数据后,除了返回给前端服务及用户数据外,还会把数据放到Memcached内存中进行缓存,等待下次请求被访问,Memcache内存始终是数据库的挡箭牌,从而大大的减轻数据库的访问压力,提高整个网站架构的响应速度,提升了用户体验。b、当程序更新,修改或删除数据库中已有的数据时,会同时发送请求通知Memcached已经缓存的同一个ID内容的旧数据失效,从而保证Memcache中数据和数据库中的数据一致。如果在高并发场合,除了通知Memcached过程的缓存失效外,还会通过相关机制,使得在用户访问新数据前,通过程序预先把更新过的数据推送到memcache中缓存起来,这样可以减少数据库的访问压力,提升Memcached中缓存命中率。c、数据库插件可以再写入更新数据库后,自动抛给MC缓存起来,自身不Cache.
2.Memcached服务分布式集群如何实现?
特殊说明:Memcached集群和web服务集群是不一样的,所有Memcached的数据总和才是数据库的数据。每台Memcached都是部分数据。(一台memcached的数据,就是一部分mysql数据库的数据)
a、程序端实现程序加载所有mc的ip列表,通过对key做hash (一致性哈希算法)例如:web1 (key)===>对应A,B,C,D,E,F,G……若干台服务器。(通过哈希算法实现)
b、负载均衡器通过对key做hash (一致性哈希算法)
一致哈希算法的目的是不但保证每个对象只请求一个对应的服务器,而且当节点宕机,缓存服务器的更新重新分配比例降到最低。
3.Memcached服务特点及工作原理是什么?
a、完全基于内存缓存的b、节点之间相互独立c、C/S模式架构,C语言编写,总共2000行代码。d、异步I/O 模型,使用libevent作为事件通知机制。e、被缓存的数据以key/value键值对形式存在的。f、全部数据存放于内存中,无持久性存储的设计,重启服务器,内存里的数据会丢失。g、当内存中缓存的数据容量达到启动时设定的内存值时,就自动使用LRU算法删除过期的缓存数据。h、可以对存储的数据设置过期时间,这样过期后的数据自动被清除,服务本身不会监控过期,而是在访问的时候查看key的时间戳,判断是否过期。j、memcache会对设定的内存进行分块,再把块分组,然后再提供服务。
4.简述Memcached内存管理机制原理?
早期的Memcached内存管理方式是通过malloc的分配的内存,使用完后通过free来回收内存,这种方式容易产生内存碎片,并降低操作系统对内存的管理效率。加重操作系统内存管理器的负担,最坏的情况下,会导致操作系统比memcached进程本身还慢,为了解决这个问题,Slab Allocation内存分配机制就延生了。
现在Memcached利用Slab Allocation机制来分配和管理内存。SlabAllocation机制原理是按照预先规定的大小,将分配给memcached)的内存分割成特定长度的内存块(chunk),再把尺寸相同的内存块,分成组(chunks slab class),这些内存块不会释放,可以重复利用。而且,slab allocator还有重复使用已分配的内存的目的。 也就是说,分配到的内存不会释放,而是重复利用。Slab Allocation的主要术语
Page分配给Slab的内存空间,默认是1MB。分配给Slab之后根据slab的大小切分成chunk。
Chunk用于缓存记录的内存空间。
SlabClass特定大小的chunk的组。集群架构方面的问题
5.memcached是怎么工作的?
Memcached的神奇来自两阶段哈希(two-stage hash)。Memcached就像一个巨大的、存储了很多<key,value>对的哈希表。通过key,可以存储或查询任意的数据。
客户端可以把数据存储在多台你能memcached上。当查询数据时,客户端首先参考节点列表计算出key的哈希值(阶段一哈希),进而选中一个节点;客户端将请求发送给选中的节点,然后memcached节点通过一个内部的哈希算法(阶段二哈希),查找真正的数据(item)。
6.memcached最大的优势是什么?
Memcached最大的好处就是它带来了极佳的水平可扩展性,特别是在一个巨大的系统中。由于客户端自己做了一次哈希,那么我们很容易增加大量memcached到集群中。memcached之间没有相互通信,因此不会增加 memcached的负载;没有多播协议,不会网络通信量爆炸(implode)。memcached的集群很好用。内存不够了?增加几台 memcached吧;CPU不够用了?再增加几台吧;有多余的内存?在增加几台吧,不要浪费了。
基于memcached的基本原则,可以相当轻松地构建出不同类型的缓存架构。除了这篇FAQ,在其他地方很容易找到详细资料的。
7.memcached和MySQL的querycache相比,有什么优
缺点?
把memcached引入应用中,还是需要不少工作量的。MySQL有个使用方便的query cache,可以自动地缓存SQL查询的结果,被缓存的SQL查询可以被反复地快速执行。Memcached与之相比,怎么样呢?MySQL的query cache是集中式的,连接到该query cache的MySQL服务器都会受益。
当您修改表时,MySQL的query cache会立刻被刷新(flush)。存储一个memcached item只需要很少的时间,但是当写操作很频繁时,MySQL的query cache会经常让所有缓存数据都失效。
在多核CPU上,MySQL的query cache会遇到扩展问题(scalability issues)。在多核CPU上,query cache会增加一个全局锁(global lock), 由于需要刷新更多的缓存数据,速度会变得更慢。
在 MySQL的query cache中,我们是不能存储任意的数据的(只能是SQL查询结果)。而利用memcached,我们可以搭建出各种高效的缓存。比如,可以执行多个独立的查询,构建出一个用户对象(user object),然后将用户对象缓存到memcached中。而query cache是SQL语句级别的,不可能做到这一点。在小的网站中,query cache会有所帮助,但随着网站规模的增加,query cache的弊将大于利。
query cache能够利用的内存容量受到MySQL服务器空闲内存空间的限制。给数据库服务器增加更多的内存来缓存数据,固然是很好的。但是,有了memcached,只要您有空闲的内存,都可以用来增加memcached集群的规模,然后您就可以缓存更多的数据。
8.memcached和服务器的local cache(比如PHP的
APC、mmap文件等)相比,有什么优缺点?首先,local cache有许多与上面(query cache)相同的问题。local cache能够利用的内存容量受到(单台)服务器空闲内存空间的限制。不过,localcache有一点比memcached和query cache都要好,那就是它不但可以存储任意的数据,而且没有网络存取的延迟。
local cache的数据查询更快。考虑把highly common的数据放在local cache中吧。如果每个页面都需要加载一些数量较少的数据,考虑把它们放在localcached吧。
local cache缺少集体失效(groupinvalidation)的特性。在memcached集群中,删除或更新一个key会让所有的观察者觉察到。但是在local cache中, 我们只能通知所有的服务器刷新cache(很慢,不具扩展性),或者仅仅依赖缓存超时失效机制。
local cache面临着严重的内存限制,这一点上面已经提到。