后端与系统架构图文讲义3290 字

京东内部缓存应用最佳实践

·全库 587 / 611

《京东内部缓存应用最佳实践》共 8 页、0.3 万字,通篇围绕 缓存、Redis、并发、数据库 展开,归在「后端与系统架构」这一层。

覆盖缓存Redis并发数据库成本场景

适合给 AI 系统搭底座、要管得住的人

目录骨架(7 节)
  1. 性能优化:不得不说的缓存技巧
  2. 二从堆内存到直接内存
  3. 内存管理
  4. 2 伪共享 false sharing
  5. 2 读写的性能提升
  6. 性能考量
  7. 3 伪共享解决方案

原 PDF 已逐页还原成图,共 8 页,这里先放前 3 页,其中 1 页识别出了标题。右侧文字由 OCR 按版面重排,可能有个别错字,以图为准;点图可全屏放大。

本讲义目录 · 3 页
  1. 01性能优化:不得不说的缓存技巧
  2. 022 读写的性能提升
  3. 03避免短期大量失效 在一些场景中,程序…
011 / 3
第 1 页:性能优化:不得不说的缓存技巧
第 1 页

性能优化:不得不说的缓存技巧

利用缓存做性能优化的案例非常多,从基础的操作系统到数据库、分布式缓存、本地缓存等。它们表现 形式各异,却有着共同的朴素的本质:弥补 CPU 的高算力和 I0 的慢读写之间巨大的鸿沟。 和架构选型类似,每引入一个组件,都会导致复杂度的上升。以缓存为例,它带来性能提升的同时,也 带来一些问题,需要开发者设计和权衡。 思维脉络如下:

缓存带来的问题和解决方案 缓存 缓存带来的提升 读写的性能 问题 接口 RT 应用的 QPS

一致性问题

方案 缓存设计模式 直接内存

一缓存和多级缓存 1 缓存的引入

在初期业务量小的时候,数据库能承担读写压力,应用可以直接和 DB 交互,架构简单且强壮。 经过一段时间发展后,业务量迎来了大规模增长,此时 DB 查询压力和耗时都在增长。此时引入分布式缓 存,在减少 DB 压力的同时,还提供了更高的 QPS。 再往后发展,分布式缓存也成为了瓶颈,高频的 QPS 是一笔负担;另外缓存驱逐以及网络抖动会影响系统 的稳定性,此时引入本地缓存,可以减轻分布式缓存的压力,并减少网络以及序列化开销。

1.0 时代,请求量小,DB 可以承担压力 2.0 时代,请求量暴增,DB 不堪重负,引入内存数据库做缓存

App

Load Balance Load Balance App RMDB Actor Actor App

3.0 时代,请求量再次暴場,MEM DB 压大.应用 RT 不达标,引入本地缓存 Local Buffer App

Local Buffer Load Balance App

Local Buffer App

不易察觉的 CPU 缓存

问题

方案 - padding Contended 注解 无锁并发

App

App MEMDB RMDB

App

Mem DB RMDB

022 / 3
第 2 页
第 2 页

2 读写的性能提升

2 读写的性能提升

  • 缓存通过减少 10 操作来获得读写的性能提升。有一个表格,可以看见磁盘、网络的 IO 操作耗时,远高于 内存存取。
  • 读优化:当请求命中缓存后,可直接返回,从而略过 10 读取,减小读的成本。
  • 写优化:将写操作在缓冲中合并,让 IO 设备可以批量处理,减小写的成本。

缓存

缓存带来的 QPS、RT 提升比较直观,不补充介绍。 3 缓存 Miss 缓存 Miss 是必然会面对的问题,缓存需保证在有限的容量下,将热点的数据维护在缓存中,从而达到性 能、成本的平衡。 缓存通常使用 LRU 算法淘汰近期不常用的 Key。 近似 LRU 可以先试想严格 LRU 的实现。假设 Redis 当前有 50W 规模的 key,先通过 Keys 遍历获得所有 Key,然后比 对出空闲时间最长的某个 key,最后执行淘汰。这样的流程下来,是非常昂贵的,Keys 命令是一笔不小的 开销,其次大规模执行比对也很昂贵。 当然严格 LRU 实现的优化空间还是有的,YY 一下,可以通过活跃度分离出活跃 Key 和待回收 Key,淘汰时 只关注待回收 key 即可;回收算法引入链表或者树的结构,使 Key 按空闲时间有序,淘汰时直接获取。然而 这些优化不可避免的是,在缓存读写时,这些辅助的数据结构需要同步更新,带来的存储以及计算的成 本很高。 在 Redis 中它采用了近似 LRU 的实现,它随机采样 5 个 Key,淘汰掉其中空闲时间最长的那个。近似 LRU 实 现起来更简单、成本更低,在效果上接近严格 LRU。它的缺点是存在一定的几率淘汰掉最近被访问的 Key,即在 TTL 到期前也可能被淘汰。

Guava Caffeine 虚拟机内存

OHC 直接内存

Ehcache memchached Redis

Java BufferedWriter MySQL InnoDB Buffer HBase MemStore SO_RCVBUF、SO_SNDBUF

本地缓存

分类

分布式缓存 应用 多级缓存

文件缓存 分类 网络缓存 应用 Redis 缓冲入账

读缓存 Cache

写缓冲 Buffer

033 / 3
第 3 页
第 3 页

避免短期大量失效 在一些场景中,程序…

Theoretical LRU

Redis 2.8 5 samples

避免短期大量失效 在一些场景中,程序是批量加载数据到缓存的,比如通过 Excel 上传数据,系统解析后,批量写入 DB 和 缓存。此时若不经设计,这批数据的超时时间往往是一致的。缓存到期后,本该缓存承担的流量将打到 DB 上,从而降低接口甚至系统的性能和稳定性。 可以利用随机数打散缓存失效时间,例如设置 TTL=8hr+random (8000)ms。 4 缓存一致性 系统应尽量保证 DB、缓存的数据一致性,较常使用的是 cache aside 设计模式。 避免使用非常规的缓存设计模式:先更新缓存、后更新 DB;先更新 DB、后更新缓存(cache aside 是直接 失效缓存)。这些模式的不一致风险较高。 缓存设计模式 业务系统通常使用 cache aside 模式,操作系统、数据库、分布式缓存等会使用 write throgh、write back。

策略名词 cache aside

write through

write back

cache aside 的缓存不一致 Cache aside 模式大部分时间运行良好,在一些极端场景下,仍可能出现不一致风险。主要来自两方面: 1.由于中间件或者网络等问题,缓存失效失败。

Approx. LRU :10 samples

:Approx. LRU Redis:3.0 5 samples

文字解释 先更新存储,成 功后失效缓存。 同时写缓存和存 储。 只更新缓存,由 缓存主导同步时

典型案例 业务系统

Redis apendfsync 配置 everysec, 每间隔一秒中,调用一次 fsync, 将缓存写入到存储。

例如 Redis apendfsync 配置 no,由 操作系统的 cache 与存储同步。

优缺点

优点:每次写入存储,数据 丢失风险低;缺点:存储交 互较多,性能较差。 优点:可自主选择存储写入 时机,性能较好;缺点:存 在断电数据丢失风险。

资料里没有你的场景?

把你手上的数据和想解决的那个环节发上来,我们按具体情况回,不复述方法论。

发布需求