本文内容
1. count() 的实现方式
在 MySQL 中,不同的存储引擎对 count() 有不同的实现方式:
- MyISAM 把表的总行数保存在了磁盘上,因此执行 count() 时可以直接返回,性能很高;
- InnoDB 在执行 count() 时需要把数据一行一行地从引擎里读取出来,然后在 server 层计数统计。
在 MySQL 中,不同的存储引擎对 count() 有不同的实现方式:
首先来看看 Redis 和不同对象进行交互时发生的操作:
当 Redis 需要保存大量数据时,一般都有两种方案,纵向扩展(scale up)和横向扩展(scale out):
前言
在 哨兵机制:主库挂了怎么办 中简单介绍了哨兵机制,它其实是由多个哨兵实例组成的 哨兵集群,所以即使有实例出现故障,其他哨兵还能继续完成 主从库切换 的工作,包括 判定主库是否下线、选择新主库、通知从库和客户端。
这篇文章就来看看,哨兵集群是如何组成、如何运行的。
在主从库集群模式下,如果从库发生故障,客户端还可以向主库和其他从库发送请求,不会影响到可用性。但如果主库发生故障,就会影响从库的数据同步,以及写操作无法进行了,因为主从模式采用的是读写分离。
而 从库无法同步数据,写操作无法执行,这两个都是不能接受的,严重影响到了集群的可用性。
因此,当主库挂了后,就需要重新来一个新主库,比如把一个从库切换为主库。
Redis 提供了 AOF 日志、RDB 快照,以及混合持久化的持久化方式,可以保障 Redis 的可用性。但是只有持久化是不够的,如果只运行了一个 Redis 实例,当这个实例宕机后,该 Redis 就无法向外提供服务了。
其实,Redis 的高可用性主要体现在两个方面,一是 数据尽量少丢失,二是 服务尽量少中断。所以只有持久化方式是不够的,还需要保证 一台 Redis 实例宕机后,还有其他的实例来继续提供服务,也就是 增加副本冗余量,将一份数据同时保存到多个实例上。
在上一章中讲解了 Redis 的一种持久化方案 — AOF 日志,它记录了操作的命令,在 AOF 文件过大时会进行 AOF 重写来压缩文件;而且提供了三种刷盘策略,来保证数据丢失和阻塞主线程之间的平衡。那为什么还需要 RDB 快照呢?
这就要从 AOF 日志的格式说起,AOF 日志中记录的是 逻辑日志,而 不是实际的数据,所以使用 AOF 进行故障恢复时,需要把日志命令都执行一遍,如果日志很多,Redis 恢复的时间就会很长,影响正常使用。这时候就需要 RDB 快照了。
上一篇文章中说到,RDB 快照的最大优势是恢复速度快,但快照的频率不好控制;AOF 快照的最大优势是丢失数据少,但恢复速度较慢。
Redis 4.0 中提出的 混合持久化 既能利用 RDB 的快速恢复优势,又能以较小的开销做到尽量少丢数据。
下面就来看看混合持久化到底是什么,是如何做到的上面效果的。
前言
我们都知道,Redis 是 内存数据库,而内存有个很明显的缺陷,就是 数据断电即失,所以一旦 Redis 服务器宕机,其中的数据将全部丢失。
虽然我们通常只是用 Redis 来做一层缓存,真正的数据还是保存到具有持久化机制的后端数据库中的,但 如果从后端数据库中恢复缓存中的所有数据,会给数据库带来很大的压力,而且速度也慢,这会使得客户端响应速度变慢。
而且对于一些对数据没有那么敏感的程序,把数据只保存到 Redis 中也不是没有,因此 Redis 的持久化尤为重要。
Redis 持久化机制主要有两个,分别是 AOF 日志和 RDB 快照。本文就先来介绍第一个 AOF 日志。
我们经常说 Redis 是单线程的,但实际上只是 网络 IO 和 对键值对的读写 是 单线程完成。而其他功能,例如 持久化、异步删除、集群数据同步 等,是由 额外的线程 来完成的。
而且 在 Redis 6.0 时,网络 IO 也使用了多线程来处理,后面会详细介绍。