Memcached面试题

12、如何将memcached中item批量导入导出?

您不应该这样做!Memcached 是一个非阻塞的服务器。任何可能导致memcached 暂停或瞬时拒绝服务的操作都应该值得深思熟虑。向
memcached中批量导入数据往往不是您真正想要的!想象看,如果缓存数据在导出导入之间发生了变化,您就需要处理脏数据了;

 

13、如果缓存数据在导入导出之间过期了,你又怎么处理这些数据?

因此,批量导出导入数据并不像您想象中的那么有用。不过在一个场景倒是很有用。如果您有大量的从不变化的数据,并且希望缓存很快热
(warm)起来,批量导入缓存数据是很有帮助的。虽然这个场景并不典型,但却经常发生,因此我们会考虑在将来实现批量导出导入的功
能。如果一个 memcached 节点 down 了让您很痛苦,那么您还会陷入其他很多麻烦。您的系统太脆弱了。您需要做一些优化工作。比如
处理”惊群”问题(比如memcached 节点都失效了,反复的查询让您的数据库不堪重负…这个问题在 FAQ的其他提到过),或者优化不好的
查询。记住,Memcached 并不是您逃避优化查询的借口。

 

14、memcached是如何做身份验证的?

没有身份认证机制!memcached 是运行在应用下层的软件(身份验证应该是应用上层的职责)。memcached 的客户端和服务器端之所以
是轻量级的,部分原因就是完全没有实现身份验证机制。这样,memcached 可以很快地创建新连接,服务器端也无需任何配置。如果您希
望限制访问,您可以使用防火墙,或者让 memcached 监听 unix domain socket

 

15、memcached的多线程是什么?如何使用它们?

线程就是定律(threads rule)!在 Steven Grimm 和 Facebook 的努力下,memcached 1.2 及更高版本拥有了多线程模式。多线程模式
允许 memcached 能够充分利用多个 CPU,并在 CPU 之间共享所有的缓存数据。memcached 使用一种简单的锁机制来保证数据更新操作
的互斥。相比在同一个物理机器上运行多个
memcached 实例,这种方式能够更有效地处理 multi gets。
如果您的系统负载并不重,也许您不需要启用多线程工作模式。如果您在运行一个拥有大规模硬件的、庞大的网站,您将会看到多线程的好
处。
简单地总结一下:命令解析(memcached 在这里花了大部分时间)可以运行在多线程模式下。memcached 内部对数据的操作是基于很多
全局锁的(因此这部分工作不是多线程的)。未来对多线程模式的改进,将移除大量的全局锁,提高memcached 在负载极高的场景下的性
能。

 

16、mecached能接受的key的最大长度?

key 的最大长度是 250 个字符。需要注意的是,250 是 memcached 服务器端内部的限制,如果您使用的客户端支持”key 的前缀”或类似特
性,那么 key(前缀+原始 key)的最大长度是可以超过 250 个字符的。我们推荐使用使用较短的 key,因为可以节省内存和带宽。

 

17、memcached对item的过期时间有什么限制?

过期时间最大可以达到 30 天。memcached 把传入的过期时间(时间段)解释成时间点后,一旦到了这个时间点,memcached 就把
item 置为失效状态。这是一个简单但 obscure 的机制。

18、memcached最大能存储多大的单个item?

1MB。如果你的数据大于 1MB,可以考虑在客户端压缩或拆分到多个 key 中。
为什么单个 item 的大小被限制在 1M byte 之内?
啊…这是一个大家经常问的问题!
简单的回答:因为内存分配器的算法就是这样的。
详细的回答:Memcached 的内存存储引擎(引擎将来可插拔…),使用 slabs 来管理内存。内存被分成大小不等的 slabs chunks(先分成
大小相等的 slabs,然后每个 slab 被分成大小相等 chunks,不同 slab 的 chunk 大小是不相等的)。chunk的大小依次从一个最小数开
始,按某个因子增长,直到达到最大的可能值。

 

19、mecached能够更有效地使用内存吗?

Memcache 客户端仅根据哈希算法来决定将某个 key 存储在哪个节点上,而不考虑节点的内存大小。因此,您可以在不同的节点上使用大
小不等的缓存。但是一般都是这样做的:拥有较多内存的节点上可以运行多个 memcached 实例,每个实例使用的内存跟其他节点上的实
例相同。

 

20、什么是二进制协议,我该关注吗?

关于二进制最好的信息当然是二进制协议规范:
二进制协议尝试为端提供一个更有效的、可靠的协议,减少客户端/服务器端因处理协议而产生的 CPU 时间。
根据 Facebook 的测试,解析 ASCII 协议是 memcached 中消耗 CPU 时间最多的环节。所以,我们为什么不改进 ASCII 协议呢?

 

21、memcached的内存分配器是如何工作的?为什么不适用于malloc/free!为什么使用slabs?

实际上,这是一个编译时选项。默认会使用内部的 slab 分配器。您确实确实应该使用内建的 slab 分配器。最早的时候,memcached 只使
用 malloc/free 来管理内存。然而,这种方式不能与 OS 的内存管理以前很好地工作。反复地 malloc/free造成了内存碎片,OS 最终花费大
量的时间去查找连续的内存块来满足 malloc 的请求,而不是运行 memcached 进程。如果您不同意,当然可以使用 malloc!
只是不要在邮件列表中抱怨啊
slab 分配器就是为了解决这个问题而生的。内存被分配并划分成 chunks,一直被重复使用。因为内存被划分成大小不等的 slabs,如果
item 的大小与被选择存放它的 slab 不是很合适的话,就会浪费一些内存。Steven Grimm 正在这方面已经做出了有效的改进

 

 

22、memcached是原子的吗?

所有的被发送到 memcached 的单个命令是完全原子的。如果您针对同一份数据同时发送了一个 set 命令和一个 get 命令,它们不会影响对
方。它们将被串行化、先后执行。即使在多线程模式,所有的命令都是原子的,除非程序有 bug:)
命令序列不是原子的。如果您通过 get 命令获取了一个 item,修改了它,然后想把它 set 回 memcached,我们不保证这个 item 没有被其
他进程(process,未必是操作系统中的进程)操作过。在并发的情况下,您也可能覆写了一个被其他进程 set 的 item。
memcached 1.2.5 以及更高版本,提供了 gets 和 cas 命令,它们可以解决上面的问题。如果您使用 gets 命令查询某个 key 的 item,
memcached 会给您返回该 item 当前值的唯一标识。如果您覆写了这个 item 并想把它写回到 memcached中,您可以通过 cas 命令把那个
唯一标识一起发送给 memcached。如果该 item存放在 memcached 中的唯一标识与您提供的一致,您的写操作将会成功。如果另一个进
程在这期间也修改了这个 item,那么该 item 存放在 memcached 中的唯一标识将会改变,您的写操作就会失败 

 


23、如何实现集群中的 session 共享存储?
Session 是运行在一台服务器上的,所有的访问都会到达我们的唯一服务器上,这样我们可以根据客户端传来的 sessionID,来获取
session,或在对应 Session 不存在的情况下(session 生命周期到了/用户第一次登录),创建一个新的 Session;但是,如果我们在集群
环境下,假设我们有两台服务器 A,B,用户的请求会由
Nginx 服务器进行转发(别的方案也是同理),用户登录时,Nginx 将请求转发至服务器 A 上,A 创建了新的 session,并将 SessionID 返
回给客户端,用户在浏览其他页面时,客户端验证登录状态,Nginx 将请求转发至服务器 B,由于 B 上并没有对应客户端发来 sessionId 的
session,所以会重新创建一个新的 session,并且再将这个新的 sessionID 返回给客户端,这样,我们可以想象一下,用户每一次操作都有
1/2 的概率进行再次的登录,这样不仅对用户体验特别差,还会让服务器上的 session 激增,加大服务器的运行压力。

为了解决集群环境下的 seesion 共享问题,共有 4 种解决方案:
1.粘性 session
粘性 session 是指 Ngnix 每次都将同一用户的所有请求转发至同一台服务器上,即将用户与服务器绑定。
2.服务器 session 复制
即每次 session 发生变化时,创建或者修改,就广播给所有集群中的服务器,使所有的服务器上的 session 相同。
3.session 共享
缓存 session,使用 redis, memcached。
4.session 持久化
将 session 存储至数据库中,像操作数据一样才做 session 


24、memcached 与 redis 的区别
1、Redis 不仅仅支持简单的 k/v 类型的数据,同时还提供 list,set,zset,hash等数据结构的存储。而 memcache 只支持简单数据类型,
需要客户端自己处理复杂对象
2、Redis 支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用(PS:持久化在 rdb、aof)。 
3、由于 Memcache 没有持久化机制,因此宕机所有缓存数据失效。Redis 配置为持久化,宕机重启后,将自动加载宕机时刻的数据到缓存
系统中。具有更好的灾备机制。
4、Memcache 可以使用 Magent 在客户端进行一致性 hash 做分布式。Redis 支持在服务器端做分布式(PS:Twemproxy/Codis/Rediscluster 多种分布式实现方式)
5、Memcached 的简单限制就是键(key)和 Value 的限制。最大键长为 250 个字符。可以接受的储存数据不能超过 1MB(可修改配置文
件变大),因为这是典型 slab 的最大值,不适合虚拟机使用。而 Redis 的 Key 长度支持到 512k。
6、Redis 使用的是单线程模型,保证了数据按顺序提交。Memcache 需要使用cas 保证数据一致性。CAS(Check and Set)是一个确保并
发一致性的机制,属于“乐观锁”范畴;原理很简单:拿版本号,操作,对比版本号,如果一致就操作,不一致就放弃任何操作cpu 利用。由
于 Redis 只使用单核,而 Memcached 可以使用多核,所以平均每一个核上 Redis 在存储小数据时比 Memcached 性能更 高。而在 100k
以上的数据中,Memcached 性能要高于 Redis 。
7、memcache 内存管理:使用 Slab Allocation。原理相当简单,预先分配一系列大小固定的组,然后根据数据大小选择最合适的块存储。
避免了内存碎片。(缺点:不能变长,浪费了一定空间)memcached 默认情况下下一个 slab 的最大值为前一个的 1.25 倍。

8、redis 内存管理: Redis 通过定义一个数组来记录所有的内存分配情况, Redis采用的是包装的 malloc/free,相较于 Memcached 的内
存 管理方法来说,要简单很多。由于 malloc 首先以链表的方式搜索已管理的内存中可用的空间分配,导致内存碎片比较多

 

posted @   开源遗迹  阅读(41)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
点击右上角即可分享
微信分享提示