为了改进其Android应用中的图像缓存管理机制,Grab的工程师们从使用“最近最少使用”缓存策略,改用了“基于时间的最近最少使用”缓存策略。这一改变使他们能够更有效地释放存储空间,同时不会影响用户体验或增加服务器成本。 Grab的Android应用主要使用Glide作为图像加载框架,并配置了LRU缓存机制,以便将图像缓存在本地,从而减少网络请求次数、提升加载速度并降低服务器成本。然而分析结果显示,使用100MB大小的LRU缓存存在明显缺陷:对于许多用户来说,该缓存很快就会被填满,从而导致性能下降;而在某些情况下,如果缓存大小从未超过限制,图像可能会被缓存数月之久,从而造成存储空间的浪费。 为了解决这些问题,他们决定在LRU缓存机制中加入基于时间的过期机制。TLRU缓存使用了三个关键参数:有效期,用于确定缓存条目何时会失效;最小缓存大小阈值,确保即使某些图像已经过期,但当缓存空间不足时,这些图像仍能被保留;最大缓存大小,则用于限制缓存的总容量。 Grab的工程师们并没有从头开始开发TLRU缓存机制,而是选择在Glide的基础上进行扩展,具体是通过修改其DiskLruCache实现来达到这一目的。他们之所以选择这种方式,是因为Glide已经具备“成熟且经过充分测试的基础架构”。
这种实现方式在整个Android生态系统中被广泛采用,它能够处理诸如崩溃恢复、线程安全性以及性能优化等复杂问题,而这些问题的解决需要耗费大量的开发精力。
为了使DiskLruCache机制满足新的需求,他们需要在三个方面对其进行扩展:首先是要添加支持,以便记录图像的最后访问时间;其次是要实现基于时间的缓存淘汰逻辑;最后则是要为现有的用户缓存数据提供迁移方案。 记录图像的最后访问时间对于按照访问时间顺序对缓存条目进行排序至关重要,而且这些信息还需要在应用重启后依然保持有效。基于时间的缓存淘汰逻辑会在每次访问缓存时被执行,以检查那些最近未被访问的缓存条目是否已经过期,然后再将其删除。而在处理现有缓存的迁移问题时,最大的挑战在于如何为每个缓存条目分配正确的最后访问时间戳。由于文件系统API无法提供可靠的时间戳生成方式,Grab的工程师们决定为所有缓存条目都统一分配一个迁移时间戳。
这种处理方法能够确保所有被缓存的图像数据都不会丢失,并且能够维持数据的一致性。不过,要完全发挥缓存淘汰机制的作用,还需要等待一个完整的有效期周期。此外,我们还保证了系统的双向兼容性——原有的LRU缓存实现可以通过忽略时间戳后缀来读取TLRU缓存中的数据,这样在需要时就可以安全地恢复到原来的配置状态。

另一个挑战在于寻找最佳配置参数,而这些参数的确定需要通过受控实验来获得。

我们的评估标准是:在转向TLRU机制的过程中,缓存命中率下降幅度不得超过3个百分点。例如,如果缓存命中率从59%降至56%,那么服务器请求量将会增加7%。这一标准能够在存储优化与可接受的性能影响之间取得平衡。

采用这种方案后,95%的应用程序用户发现他们的缓存大小减少了50MB,而排名前5%的用户所获得的节省幅度甚至更大。根据这些结果,Grab的工程师们估计:他们可以在不增加服务器成本的情况下,让所有设备上的存储空间释放出数TB的容量,同时仍能将缓存命中率控制在可接受的范围内。

原始文章对LRU机制的工作原理以及TLRU技术的实现方式提供了非常详细的信息,这些内容在这里是无法完全涵盖的。因此,请务必阅读原文以获取全部细节。

Comments are closed.