爱我,就要懂我 – Memcached- 第284篇
相关历史文章(阅读本文之前,您可能需要先看下之前的系列)
烦不烦,别再问我时间复杂度了:这次不色,女孩子进来吧 - 第281篇
悟纤:师傅,最近很是烦人呐?
师傅:谁欺负我徒儿了?
悟纤:哎,最近数据库压力大,导致徒儿压力也山大。
师傅:数据库压力大,缓存来解决,徒儿,赶紧上缓存呐。就如同现在这是所有的“妖怪”都是你在打,赶紧让“八戒”拦一部分。这样你的压力就小了。
悟纤:缓存这是什么东东?
师傅:为师今天就来给你普及下Memcached缓存。
BTW:缓存缓存,让你的头不再疼。
一、何为Memcached缓存
[百度百科」:
Memcached是一个*开源的,高性能,分布式内存对象缓存系统。
Memcached是以LiveJournal旗下Danga Interactive公司的Brad Fitzpatric为首开发的一款软件。现在已成为mixi、hatena、Facebook、Vox、LiveJournal等众多服务中提高Web应用扩展性的重要因素。
Memcached是一种基于内存的key-value存储,用来存储小块的任意数据(字符串、对象)。这些数据可以是数据库调用、API调用或者是页面渲染的结果。
Memcached简洁而强大。它的简洁设计便于快速开发,减轻开发难度,解决了大数据量缓存的很多问题。它的API兼容大部分流行的开发语言。
一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展性。
「学深悟透」
悟纤:这信息量不少呐,师傅梳理下呗。
师傅:好吧,为师用一句话概况下。
BTW:Memcached是一个基于K-V内存存储、开源、免费、高性能的分布式缓存系统。
悟纤:师傅,徒儿理解了,
Memcached(MemoryCached)
就是使用K-V的方式进行内存储存,性能比较高,支持分布式处理。由于将大部分的请求数据都由缓存进行处理返回,所以数据库的压力就减少了。
师傅:为师要给你32个赞。
二、Memcached的一些基本特性
为了对于Memcached有一个更好的认知,我们需要对于Memcached的基本特性有一个简单的理解,这样一方面有助于对于Memcached的使用,另外一方面也有助于技术的选型。
(1) Memcached是使用KV内存管理,key的长度最大250字符,value存储最大为1M,不支持复杂的数据类型(哈希、列表、集合等)。
(2)Memcached不支持持久化(不能存在磁盘,只能存储在内存中)。
(3)Memcached支持key过期(过期时间最大可以达到30天)。
(4)Memcached使用非阻塞IO复用网络模型,使用监听线程/工作线程的多线程模型。
(5)Memcached基于c/s架构,协议简单。
…
三、悟纤100问
3.1 key和value是否有限制
Memcached是使用KV内存管理,key的长度最大250字符,value存储最大为1M。
3.2 memcached是用什么技术实现key过期的?
懒淘汰(lazy expiration)。
Memcached 内部不会监视记录是否过期,而是在get时查看记录的时间戳,检查记录是否过期。这种技术被称为lazy(惰性)expiration。因此,Memcached不会在过期监视上耗费CPU时间。
3.3 删除机制(缓存策略)
Memcached的缓存策略是LRU(最近最少使用)加上到期失效策略。当你在memcached内存储数据项时,你有可能会指定它在缓存的失效时间。当memcached服务器用完分配的内时,失效的数据被首先替换,然后也是最近未使用的数据。在LRU中,memcached使用的是一种LazyExpiration策略,自己不会监控存入的key/vlue对是否过期,而是在获取key值时查看记录的时间戳,检查key/value对空间是否过期,这样可减轻服务器的负载。
BTW:Memcached的缓存策略就是LRU+到期失效;使用懒淘汰,当获取key的时候触发。
->LRU还不懂,公众号「SpringBoot」可以查看文章《面试不再怕,让LRU无处可逃》
对于Memcached的LRU和我们之前讲的LRU有何区别呐?
->之后公众号「SpringBoot」会有章节详细说明Memcached的LRU《你懂她,可惜你不懂我》
3.4 存储方式
内存存储方式, 非持久性存储。所有数据都保存在内存中,存取数据比硬盘快,当内存满后,通过LRU算法自动删除不使用的缓存,但没有考虑数据的容灾问题,重启服务,所有数据会丢失。
3.5 Memcached分布式是如何实现的
memcached本身是一个非常轻量级的服务,不支持主辅同步,也没有集群的概念。但为了可扩展性,memcached服务器端和 memcached 客户端结合起来可以构成一个分布式系统。
在memcached分布式系统中,各个 memcached 节点之间无须通信,所以扩展性非常好。
->Memcached的分布式特点:
•1>: 服务器端不关心分布式:服务端的各个Memcached都是独立部署,之间不相互通信,这样服务端部署多个Memcached就很简单。
•2>: 依靠客户端来实现分布式:最简单的方式就是客户端拥有服务端所有连接地址,客户端通过key的hash值获取到对应的Memcached。
->之后公众号「SpringBoot」会有章节详细说明分布式的算法《分布式算法真是吊炸天》
3.6 Memcached的集群方案有哪些?
因为memcached的服务器并不支持集群,所以有两种方案支持
(1)代理端支持集群(性能会有所损耗,大概20%);
(2)一种是客户端支持集群。
BTW:推荐使用客户端。由上面可知一般的应用中memcached服务端集群不用做太多工作,部署一堆memcached服务器就可以了。
Memcached集群和web服务集群是不一样的, 所有Memcached的数据总和才是数据库的数据。每台Memcached都是部分数据。((一台memcached的数据,就是一部分mysql数据库的数据))
3.7 Memcached碰到秒杀业务怎么玩?
如果碰到电商秒杀等高并发的业务,一定要事先预热,或者其它思想实现,例如:称杀只是获取资格,而不是瞬间秒杀到手商品。
那么什么是获取资格?就是在数据库中,把0标成1.就有资格啦。再慢慢的去领取商品订单。因为秒杀过程太长会占用服务器资源。
BTW:核心就是事先预热、获取资格
还记得12306的火车票余票查询嘛,一开始的时候,设计成时时更新余票数量,后来调整为有票无票,对于用户而言,不关心还剩下多少票,关心的是有没有票。抢票成功之后,就获取了票的资格,至于下单支付在45分钟内操作完成即可,否则票被释放出来。
3.8 Memcached服务在业务应用场景中的工作流程
(1)查询:当web程序需要访问后端数据库获取数据时会优先访问Memcached内存缓存,如果缓存中有数据就直接获取返回前端服务及用户,如果没有数据(没有命中),在由程序请求后端的数据库服务器,获取到对应的数据后,除了返回给前端服务及用户数据外,还会把数据放到Memcached内存中进行缓存,等待下次请求被访问,Memcache内存始终是数据库的挡箭牌,从而大大的减轻数据库的访问压力,提高整个网站架构的响应速度,提升了用户体验。
(2)更新:当程序更新,修改或删除数据库中已有的数据时,会同时发送请求通知Memcached已经缓存的同一个ID内容的旧数据失效,从而保证Memcache中数据和数据库中的数据一致。
3.9 Memcached为什么性能高?
memcached 性能高的原因主要在于 libevent事件机制、多线程、全内存操作、模型简单(时间复杂度 O(1),尽量避免锁机制)。
memcached 所有的操作都是 O(1) (LRU算法),set/get 操作不应该出现滞后,一个请求正常情况下不到 1ms 就能返回,如果遇到 Hang,那可能是连接数过多、产生了 swap、遇到了网络问题。
配置相对较高的服务器,每秒可以处理 200,000+ 的请求,即使在很慢的机器上,每秒处理几百次也毫无压力。
->时间复杂度为O(1)还不懂,公众号「SpringBoot」可以查看文章《烦不烦,别再问我时间复杂度了》
3.10 memcache为什么能保证运行性能
主要是通过提前分配内存,对于Memcached的内存模型,我们在之后的章节会讲到,本节就不过多展开了。
->之后公众号「SpringBoot」会有章节详细说明内存管理《内存管理,难于上青天》
3.11 是否支持复杂的操作
和 redis 不一样的是,memcached 没有复杂的数据结构(比如队列、集合),它只能存储字符串类型,也不关心具体存储什么,这是它的一个优势:简单。但很多人用的时候可能就不爽了,说它比 redis 弱爆了,其实双方的应用场景不一样。
当然也可以基于基本命令模拟一些数据结构,这是允许的,但这和memcached无关。
3.12 很少会出现内存碎片?
浪费存储空间,来减少内存碎片。
对于Memcached内存是预先分配的,比如chunk=128B,那么有一个item=100B,那么就会浪费28B。
->之后公众号「SpringBoot」会有章节详细说明内存管理《内存管理,难于上青天》
四、悟纤小结
这节说的很多了,感觉都很重要呐,还是来做个简单的总结吧:
(1)Memcached:Memcached是一个基于K-V内存存储、开源、免费、高性能的分布式缓存系统。(几个关键词要记住:内存,KV,高性能、分布式)
(2)内存储存:全部数据存放于内存中,无持久性存储的设计,重启服务器,内存里的数据会丢失。(存放内存、不支持持久化)。
(3)KV储存:使用key-value的方式储存数据,key的最大长度是250个字符,value储存最大值是1M。
(4)高性能缘由:libevent事件机制、多线程、全内存操作、模型简单、所有操作都是O(1)。
(5)分布式实现:服务端正常部署,客服端实现。
(6)缓存策略:LRU+到期失效+懒淘汰。(不会监控存入的key/vlue对是否过期,而是在获取key值时查看记录的时间戳,当内存中缓存的数据容量达到启动时设定的内存值时,就自动使用LRU算法删除过期的缓存数据。)
BTW:
Memcached是大佬,缓存它来搞;
内存KV储存真有效;
多线程、libevent事件、内存操作性能高;
分布式实现有一套,服务端不管,客户端hash搞起真高档;
缓存淘汰有策略,LRU算法最近最少就淘汰、到期无效key不要,
配上懒淘汰,淘汰淘汰Memcached真厉害。
我就是我,是颜色不一样的烟火。
我就是我,是与众不同的小苹果。
à悟空学院:https://t.cn/Rg3fKJD
学院中有Spring Boot相关的课程!点击「阅读原文」进行查看!
SpringBoot视频:http://t.cn/A6ZagYTi
Spring Cloud视频:http://t.cn/A6ZagxSR
SpringBoot Shiro视频:http://t.cn/A6Zag7IV
SpringBoot交流平台:https://t.cn/R3QDhU0
SpringData和JPA视频:http://t.cn/A6Zad1OH
SpringSecurity5.0视频:http://t.cn/A6ZadMBe
Sharding-JDBC分库分表实战:http://t.cn/A6ZarrqS
分布式事务解决方案「手写代码」:http://t.cn/A6ZaBnIr