---
title: "多级缓存 | OceanBase 文档中心"
description: 多级缓存 OceanBase 数据库的 Cache 设计与 MySQL 数据库相比有很大的不同。由于 OceanBase 数据库的存储引擎是基于 LSM-tree 架构的，所有的修改只会写入 MemTable，而 SSTable 是只读的，这就意味着 OceanBase 数据库的 Cache 是一个只读 Cache，…
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*P8CuR4UJ_FkAAAAAAAAAAAAADiGDAQ/original) OceanBase 数据库分布式版 - V 3.1.4 社区版

# 多级缓存

更新时间：2023-08-03 17:20:32

[编辑](https://github.com/oceanbase/oceanbase-doc/edit/V3.1.4/zh-CN/1500.oceanbase-database-overview/1100.storage-architecture/400.multi-level-caches.md)  

OceanBase 数据库的 Cache 设计与 MySQL 数据库相比有很大的不同。由于 OceanBase 数据库的存储引擎是基于 LSM-tree 架构的，所有的修改只会写入 MemTable，而 SSTable 是只读的，这就意味着 OceanBase 数据库的 Cache 是一个只读 Cache，没有刷脏页的相关逻辑，这相对于传统数据库来说会简单一些；但同时我们对存储在 SSTable 内的数据会进行数据编码和压缩，这意味着我们需要存储的数据是变长而非定长的，和传统数据库相比 Cache 的内存管理又要复杂很多。除此之外，OceanBase 数据库还是一个面向多租户的分布式数据库系统，除了和传统数据库一样要处理 Cache 的内存淘汰之外，在 Cache 内部还需要进行多租户的内存隔离。

与 MySQL 数据库类似，在 OceanBase 数据库内部，也会有很多种不同类型的 Cache，除了用于缓存 SSTable 数据的 Block Cache（类似于 MySQL 数据库的 buffer cache）之外，还有 row cache（用于缓存数据行）、log cache（用于缓存 redo log）、location cache（用于缓存数据副本所在的位置）、schema cache（用于缓存表的 Schema 信息）、bloom filter cache（用于缓存静态数据的 bloomfilter，快速过滤空查）等等。OceanBase 数据库设计了一套统一的 Cache 框架，所有不同租户的不同类型的 Cache 都由框架统一管理。对于不同类型的 Cache，会配置不同的优先级，不同类型的 Cache 会根据各自的优先级以及数据访问热度做相互挤占；对于不同租户，会配置对应租户内存使用的上限和下限，不同租户的 Cache 会根据各自租户的内存上下限以及 Server 整体的内存上限做相互挤占。

![缓存](https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/3173623461/p351813.jpg)

上图以一个典型的 table get 示例了 OceanBase 数据库中目前服务于查询流程的各种 cache。

- BloomFilter Cache

  OceanBase 数据库的 BloomFilter 是构建在宏块上的，根据用户实际空查率按需自动构建，当一个宏块上的空查次数超过某个阈值时，就会自动构建 BloomFilter，并将 BloomFilter 放入 Cache。
 - Row Cache

  针对每个 SSTable 缓存具体的数据行，在进行 Get/MultiGet 查询时，可以将对应查到的数据行放入 Row Cache，这样在下次走到对应行查询时就可以避免多次二分定位对行的查找。
 - Block Index Cache

  缓存微块的索引，因为每个 SSTable 虽然以宏块组织，但是 2M 的粒度对于用户查询来说往往粒度太大，因此需要根据用户查询的范围在宏块中定位实际需要的微块，微块索引就是描述对每个宏块中所有的微块的范围，当需要访问某个宏块的微块时，需要提前装载这个宏块的微块索引，因为进行了前缀压缩，因此大小通常较小，并且在 OceanBase 数据库内部给予其较高优先级，因此一般命中率较高。
 - Block Cache

  OceanBase 数据库缓存具体的数据微块，每个微块都会解压后装载到 Block Cache 中, 因此每个 cache 大小都是变长的。
 - Fuse Row Cache

  在 LSM-Tree 架构中, 同一行的修改可能存在于不同的 SSTable 中，OceanBase 数据库为了进一步优化存储占用，每次用户的更新都只会存储增量数据，因此在查询时需要对各个 SSTable 查询的结果进行熔合，当用户不再触发新的更新时，这个熔合结果对查询都是一直有效的，因此 OceanBase 数据库也提供了对于熔合结果缓存的 Fuse Row Cache，更大幅度支持部分用户的热点行查询。

OceanBase 数据库除了以上用户查询相关的多级缓存之外, 还支持多种更多不同类型的 cache，例如：

- Partition Location Cache：用于缓存 Partition 的位置信息，帮助对一个查询进行路由。
 - Schema Cache：缓存数据表的元信息，用于执行计划的生成以及后续的查询。
 - Clog Cache：缓存 clog 数据，用于加速某些情况下 Paxos 日志的拉取。
 - ......

为了能够更加通用的支持这么多种类的 Cache，需要处理变长数据的问题，OceanBase 数据库的底层 Cache 框架将内存划分为多个 2MB 大小的内存块，对内存的申请和释放都以 2MB 为单位进行。变长数据被简单 pack 在 2MB 大小的内存块内。为了支持对数据的快速定位，在 Hashmap 中存储了指向对应数据的指针，整体结构如下图所示。

![缓存2](https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/3173623461/p351824.jpg)

Cache 内存是以 2MB 为单位整体淘汰的，OceanBase 数据库会根据每个 2MB 内存块上各个元素的访问热度为其计算一个分值，访问越频繁的内存块的分值越高，同时有一个后台线程来定期对所有 2M 内存块的分值做排序，淘汰掉分值较低的内存块。对于一个整体分值不高但是内部存在热点数据的 2MB 内存块，OceanBase 数据库会将其热点数据从它所在的"冷块"移动到"热块"中，避免热点数据被淘汰。在数据结构上并没有维持类似于 MySQL 的 LRU 链表，因此对于数据读取，OceanBase 数据库的 Cache 访问几乎是无锁的（除了 HashMap 上的 Bucket 锁之外），对于热点数据的高并发访问更加友好。在淘汰时，我们会考虑租户的内存上限及下限，控制各个租户中 Cache 内存的用量。

 上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
