数据库缓存,缓存机制详解

4747 2658 2023-06-09

本文讲述了数据库缓存,缓存机制详解

什么是数据库缓存?

这里讲的缓存是数据库本身的缓存,并不是外部缓存例如Redis/Memcache等等。

数据库的数据分为冷数据和热数据库,通俗的讲冷数据是存储在磁盘上不经常查询的数据;而热数据是频繁查询的数据,这部分数据会被缓存到内存中。

为什么缓存数据呢?

因为频繁查询相同结果集的数据时,每次到磁盘上查找数据是非常耗时的,所以数据库将频繁查询且返回相同结果集的数据放到内存中,可以减少磁盘访问操作。

什么时候使用数据库缓存

频繁访问且返回相同结果集的情况下使用缓存。

偶尔查询一次且间隔时间较长的情况下不要使用缓存。

尺寸较大的结果集不建议使用缓存,因为数据太大太大,缓存不足以存储,会导致频繁载入与销毁,命中率低。

通常数据库默认情况是开启缓存的,也就是说正常的select查询,如果符合缓存规则就会经过缓存。

当一条SQL查询时如果结果集在内存中称作“命中”

涉及缓存的地方有哪些

数据库本身,查看数据库缓存状态

数据库应用程序接口(ODBC、JDBC......)

谁来控制数据库缓存

通常DBA只能控制数据库缓存是否开启,分配多少内存给缓存使用,过期销毁时间,以及策略等等.

上面我已经说过,通常数据库默认都开启缓存,所以更多的时候我们的操作是禁用缓存。这就需要开发人员来通过特定的SQL操作来控制数据库缓存。

怎么控制数据库缓存

以 MySQL 为例

image.png

编辑 my.cnf 文件,加入配置项 query_cache_type=1 然后重启mysql服务

image.png

query_cache_type | ON 表示缓存已经开启。

SQL_CACHE 缓存

默认情况 select 查询操作只要符合数据库缓存规则那么结果集就会被缓存,如果你的数据库没有开启缓存,请参考下面

image.png

例 13.1. 演示 SQL_CACHE

image.png

我们可以看到 Qcache_queries_in_cache 值由0转为1表示缓存已经生效。

禁止缓存 SQL_NO_CACHE

这里我们主要讲怎样禁止缓存,使查询出的结果集不进入缓存。

image.png

下面的用法比较安全,切换到其他数据库也能正常工作

image.png

例 13.2. 演示 SQL_NO_CACHE

image.png

使用 sql_no_cache 查询 Qcache_queries_in_cache 值始终是 0

关闭缓存 set session query_cache_type=off

我们使用 set session query_cache_type=off 可以关闭本次查询缓存。

image.png

例 13.3. 演示 query_cache_type=off 关闭查询缓存

image.png

一、MyBatis 缓存机制概述

在我们常见的 OLTPQ (on-line transaction processing,联机事务处理)类型的 Web 应用中,性能的颈往往来源于数据库查询,因为应用服务器层面可以水平扩展,但是数据库是单点的,很难水平扩展,当数据库服务器发生磁盘 0,往往无法有效提高性能,因此如何有效降低数据库查询频率,减轻数据库磁盘 0 压力,是 Web 应用性能问题的根源之-

对象缓存是所有缓存技术当中适用场景最广泛的,即使在实时性要求很高的 OLTP 应用中,我们依旧可以使用,而且好的 ORM 实现,对象缓存是完全透明的,完全不需要程序代码进行硬编码。

Mybatis 作为目前流行的 ORM 持久层框架,与其他 ORM 架一样,也提供了缓存机制,用以提高查询的效率、减少数据库压力。在日常工作中,开发人员多教情况下是使用 MyBatis 的默认缓存配置就已经足够了,但是 Mybatis 的缓存机制并不完美,本身还存在着很多问题,还需要我们深入了解其内在机制原理才行。

uyhats 的缓存分为两级:一级缓存,二级缓存,一级缓存被称为 Salssi0n 级到的缓存,缓存的数提只车 SaSessin 内有效,二级缓有被称为表(mapper) 级缓存,同一个 namespace 共用这一个缓存,所以对 SqlSession 是共享的。

二、一级缓存和二级缓存

1.一级缓存

MyBatis 的一级缓存是 SalSession 级别的缓存,在操作数据库的时候需要先创建 SaSession 会话对象,在对象中有一 HashMap 用于存储缓存数据,此 HashMap 是当前会话对象私有的,别的 SglSession 会话对象无法访问。

image.png

具体流程:

第一次执行 select 完毕会将查到的数据写入 SglSession 内的 HashMap 中缓存起来

第二次执行 select 会从缓存中查数据,如果 selet 相同切传参数一样,那么就能从缓存中返回数据,不用去数据库了,从而提高了效率。

注意事项:

如果 SalSession 执行了 DML操作 (inset, update、delete),并commit了,那么 mybatis 就会清空当前 SalSession 缓存中的所有缓存数据,这样可以保证缓存中的存的数据永远和数据库中一致,避免出现脏读;当一个 SalSession 结束后那么他里面的一级缓存也就不存在了,Mybatis 默认是开启一级缓存,不需要配置:MyBatis 的缓存是基于[namespace:sa语句:参数来进行缓存的,意思就是,SqlSession 的 HashMap存储缓存数据时,是使用

namespacesql参数] 作为 key,查询返回的语句作为 value 保存的

2.二级缓存

二级缓存是 mapper 级别的缓存,也就是同一个namespace 的 mappe.xml,当多 SalSessin 使用同一个 Mapper 操作数据库的时候,得到的数据会缓存在同一个二级缓存区域二级缓存默认是没有开启的。需要在 setting 全局参数中配置开启二级缓存。

image.png

在还需要使用二级缓存的 Mapper 配置文件中加入 <cache> 标签

image.png

cache 标签的一些属性:

eviction 属性: 缓存回收策略 (默认的是 LRU)

LRU (Least Recently Used) - 最近最少使用的: 移除最长时间不被使用的对象

FIFO (First in First out) - 先进先出: 按对象进入缓存的顺序来移除它们。

SOFT-软引用: 移除基于垃圾回收器状态和软引用规则的对象。

WEAK-弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象

fushlnterval 属性:刷新间隔,单位毫秒,默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。size 属性: 引用数目,正整数,代表缓存最多可以存储多少个对象,太大容易导致内存溢出

readOnly 属性: 只读,true/false

true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。

false: 读写缓存;会返回缓存对象的拷贝 (通过序列化)。这会慢一些,但是安全,因此默认是 false.

如果我们是基于注解形式进行查询,可以在 mapper 查询接口上添加 @CacheNamespace 注解开启二级缓存,后面可以带参数指定加载自定义的缓存实现类:

image.png

具体流程:

当一个 Salseesion 执行了一次 select 后,在关闭此 session 的时候,会将查询结果缓存到二级缓存:当另一个 Salsession 执行 select时,首先会在他自己的一级缓存中找,如果没找到,就回去二级缓存中找,找到了就返回,就不用去数据库了,从而减少了数据库压力提高了性能

注意事项:

如果 SalSession 执行了 DML 操作 (insert、 update、 delete),并 commit了,那么 Mybatis 就会清空当前 mapper 缓存中的所有缓存数据,这样可以保证缓存中的存的数据永远和数据库中一致,避免出现脏读。MyBatis 的缓存是基于[namespace:sal语句:参数]来进行缓存的 (一二级缓存命名相同),竟思就是,SalSession 的 HashMap 存储缓存数据时,是使用[namespace:sal:参数]作为 key,查询返回的语句作为 value 保存的.

上文就是小编为大家整理的数据库缓存,缓存机制详解。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Apache IoTDB 随笔 - Time Series DBMS 综述
下一篇:数据库的存储原理,数据的存储结构包括哪些
相关文章