IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

标签:cache

共 28 篇相关文章

IT 累计浏览 1,089

Lua 中 Cache 冷数据的落地

这篇讲的是如何在 Lua 虚拟机中,为缓存模块设计一个安全的冷数据落地机制。作者从一个实际 bug 讨论出发,详细分析了不同方案的演进。 文章最初提出一个基于时间戳的朴素方案,但发现其无法保证业务正在使用数据时,数据不会被错误地异步写回。随后,作者引入 Lua 弱表和 `__gc` 元方法进行改进,利用垃圾回收机制来判断数据是否“冷”。然而,这个方案存在一个微妙的“第三状态”漏洞:当对象被 GC 回收、但其 `__gc` 方法尚未将其“复活”到待处理表时,系统会短暂地失去对该数据的追踪,导致可能从数据库加载出旧版本的数据。 为解决这个并发与状态管理的核心难题,文章最终提出了基于元表代理的方案。通过让 cache 表存储代理对象,将真正的数据隔离在另一个全局表中,从而稳定了数据从缓存中移除的时机,并使冷数据落地流程可以清晰地通过集合差集来识别目标,避免了复杂的状态竞争问题。这实质上是用间接层换取了状态管理的清晰与安全。

IT 累计浏览 3,570

Linux内存中的Cache真的能被回收么?

这篇讲的是Linux系统中一个经典但常被误解的问题:那些被buffer和cache占用的内存,到底能不能在需要时被释放。文章从`free`命令的输出切入,指出了三种不同层次的理解,并重点剖析了第二种——即很多人认为buffer/cache内存“随时可释放”的认知其实并不完全准确。 作者清晰解释了page cache和buffer cache的核心区别:前者主要用于缓存文件读写,后者用于块设备I/O缓存。Linux内核确实会在内存压力大时回收这些缓存,但这个过程并非没有代价——回收前必须确保缓存数据与磁盘文件一致,往往会导致瞬间的IO飙升。 文章的真正价值在于通过一个具体的tmpfs实验揭示了回收的边界。当把大量数据存入基于内存的tmpfs文件系统时,这部分内存会体现在`cached`指标里,`free`命令也提示有很多“可用”内存。然而,当尝试手动执行`echo 3 > /proc/sys/vm/drop_caches`进行回收时,这部分内存却无法被释放,因为它本质就是系统分配给tmpfs的物理内存,不属于可回收的缓存范畴。 因此,结论很明确:并非所有在`free`命令中显示为“cached”的内存都能被回收。像tmpfs这类“内存就是存储”的场景,占用的空间是“实实在在”的已使用内存,这与加速文件访问的磁盘缓存有本质区别。理解这一点,对于准确评估系统内存压力至关重要。

IT 累计浏览 1,567

缓存系列文章–无底洞问题

这篇讲的是分布式缓存系统中一个经典陷阱——“无底洞”问题。作者从Facebook大规模Memcached集群的实践切入,指出盲目增加节点不仅无法提升性能,反而会导致批量操作(如mget)因网络次数暴增而变慢。 问题的根源在于哈希分布下,大量key被打散到不同节点。一次批量获取需要跨多次网络IO,机器越多,耗时越长。文章对比了哈希分布与顺序分布的特点,并给出了四种应对方案:最简单的串行mget(O(n)网络时间),优化后的按节点分组串行IO(O(节点数)网络时间),以及多线程并行IO和利用Redis的hash-tag强制key到同一节点。 通过对比可以看出,从“串行mget”到“hash-tag”,核心思路都是尽可能减少网络往返次数。文章最后用清晰的表格总结了各方案的优劣与适用场景,为开发者在数据分散与访问效率之间做出权衡提供了明确参考。

IT 累计浏览 5,347

memcached 源码阅读笔记

这篇讲的是作者深入阅读 memcached 源码后梳理出的核心流程。作者从程序的入口函数 `main()` 出发,剖析了 memcached 如何基于 libevent 构建起高效的事件驱动模型。初始化过程涉及事件中心、内部数据结构、空闲连接池以及工作线程的创建与配置。 文章重点分析了 memcached 两种可配置的服务模式:UNIX 域套接字与 TCP/UDP。前者在本地通信中性能更优,后者则提供了更通用的网络接入能力。两者通过注册 `event_handler()` 回调来处理客户端连接。 在多线程协作方面,文章揭示了一个巧妙的设计:每个工作线程拥有独立的连接队列(CQ)和 libevent 事件中心,并通过创建读写管道进行线程唤醒。主线程通过 `dispatch_conn_new()` 将新连接分发到指定线程的队列,工作线程则监听管道事件,按需取出并执行任务。这种基于事件驱动和管道通信的线程调度机制,保证了高并发下的处理效率。 作者从全局到细节,清晰展现了 memcached 如何用简洁的 C 代码,借助 libevent 实现了一个高性能、多线程的网络服务框架。

IT 累计浏览 3,135

通过FastCGI Cache实现服务降级

这篇讲的是如何在去掉CDN的PHP网站里,通过FastCGI Cache巧妙实现服务降级。背景是项目新增实时需求后架构稳定性下降,但完全重构不现实,因此需要一种尽可能透明的降级方案。 核心思路是在Nginx层利用FastCGI Cache和error_page指令。正常流量时缓存被穿透,保持实时性;一旦后端返回500/502等错误,便通过重写触发降级逻辑,从缓存中提供陈旧内容,从而实现“断尾求生”。文章给出了可直接使用的通用版Nginx配置。 更进一步,作者通过Lua脚本和共享字典实现了“定制版”:能自动统计单位时间内的错误次数,一旦超过阈值(如每分钟1000次),便全局自动激活缓存,无需人工干预。这种从“被动响应错误”到“主动判断系统健康并自动降级”的演进,是方案的亮点所在。

IT 累计浏览 1,610

Solr之缓存篇

这篇讲的是Solr搜索引擎中“看不见”却至关重要的性能支柱——缓存系统。作者没有停留在配置层面,而是直接钻进源码,剖析了Solr四种核心缓存(filterCache、documentCache等)的生命周期是如何被 `SolrIndexSearcher` 牢牢掌控的。 文章清晰地展示了,一次索引提交(commit)如何像一个开关,触发 `getSearcher()` 方法关闭旧的 `IndexReader`,并构建新的 `SolrIndexSearcher`。而新的Searcher一旦构建,它所管理的所有缓存实例便会随之重建。这意味着缓存并非永久存在,其生命周期与底层的索引阅读器严格绑定。 更巧妙的部分在于“预热”机制的设计。文章通过代码片段揭示,当新Searcher被构建时,系统会在后台线程中将老缓存中的热点数据预先加载到新缓存中。这个过程有效避免了缓存“冷启动”带来的性能断崖,确保了搜索服务在索引更新后的平滑过渡。这种从实现原理出发的解读,让读者不仅能配置缓存,更能理解其背后的运行逻辑与优化思想。

IT 累计浏览 5,994

fatcache源码浅析

这篇讲的是Twitter开源的缓存服务fatcache,可以把它理解为一个“SSD版的Memcached”。作者从其源码出发,剖析了它如何用有限的内存索引,去管理大容量的SSD存储。 文章详细解读了fatcache的核心设计。它使用通用的队列(generic queue)来管理资源池,底层则采用了经典的slab allocator内存模型。作者拆解了slabclass、slab和item等关键结构,并说明了fatcache如何在内存中用哈希表快速索引key,而实际的value数据则可能存储在内存或磁盘的slab里。 最精巧的部分在于其读写与淘汰机制。为了适配SSD,fatcache设计了一套基于FIFO的淘汰策略。在写入时,它能将内存中的slab成片地交换到磁盘,巧妙地将随机写转化为顺序写,提升了IO效率。对于删除操作,它只在索引层面标记删除,而不立即修改SSD数据,等待后续自然淘汰,这种设计充分避免了不必要的随机写入。 整个设计体现了对硬件特性的深刻理解,用相对简单的队列和slab管理,在缓存层实现了高效的数据存取。

IT 累计浏览 17,320

浅析http协议、cookies和session机制、浏览器缓存

这篇讲的是从实际网站数据出发,拆解HTTP协议中几个关键但常被忽略的环节。作者从QQ空间的完整请求与响应头入手,直观展示了HTTP交互的全貌,比如请求行、状态行以及各头域的格式与作用。文章的核心在于实践对比,作者测试了包括CSDN、腾讯、新浪、百度在内的十余家主流网站,深入分析了`Connection`、`Content-Encoding`、`Server`、`Cache-control`等头域的具体表现。例如,为什么腾讯、新浪等部分大型网站会使用`Connection: close`而非默认的长连接?`Server`头域如何暴露了网站使用的服务器信息(如腾讯内部的QZHTTP、淘宝的Tengine),这又带来了哪些安全考量?这些对比都给出了作者的分析。更重要的是,文章并未止步于分析,而是提供了对应的PHP实现代码,比如如何通过`header()`函数设置`Connection`、`Cache-control`、`Last-Modified`,以及如何利用`if-modified-since`实现304缓存判断。整篇文章将理论知识与大站的实际运维策略、具体的编码实践紧密结合,对于想深入理解HTTP机制并应用于开发的读者来说,提供了非常具象的参考。

IT 累计浏览 2,902

有关Cache 2 - 基本结构

这篇讲的是《计算机体系结构量化方法》一书中关于Cache原理的部分章节。作者分享了阅读附录B后的感悟,认为书中将Cache比喻为“一种将小而快的存储器与大而慢的存储器结合使用的巧妙机制”这一描述非常精准。 文章从一个常见误区切入:我们往往笼统地说Cache能提升性能,但它具体是怎么提升的?书中一句话点明了关键:Cache对“时延”和“带宽”的改善是分离的。Cache通过提供靠近CPU的快速存储,极大地降低了数据访问的“时延”(第一个比特到达的时间);而其通过预取和块传输的设计,又在一定程度上保证了后续数据传输的“带宽”。 作者特别欣赏这种化繁为简的论述方式。通过这个清晰的视角,Cache不再是一个模糊的“加速器”,而是一个在成本、容量与性能之间进行精细权衡与协同设计的系统核心部件。这种理解方式,能让工程师在架构设计和性能分析时,有更明确的思考方向。

IT 累计浏览 2,304

Google Guava V11 中的Cache操作

这篇讲的是 Java 生态中广受欢迎的本地内存缓存组件 Google Guava Cache,并聚焦于 V11 版本带来的核心操作与新特性。作者从实际应用场景出发,清晰地拆解了 Guava Cache 的主要功能点:它不仅仅是一个简单的键值存储,更提供了基于容量、时间、引用等多种灵活的驱逐策略,确保缓存既能高效利用内存,又能保持数据的“新鲜度”。 文章特别提到了 V11 版本中引入的重要增强,比如新增的 `RecordStats` 统计功能,能让你轻松监控缓存的命中率、加载耗时等关键指标,这对于性能调优至关重要。同时,也对 CacheBuilder 的构建方式做了细致讲解,展示了如何通过流畅的 API 链式配置出满足业务需求的缓存实例。 对于开发者而言,这篇文章的价值在于它不仅解释了“是什么”,更侧重于“怎么用”和“为什么好”。它帮助读者理解,Guava Cache 如何以极低的集成成本,为单机应用提供高性能、细粒度控制的缓存能力,尤其适用于需要快速访问且允许短暂不一致的场景。如果你正在设计本地缓存方案,文章中对策略选型的讨论会提供直接的参考。

IT 累计浏览 2,947

深入浅出Flashcache(三)

这篇是“深入浅出Flashcache”系列的第三篇,作者在回顾了block device和device mapper的基础概念后,将话题转向Linux内核模块编写的基础知识。由于Flashcache本身是一个内核模块,要真正理解其源码实现,必须先掌握内核编程的基本框架,因此这一篇专注于讲解模块的加载机制、核心结构和编写要点。作者以自谦的门外汉视角,现学现卖地梳理了module_init和module_exit宏的作用、模块参数的定义方式,以及内核模块的常见结构。虽然对于已经熟悉内核开发的读者来说,这些内容可能显得浅显,但它为整个系列后续深入分析Flashcache的代码扫清了必要的障碍。通过这篇铺垫,读者能更顺畅地跟随作者进入Flashcache的技术深水区,理解它如何在内核层与块设备交互并实现缓存功能。

IT 累计浏览 5,687

分享会-高性能nosql数据库redis

这篇分享会的内容聚焦于Redis高性能的底层原因,并穿插了几个关键知识点的截图讲解。作者从Redis作为内存数据库的核心优势出发,解释了它为什么能在高并发场景下保持极低的响应延迟。文章并未停留在概念层面,而是具体点出了几个实现高性能的关键设计:比如基于内存的原子操作、丰富的数据结构如何避免不必要的网络开销和序列化损耗、单线程模型如何简化并发控制并充分利用现代CPU的缓存特性,以及RDB和AOF两种持久化机制在性能与安全之间的权衡。 分享还涉及了Redis在实际业务中的典型应用场景与配置建议。它帮助读者理解,选择Redis不仅是选择一个缓存工具,更是选择了一种“数据结构化、操作原子化、存储内存化”的高效设计思维。对于正在考虑技术选型或优化现有系统数据层的工程师,这些提炼出的设计原则和实战经验,提供了清晰的决策依据。

IT 累计浏览 3,525

Cache 文件是否存在的查询

这篇讲的是如何高效检查 Squid 缓存中是否存在大量文件的问题。作者从日常运维中常见的痛点出发:用 `wget -S` 查看单个文件缓存状态虽然直观(看到 HIT 即命中),但一旦文件数量达到百万级别,逐个下载确认的效率就太低了。于是有人想到用 `curl` 发送 HTTP HEAD 请求来快速验证,避免了完整的下载过程。但文章并未止步于此,而是进一步探讨了这种看似更优的方法背后隐藏的实际问题——它可能仍然不够快,并且会引发其他需要考虑的因素。文章通过这个具体的技术点,引导读者思考工具选择与批量操作场景下的性能平衡。

IT 累计浏览 7,886

TT的作者出新作品鸟:kyoto tycoon

这篇讲的是知名开源项目Tokyo Tyrant作者的最新动作。作者在之前推出性能出色的Tokyo系列后,这次带来了基于Kyoto Cabinet的新服务端项目:Kyoto Tycoon。 文章清晰地梳理了这几件作品间的关系:Kyoto Cabinet之于Tokyo Cabinet,正如Kyoto Tycoon之于Tokyo Tyrant。对于熟悉Tokyo Tyrant的开发者来说,这基本指明了Kyoto Tycoon的定位——一个高性能的Key-Value存储服务。作者还提供了Kyoto Tycoon官方技术规格页的翻译链接,便于读者直接查看其功能特性与设计细节,快速判断它是否适合自己的技术场景。

IT 累计浏览 3,582

一个cache的改造过程

这篇讲的是一个缓存架构改造的完整过程。作者团队在原有系统中遇到了经典的缓存三问:缓存命中率上不去、缓存与数据库双写一致性难保证,以及突发流量下缓存可能被击穿。针对这些问题,他们没有采用单一的解决方案,而是从数据结构、同步策略和防护机制三个层面进行了系统性重构。 核心改造思路清晰:首先,将缓存的数据结构从简单的K-V存储,优化为包含热数据标识和过期时间元数据的复合结构,为后续策略打下基础。其次,放弃了成本较高的“先删缓存再更新数据库”方案,改用基于消息队列的异步订阅重删策略,显著降低了在高并发下出现数据不一致的概率。最后,为应对热点Key问题,引入了本地缓存作为二级屏障,形成了“本地缓存+分布式缓存”的多级防护体系。 从结果上看,改造后该系统的缓存命中率从85%提升至99%以上,核心接口的平均响应时间下降了约40%,且在压测中成功抵御了原先会导致雪崩的瞬时流量。整个过程不是简单地替换组件,而是对缓存作用的再思考,其分层解决问题的思路,对面临类似挑战的团队很有参考价值。

IT 累计浏览 4,409

[Squid] TCP_MEM_HIT 和 TCP_HIT 的性能到底相差多远

这篇讲的是 Squid 缓存中两种不同命中机制——TCP_MEM_HIT 和 TCP_HIT——的性能对比。作者直接切入核心问题:当请求在 Squid 自身的内存缓存中命中,与在操作系统层面的文件系统缓存中命中时,性能差距究竟有多大? 文章对这两种机制进行了拆解。TCP_MEM_HIT 意味着数据直接从 Squid 管理的内存区域返回,路径最短。而 TCP_HIT 则指数据从磁盘文件中读取,可能借助了操作系统的文件缓存。作者通过实际测试或理论分析,量化了两者在响应延迟和吞吐量上的具体差异,得出了明确的性能对比结论。 更重要的是,文章不仅给出了数据,还分析了差异背后的原因以及各自的适用场景。比如,内存缓存虽然更快但容量有限、成本高,适合缓存最关键、最热的数据;而文件系统缓存容量更大,是更经济的通用缓存方案。这种对比为运维人员在配置 Squid 缓存策略时提供了明确的依据,帮助他们在性能和成本之间做出更优的权衡。

IT 累计浏览 6,046

学习:一个并发的Cache

这篇讲的是作者从实际需求出发,设计并实现了一个线程安全的缓存包装器 Memoizer。文章的核心在于展示如何利用 Java 的并发工具,优雅地解决“为计算结果缓存”场景下的并发问题。 作者没有选择简单的加锁,而是基于 ConcurrentHashMap 和 FutureTask,构建了一个精妙的方案。当多个线程同时以相同参数调用 compute 时,Memoizer 确保只有第一个线程会真正执行耗时的计算,并将代表该计算结果的 FutureTask 存入缓存。后续线程则直接获取这个 FutureTask,并通过 f.get() 等待结果,从而避免了重复计算。 实现的巧妙之处在于 putIfAbsent 原子操作的运用,它确保了“检查-插入”过程的线程安全。同时,将 FutureTask 作为缓存值,使得计算可以异步进行,而其他调用者可以无阻塞地获取 Future,只是在真正需要结果时才会等待。代码也妥善处理了计算任务被取消或抛出异常的情况,体现了健壮性。 这个实现为我们提供了一个在并发环境下构建高效、线程安全缓存的范本,其思路在优化服务接口性能、避免资源浪费的场景中非常具有启发意义。

IT 累计浏览 5,524

[调优] Squid 不同版本的性能对比

这篇讲的是Squid代理服务器在不同版本间的性能对比测试。作者从实际调优需求出发,对目前所有标准版本进行了系统的横向对比,重点剖析了Squid 2.7与Squid 3.1这两代常用版本在性能表现上的具体差异。 文章的测试方法颇具参考价值:在每一次不同配置或版本的测试前,都会严格清空cache_dir中的所有缓存对象,确保了测试起点的一致性与结果的可靠性。这种严谨的实操细节,对于想要复现或设计类似性能测试的工程师来说尤为有用。 核心结论指向了版本选择对实际应用场景的影响。虽然更具体的性能数据需参阅正文,但文章明确了版本迭代带来的变化。例如,对于需要处理高并发连接的场景,新版本可能在资源管理或协议支持上有所优化;而对于追求稳定性和特定功能兼容性的环境,旧版本或许仍有其立足之地。这为技术选型提供了直接的依据,而不仅仅是理论上的版本号变化。

IT 累计浏览 2,283

Nc 的妙用

这篇讲的是一个非常实用的网络技巧——如何利用 `nc`(Netcat)命令来快速清空 Memcache 缓存。作者从运维中经常遇到的缓存清理需求出发,介绍了 `nc` 这个通常被称为“网络瑞士军刀”的工具在其中的妙用。 通常,我们清空 Memcache 需要编写脚本或使用专用客户端连接逐一删除键值,过程相对繁琐。而文章的核心思路非常巧妙:直接利用 `nc` 作为底层的、轻量级的 TCP 客户端,向 Memcache 服务发送 `flush_all` 这条管理命令。整个操作只需一行简洁的命令,就能瞬间重置缓存内容,实现了“快刀斩乱麻”的效果。 文章不仅给出了具体的命令示例,也点明了其背后的原理——`nc` 帮我们处理了与 Memcache 服务器建立 TCP 连接和发送原始协议命令的所有细节。这种方法特别适用于临时调试、开发环境快速重置,或者在自动化脚本中集成简单的缓存管理动作。它展示了用对工具,能让一些看似常规的运维操作变得异常高效。

IT 累计浏览 10,905

淘宝图片存储架构

这篇讲的是作者花一小时阅读章文嵩博士的《淘宝海量图片存储与CDN系统》后的学习心得。作者坦言自己没有大容量存储或分布式应用的实战经验,但这次阅读让他从宏观角度思考了未来可能的学习路径。 淘宝图片存储架构的核心挑战在于处理海量图片的存储和高效分发。面对每天数亿张图片的上传与访问,系统