Java架构师之面试题

简介: memcached

11、memcached 如何处理容错的?

不处理! 在 memcached 节点失效的情况下,集群没有必要做任何容错处理。如 果发生了节点失效,应对的措施完全取决于用户。节点失效时,下面列出几种方 案供您选择:

  • 忽略它! 在失效节点被恢复或替换之前,还有很多其他节点可以应对节 点失效带来的影响。
  • 把失效的节点从节点列表中移除。做这个操作千万要小心!在默认情况下 (余数式哈希算法),客户端添加或移除节点,会导致所有的缓存数据不可用! 因为哈希参照的节点列表变化了,大部分 key 会因为哈希值的改变而被映射到 (与原来)不同的节点上。
  • 启动热备节点,接管失效节点所占用的 IP。这样可以防止哈希紊乱 (hashing chaos)。
  • 如果希望添加和移除节点,而不影响原先的哈希结果,可以使用一致性哈 希算法(consistent hashing)。您可以百度一下一致性哈希算法。支持一致性 哈希的客户端已经很成熟,而且被广泛使用。去尝试一下吧!
  • 两次哈希(reshing)。当客户端存取数据时,如果发现一个节点 down 了,就再做一次哈希(哈希算法与前一次不同),重新选择另一个节点(需要注 意的时,客户端并没有把 down 的节点从节点列表中移除,下次还是有可能先 哈希到它)。如果某个节点时好时坏,两次哈希的方法就有风险了,好的节点和 坏的节点上都可能存在脏数据(stale data)。

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、memcached 能接受的 key 的最大长度是多少?

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

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

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

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

1MB。

如果你的数据大于 1MB,可以考虑在客户端压缩或拆分到多个 key 中。

为什么单个 item 的大小被限制在 1M byte 之内? 啊…这是一个大家经常问的问题!

简单的回答:因为内存分配器的算法就是这样的。

详细的回答:Memcached 的内存存储引擎(引擎将来可插拔…),使用 slabs 来 管理内存。内存被分成大小不等的 slabs chunks(先分成大小相等的 slabs,然后 每个 slab 被分成大小相等 chunks,不同 slab 的 chunk 大小是不相等的)。chunk 的大小依次从一个最小数开始,按某个因子增长,直到达到最大的可能值。

18、memcached 能够更有效地使用内存吗?

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

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

关于二进制最好的信息当然是二进制协议规范:

二进制协议尝试为端提供一个更有效的、可靠的协议,减少客户端/服务器端因处 理协议而产生的 CPU 时间。

根据 Facebook 的测试,解析 ASCII 协议是 memcached 中消耗 CPU 时间最多的 环节。所以,我们为什么不改进 ASCII 协议呢?

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

实际上,这是一个编译时选项。默认会使用内部的 slab 分配器。您确实确实应该 使用内建的 slab 分配器。最早的时候,memcached 只使用 malloc/free 来管理 内存。然而,这种方式不能与 OS 的内存管理以前很好地工作。反复地 malloc/free 造成了内存碎片,OS 最终花费大量的时间去查找连续的内存块来满足 malloc 的 请求,而不是运行 memcached 进程。如果您不同意,当然可以使用 malloc!只 是不要在邮件列表中抱怨啊。

slab 分配器就是为了解决这个问题而生的。内存被分配并划分成 chunks,一直被 重复使用。因为内存被划分成大小不等的 slabs,如果 item 的大小与被选择存放 它的 slab 不是很合适的话,就会浪费一些内存。Steven Grimm 正在这方面已经 做出了有效的改进。

目录
打赏
0
0
0
0
2521
分享
相关文章
java面试-基础语法与面向对象
本文介绍了 Java 编程中的几个核心概念。首先,详细区分了方法重载与重写的定义、发生阶段及规则;其次,分析了 `==` 与 `equals` 的区别,强调了基本类型和引用类型的比较方式;接着,对比了 `String`、`StringBuilder` 和 `StringBuffer` 的特性,包括线程安全性和性能差异;最后,讲解了 Java 异常机制,包括自定义异常的实现以及常见非检查异常的类型。这些内容对理解 Java 面向对象编程和实际开发问题解决具有重要意义。
41 15
Java社招面试中的高频考点:Callable、Future与FutureTask详解
大家好,我是小米。本文主要讲解Java多线程编程中的三个重要概念:Callable、Future和FutureTask。它们在实际开发中帮助我们更灵活、高效地处理多线程任务,尤其适合社招面试场景。通过 Callable 可以定义有返回值且可能抛出异常的任务;Future 用于获取任务结果并提供取消和检查状态的功能;FutureTask 则结合了两者的优势,既可执行任务又可获取结果。掌握这些知识不仅能提升你的编程能力,还能让你在面试中脱颖而出。文中结合实例详细介绍了这三个概念的使用方法及其区别与联系。希望对大家有所帮助!
215 60
【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
126 13
【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
|
15天前
|
Java线程池的实现架构
线程池是一种用于管理多线程的池化技术,通过复用线程减少创建和销毁线程的开销。Java中的线程池架构包括`Executor`、`ExecutorService`、`ScheduledExecutorService`等接口,以及`ThreadPoolExecutor`和`ScheduledThreadPoolExecutor`两个核心实现类。`Executors`工厂类提供了便捷的线程池创建方法。线程池不仅简化了多线程编程,还能避免线程过多导致的资源消耗和切换开销。本文从使用示例入手,剖析了线程池的实现原理及其内部架构,重点分析调度线程池的实现机制。
Java线程池实现架构
Java线程池实现架构
Java社招面试题:一个线程运行时发生异常会怎样?
大家好,我是小米。今天分享一个经典的 Java 面试题:线程运行时发生异常,程序会怎样处理?此问题考察 Java 线程和异常处理机制的理解。线程发生异常,默认会导致线程终止,但可以通过 try-catch 捕获并处理,避免影响其他线程。未捕获的异常可通过 Thread.UncaughtExceptionHandler 处理。线程池中的异常会被自动处理,不影响任务执行。希望这篇文章能帮助你深入理解 Java 线程异常处理机制,为面试做好准备。如果你觉得有帮助,欢迎收藏、转发!
152 14
Java 面试必问!线程构造方法和静态块的执行线程到底是谁?
大家好,我是小米。今天聊聊Java多线程面试题:线程类的构造方法和静态块是由哪个线程调用的?构造方法由创建线程实例的主线程调用,静态块在类加载时由主线程调用。理解这些细节有助于掌握Java多线程机制。下期再见! 简介: 本文通过一个常见的Java多线程面试题,详细讲解了线程类的构造方法和静态块是由哪个线程调用的。构造方法由创建线程实例的主线程调用,静态块在类加载时由主线程调用。理解这些细节对掌握Java多线程编程至关重要。
66 13
Java线程调度揭秘:从算法到策略,让你面试稳赢!
在社招面试中,关于线程调度和同步的相关问题常常让人感到棘手。今天,我们将深入解析Java中的线程调度算法、调度策略,探讨线程调度器、时间分片的工作原理,并带你了解常见的线程同步方法。让我们一起破解这些面试难题,提升你的Java并发编程技能!
121 16
Java 高级面试技巧:yield() 与 sleep() 方法的使用场景和区别
本文详细解析了 Java 中 `Thread` 类的 `yield()` 和 `sleep()` 方法,解释了它们的作用、区别及为什么是静态方法。`yield()` 让当前线程释放 CPU 时间片,给其他同等优先级线程运行机会,但不保证暂停;`sleep()` 则让线程进入休眠状态,指定时间后继续执行。两者都是静态方法,因为它们影响线程调度机制而非单一线程行为。这些知识点在面试中常被提及,掌握它们有助于更好地应对多线程编程问题。
120 9
Java高级应用开发:基于AI的微服务架构优化与性能调优
在现代企业级应用开发中,微服务架构虽带来灵活性和可扩展性,但也增加了系统复杂性和性能瓶颈。本文探讨如何利用AI技术,特别是像DeepSeek这样的智能工具,优化Java微服务架构。AI通过智能分析系统运行数据,自动识别并解决性能瓶颈,优化服务拆分、通信方式及资源管理,实现高效性能调优,助力开发者设计更合理的微服务架构,迎接未来智能化开发的新时代。

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等