Redis

Table of Contents

1 Command

  • 启动: redis-server redis.conf
  • 关闭: redis-cli shutdown
  • 客户端连接: redis-cli -h <hostname> -p <port> -a <password>
  • 退出客户端: QUIT
  • INFO
  • CLIENT LIST: 连接的客户端列表
  • DBSIZE: 返回当前数据库的 KEY 的数量
  • MONITOR: 实时打印出 Redis 服务器接收到的命令,调试用
  • redis-cli KEYS "a0002*" | xargs redis-cli DEL: delete keys with pattern
  • FLUSHALL: 清空整个 Redis 服务器的数据
  • FLUSHDB: 清空当前数据库中的所有 key
  • LASTSAVE: 返回最近一次 Redis 成功将数据保存到磁盘上的时间,以 UNIX 时间戳格式表示

2 Redis cluster

2.1 数据分片

集群没使用一致的散列方式,而是使用不同形式的分片,每个 key 在概念上都称为 hash slot 的一部分。

在 Redis 集群中一共有 16384 个 hash slot,根据给定的 key 计算出属于哪一个 hash slot。算法为 =CRC16(key)/16384=。

集群中的每个节点都只负责 hash slot 的自己,因此假设你有 3 个节点的集群:

  • A 节点包含 0~5500 的 hash slot;
  • B 节点包含 5501~11000 的 hash slot;
  • C 节点包含 11001~16383 的 hash slot;

有关一致性 hash 可以查看我之前翻译的这篇文章:https://www.zhangjiee.com/blog/2018/consistent-hashing.html

3 持久化

Redis 有两种持久化的方式:快照(RDB 文件)和追加式文件(AOF 文件):

  • RDB 持久化方式会在一个特定的间隔保存那个时间点的一个数据快照;
  • AOF 持久化方式则会记录每一个服务器收到的写操作。在服务启动时,这些记录的操作会逐条执行从而重建出原来的数据。 写操作命令记录的格式跟 Redis 协议一致,以追加的方式进行保存;
  • Redis 的持久化是可以禁用的,就是说你可以让数据的生命周期只存在于服务器的运行时间里;
  • 两种方式的持久化是可以同时存在的,但是当 Redis 重启时,AOF 文件会被优先用于重建数据;

注意,Redis 一般作为单纯的缓存,也就意味着都是可被重建的数据,所以一般无需持久化(持久化会为运维带来成本)。 还有些公司会将 Redis 作为消息中间件(PUB/SUB),在安全性要求比较高的业务场景下,使用持久化也不咋靠谱, 单点就不说了,Cluster 在添加或者删除节点的时候也有丢失数据的风险,所以高安全性的消息中间件推荐使用 Kafka,而不是 Redis。

下面只是作为知识扩展:

3.1 RDB

优点:

  • RDB 文件是一个很简洁的单文件,它保存了某个时间点的 Redis 数据,很适合用于做备份。 你可以设定一个时间点对 RDB 文件进行归档,这样就能在需要的时候很轻易的把数据恢复到不同的版本;
  • 基于上面所描述的特性,RDB 很适合用于灾备。单文件很方便就能传输到远程的服务器上;
  • RDB 的性能很好,需要进行持久化时,主进程会 fork 一个子进程出来, 然后把持久化的工作交给子进程,自己不会有相关的 I/O 操作;
  • 比起 AOF,在数据量比较大的情况下,RDB 的启动速度更快;

缺点:

  • RDB 容易造成数据的丢失。假设每 5 分钟保存一次快照,如果 Redis 因为某些原因不能正常工作,那么从上次产生快照到 Redis 出现问题这段时间的数据就会丢失了;
  • RDB 使用 fork() 产生子进程进行数据的持久化,如果数据比较大的话可能就会花费点时间,造成 Redis 停止服务几毫秒。如果数据量很大且 CPU 性能不是很好的时候,停止服务的时间甚至会到 1 秒;

3.2 AOF

快照并不是很可靠。如果你的电脑突然宕机了,或者电源断了,又或者不小心杀掉了进程,那么最新的数据就会丢失。而 AOF 文件则提供了一种更为可靠的持久化方式。每当 Redis 接受到会修改数据集的命令时,就会把命令追加到 AOF 文件里,当你重启 Redis 时,AOF 里的命令会被重新执行一次,重建数据。

优点:

  • 比 RDB 可靠。你可以制定不同的 fsync 策略:不进行 fsync、每秒 fsync 一次和每次查询进行 fsync。默认是每秒 fsync 一次。这意味着你最多丢失一秒钟的数据;
  • AOF 日志文件是一个纯追加的文件。就算是遇到突然停电的情况,也不会出现日志的定位或者损坏问题。甚至如果因为某些原因(例如磁盘满了)命令只写了一半到日志文件里,我们也可以用 redis-check-aof 这个工具很简单的进行修复;
  • 当 AOF 文件太大时,Redis 会自动在后台进行重写。重写很安全,因为重写是在一个新的文件上进行,同时 Redis 会继续往旧的文件追加数据。新文件上会写入能重建当前数据集的最小操作命令的集合。当新文件重写完,Redis 会把新旧文件进行切换,然后开始把数据写到新文件上;
  • AOF 把操作命令以简单易懂的格式一条接一条的保存在文件里,很容易导出来用于恢复数据。例如我们不小心用 FLUSHALL 命令把所有数据刷掉了,只要文件没有被重写,我们可以把服务停掉,把最后那条命令删掉,然后重启服务,这样就能把被刷掉的数据恢复回来;

缺点:

  • 在相同的数据集下,AOF 文件的大小一般会比 RDB 文件大;
  • 在某些 fsync 策略下,AOF 的速度会比 RDB 慢。通常 fsync 设置为每秒一次就能获得比较高的性能,而在禁止 fsync 的情况下速度可以达到 RDB 的水平;
  • 在过去曾经发现一些很罕见的 BUG 导致使用 AOF 重建的数据跟原数据不一致的问题;

3.3 从 RDB 切换到 AOF

这里只说 Redis >= 2.2 版本的方式:

备份一个最新的 dump.rdb 的文件,并把备份文件放在一个安全的地方。

运行以下两条命令:

$ redis-cli config set appendonly yes
$ redis-cli config set save ""
  • 确保数据跟切换前一致;
  • 确保数据正确的写到AOF文件里;

第二条命令是用来禁用 RDB 的持久化方式,但是这不是必须的,因为你可以同时启用两种持久化方式。

记得对配置文件 redis.conf 进行编辑启用 AOF,因为命令行方式修改配置在重启 Redis 后就会失效。

4 Resource

Date: 2017-12-04 10:58:35

Author: JerryZhang