你好,是我琉忆。 今天是周五了,再上一天班就周末了,提前祝大家周末愉快。
嘿嘿。 这篇文章是本周Memcache和Redis内存数据库常考的专题。
本周一和周三更新的文章路径:
本周(2019.2-18至2-22)的文章内容点为以下几点,更新时间为每周一三五,可以关注本栏持续关注,感谢你的支持。
一、什么是Memcache?
二、Memcache有什么特征?
三、Memcache的内存管理机制是什么样的?
四、Memcache和Memcached有什么区别?
五、如何操作Memcache?
六、如何使用Memcache做Session共享?
七、什么是Redis?
八、如何使用Redis?
九、使用Redis需要注意哪些问题?
十、新增:Redis和Memcache有什么不同?
十一、新增:Redis如何实现持久化?
十二、Memcache和Redis常考的面试题
本章节的内容将会被分为三篇文章进行讲解完整块内容,第一篇主要讲解一到六,第二篇主要讲解七到十一(新增了十和十一),第三篇围绕第十二点。
以下正文的部分内容来自《PHP程序员面试笔试真题解析》书籍,如果转载请保留出处:
十二、Memcache和Redis常考的面试题
【真题1】Memcache的工作原理是什么?
答案:Memcache的工作就是在专门的机器内存里维护一张巨大的hash表,存储经常被读写的一些文件与数据,从而极大地提高网站的运行效率。 Memcache的程序运行在一个或多个服务器中,Memcache把全部的数据保存在内存中,通过hash表的方式,每条数据由key/value的形式构成,随时接受客户端的请求,然后返回结果。
客户端与Memcache建立连接后,存储对象主要是通过唯一的key存储value到内存中,取数据时通过这个key从内存中获取对应的value。由于Memcache的数据是存储在内存中而不是保存在cache文件中,所以Memcache访问比较快,但是由于这些数据不是永久化存储,所以不建议存储重要数据在Memcache中,因为重启服务器后这些数据就会消失。
【真题2】Memcache的优点有哪些?
答案:Memcache是一个高性能的分布式内存对象缓存系统,主要通过在内存里维护一个巨大的hash表进行数据缓存。它主要是将数据存储到内存中,然后从内存中读取数据,从而提高读取速度。它主要通过key-value的形式存储各种数据,包括图像、视频、文件等。 它具有以下几点优点:
(1)支持多台服务器使用Memcache,由于Memcache的存储数据大小必须小于内存的大小,所以可以将Memcache使用在多台服务器上,增加缓存容量;
(2)支持均衡请求。当使用多台Memcache服务器时,可以均衡请求,避免所有请求都进入一台Memcache服务器中,避免服务器挂掉而丢失数据;
(3)支持分布式,可以解决缓存本身水平线性扩展的问题和缓存大并发下的自身性能问题,避免缓存的单点故障问题;
(4)支持部分容灾问题,如果多台服务器存储了Memcache数据,其中一台Memcache服务器挂掉,部分请求还是可以在其它服务器的Memcache中命中,为修复挂掉的服务器争取一些时间。
【真题3】如何合理地使用Memcache缓存?如果缓存数据量过大,那么如何部署?(分布式,缓存时间,优化缓存数据)
答案:如果要合理地使用Memcache缓存,那么需要注意以下几点内容:
(1)因为Memcache支持最大的存储对象大小为1M,所以当合理使用Memcache缓存时,要求不能往Memcache存储一个大于1MB的数据;
(2)Memcache存储的所有数据,如果数据大小分布于各种chunk大小区间,从64B到1MB都有,那么会造成内存的极大浪费和Memcache的异常。所以需要注意数据大小的分布区间;
(3)key的长度不能大于250个字符;
(4)虚拟主机不允许运行Memcache服务,所以不能把Memcache部署到虚拟主机中;
(5)因为Memcache可以轻松访问到,所以可以运行在不安全的环境中,如果对数据安全要求高,那么需要着重考虑运行环境的安全问题;
(6)因为Memcache存储的数据都在内存中,服务器挂掉就会清空内存,所以缓存中的数据尽量是丢失了也不会有太大影响的数据。
如果缓存中的数据量过大,那么可以采取以下的办法: (1)使用Memcache服务器集群的方法,首先是将数据安排放在不同的Memcache服务器上,可以将不同硬件服务器上的Memcache服务器再做成一个数据互相备份的组,避免数据的单点丢失问题;
(2)缓存数据到数据库中,在数据库中先建一张表来说明Memcache服务器集群中缓存数据的存放逻辑,然后实现把缓存数据存到数据库中,可以保证数据库和缓存的数据双向存取。
【真题4】Redis 与 Memcache有什么区别?
答案:Redis是一个完全开源免费的高性能key-value数据库,具有丰富的数据类型,可以支持数据的持久化,将内存中的数据保存在磁盘中,当重启服务器时可以再次加载使用。
Memcache是一个高性能的分布式内存对象缓存系统,用于动态的Web应用中帮助数据库减轻负担,在内存中缓存数据和对象,减少每次访问数据时对数据库的访问次数,从而提高访问速度。
它们具有以下几点区别: (1)Redis和Memcache的最大区别是,虽然Memcache和Redis都是将数据存在内存中,是内存数据库,但Redis存储时,并不是所有的数据都一直存储在内存中,而Memcache存储时,数据都存在内存中;
(2)数据安全问题,由于memecache 把数据全部存在内存之中,服务器挂掉后,重启服务器数据就会丢失,而Redis可以定期保存数据到磁盘中做持久化存储,当需要时可以再加载使用。对于灾难恢复,Memcache挂掉后,数据不可恢复,但Redis数据丢失后可以通过aof恢复;
(3)Redis支持多种数据结构存储,例如list,set,hash等数据结构的存储,而Memcache主要是在内存中维护一个统一的巨大的hash表进行存储数据,只支持简单的key/value类型的数据存储,但Memcache可以存储图片、视频、文件及数据库检索结果等;
(4)数据备份问题,Redis支持数据的备份,即master-slave模式的数据备份。而Memcache不支持数据持久化,所以无法进行数据备份;
(5)在内存使用率上,使用简单的key-value存储的话,Memcached的内存利用率更高,而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcached。具体和应用场景、数据特性有关;
(6)在线程上的比较,Memcache是支持多线程的,而Redis只支持单线程,所以CPU利用方面Memcache优于Redis;
(7)它们的扩展都需要做集群;实现方式:master-slave、Hash;
(8)数据的读写方面,Redis和Memcache在写入性能上面差别不大,读取性能上面尤其是批量读取性能上Memcache更强。
【真题5】Redis集群方案应该怎么做?都有哪些方案?
答案:1.twemproxy,大概概念是,它类似于一个代理方式,使用方法和普通redis无任何区别,设置好它下属的多个redis实例后,使用时在本需要连接redis的地方改为连接twemproxy,它会以一个代理的身份接收请求并使用一致性hash算法,将请求转接到具体redis,将结果再返回twemproxy。使用方式简便(相对redis只需修改连接端口),对旧项目扩展的首选。 问题:twemproxy自身单端口实例的压力,使用一致性hash后,对redis节点数量改变时候的计算值的改变,数据无法自动移动到新的节点。
2.codis,目前用的最多的集群方案,基本和twemproxy一致的效果,但它支持在 节点数量改变情况下,旧节点数据可恢复到新hash节点。
3.redis cluster3.0自带的集群,特点在于他的分布式算法不是一致性hash,而是hash槽的概念,以及自身支持节点设置从节点。具体看官方文档介绍。
4.在业务代码层实现,起几个毫无关联的redis实例,在代码层,对key 进行hash计算,然后去对应的redis实例操作数据。 这种方式对hash层代码要求比较高,考虑部分包括,节点失效后的替代算法方案,数据震荡后的自动脚本恢复,实例的监控,等等。
自己整理了一篇“PHP不同等级面试都问什么?”的文章,关注公众号:“琉忆编程库”,回复:“等级”,我发给你。
【真题6】Redis有哪些适合的场景?
答案:(1)、会话缓存(Session Cache)
最常用的一种使用Redis的情景是会话缓存(session cache)。用Redis缓存会话比其他存储(如Memcached)的优势在于:Redis提供持久化。当维护一个不是严格要求一致性的缓存时,如果用户的购物车信息全部丢失,大部分人都会不高兴的,现在,他们还会这样吗?
幸运的是,随着 Redis 这些年的改进,很容易找到怎么恰当的使用Redis来缓存会话的文档。甚至广为人知的商业平台Magento也提供Redis的插件。
(2)、全页缓存(FPC)
除基本的会话token之外,Redis还提供很简便的FPC平台。回到一致性问题,即使重启了Redis实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降,这是一个极大改进,类似PHP本地FPC。
再次以Magento为例,Magento提供一个插件来使用Redis作为全页缓存后端。
此外,对WordPress的用户来说,Pantheon有一个非常好的插件 wp-redis,这个插件能帮助你以最快速度加载你曾浏览过的页面。
(3)、队列
Reids在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作,就类似于本地程序语言(如Python)对 list 的 push/pop 操作。
如果你快速的在Google中搜索“Redis queues”,你马上就能找到大量的开源项目,这些项目的目的就是利用Redis创建非常好的后端工具,以满足各种队列需求。例如,Celery有一个后台就是使用Redis作为broker,你可以从这里去查看。
(4),排行榜/计数器
Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单,Redis只是正好提供了这两种数据结构。所以,我们要从排序集合中获取到排名最靠前的10个用户–我们称之为“user_scores”,我们只需要像下面一样执行即可:
当然,这是假定你是根据你用户的分数做递增的排序。如果你想返回用户及用户的分数,你需要这样执行:
ZRANGE user_scores 0 10 WITHSCORES
Agora Games就是一个很好的例子,用Ruby实现的,它的排行榜就是使用Redis来存储数据的,你可以在这里看到。
(5)、发布/订阅
最后(但肯定不是最不重要的)是Redis的发布/订阅功能。发布/订阅的使用场景确实非常多。我已看见人们在社交网络连接中使用,还可作为基于发布/订阅的脚本触发器,甚至用Redis的发布/订阅功能来建立聊天系统!(不,这是真的,你可以去核实)。
【真题7】Redis持久化数据和缓存怎么做扩容?
答案:如果Redis被当做缓存使用,使用一致性哈希实现动态扩容缩容。
如果Redis被当做一个持久化存储使用,必须使用固定的keys-to-nodes映射关系,节点的数量一旦确定不能变化。否则的话(即Redis节点需要动态变化的情况),必须使用可以在运行时进行数据再平衡的一套系统,而当前只有Redis集群可以做到这样。
【真题8】Redis回收进程如何工作的?
答案:一个客户端运行了新的命令,添加了新的数据。
Redi检查内存使用情况,如果大于maxmemory的限制, 则根据设定好的策略进行回收。
一个新的命令被执行,等等。
所以我们不断地穿越内存限制的边界,通过不断达到边界然后不断地回收回到边界以下。
如果一个命令的结果导致大量内存被使用(例如很大的集合的交集保存到一个新的键),不用多久内存限制就会被这个内存使用量超越。
【真题9】都有哪些办法可以降低Redis的内存使用情况呢?
答案:如果你使用的是32位的Redis实例,可以好好利用Hash,list,sorted set,set等集合类型数据,因为通常情况下很多小的Key-Value可以用更紧凑的方式存放到一起。
【真题10】你知道有哪些Redis分区实现方案?
答案:客户端分区就是在客户端就已经决定数据会被存储到哪个redis节点或者从哪个redis节点读取。大多数客户端已经实现了客户端分区。
代理分区 意味着客户端将请求发送给代理,然后代理决定去哪个节点写数据或者读数据。代理根据分区规则决定请求哪些Redis实例,然后根据Redis的响应结果返回给客户端。redis和memcached的一种代理实现就是Twemproxy
查询路由(Query routing) 的意思是客户端随机地请求任意一个redis实例,然后由Redis将请求转发给正确的Redis节点。Redis Cluster实现了一种混合形式的查询路由,但并不是直接将请求从一个redis节点转发到另一个redis节点,而是在客户端的帮助下直接redirected到正确的redis节点。
自己根据不同PHP不同等级面试时,会问哪些PHP常考的知识点整理成了一篇文章自己整理了一篇“PHP不同等级面试都问什么?”的文章,关注公众号:“琉忆编程库”,回复:“等级”,我发给你。
更多相关面试常考真题可以阅读《PHP程序员面试笔试真题解析》。
预告:下周(2019.2.25至2019.3.1)一三五将更新的主题为:PHP面试之会话控制、网络协议、相关的面试题。
以上内容摘自《PHP程序员面试笔试真题解析》书籍,该书已在天猫、京东、当当等电商平台销售。
更多PHP相关的面试知识、考题可以关注公众号获取:琉忆编程库
对本文有什么问题或建议都可以进行留言,我将不断完善追求极致,感谢你们的支持。
共同学习,写下你的评论
评论加载中...
作者其他优质文章