Redis的配置优化、数据类型、消息队列
文章目录
- 一、Redis的配置优化
- redis主要配置项
- CONFIG 动态修改配置
- 慢查询
- 持久化
- RDB模式
- AOF模式
- Redis多实例
- Redis命令相关
- 二、Redis数据类型
- 字符串string
- 列表list
- 集合 set
- 有序集合sorted set
- 哈希hash
- 三、消息队列
- 生产者消费者模式
- 发布者订阅者模式
一、Redis的配置优化
redis主要配置项
配置项 | 含义 |
---|---|
bind 0.0.0.0 | 监听地址,可以用空格隔开后多个监听IP |
protected-mode yes | redis3.2之后加入的新特性,在没有设置bind IP和密码的时候,redis只允许访问127.0.0.1:6379,可以远程连接,但当访问将提示警告信息并拒绝远程访问。 |
port 6379 | 监听端口,默认6379/tcp |
tcp-backlog 511 | 三次握手的时候server端收到client ack确认号之后的队列值,即全连接队列长度 |
timeout 0 | 客户端和Redis服务端的连接超时时间,默认是0,表示永不超时。 |
tcp-keepalive 300 | tcp 会话保持时间300s |
daemonize no | 默认no,即直接运行redis-server程序时,不作为守护进程运行,而是以前台方式运行,如果想在后台运行需改成yes,当redis作为守护进程运行的时候,它会写一个 pid 到/var/run/redis.pid 文件 |
supervised no | 和OS相关参数,可设置通过upstart和systemd管理Redis守护进程,centos7后都使用systemd |
pidfile /var/run/redis_6379.pid | pid文件路径,可以修改为/apps/redis/run/redis_6379.pid |
loglevel notice | 日志级别 |
logfile “/path/redis.log” | 日志路径,示例:logfile "/apps/redis/log/redis_6379.log"databases 16 #设置数据库数量,默认:0-15,共16个库 |
always-show-logo yes | 在启动redis 时是否显示或在日志中记录记录redis的logo |
save 900 1 | 在900秒内有1个key内容发生更改,就执行快照机制 |
save 300 10 | 在300秒内有10个key内容发生更改,就执行快照机制 |
save 60 10000 | 60秒内如果有10000个key以上的变化,就自动快照备份 |
stop-writes-on-bgsave-error yes | 默认为yes时,可能会因空间满等原因快照无法保存出错时,会禁止redis写入操作,生产建议为no ;此项只针对配置文件中的自动save有效 |
rdbcompression yes | 持久化到RDB文件时,是否压缩,"yes"为压缩,"no"则反之 |
rdbchecksum yes | 是否对备份文件开启RC64校验,默认是开启 |
dbfilename dump.rdb | 快照文件名 |
dir ./ | 快照文件保存路径,示例:dir “/apps/redis/data” |
replicaof | 指定复制的master主机地址和端口,5.0版之前的指令为slaveof |
masterauth | 指定复制的master主机的密码 |
replica-serve-stale-data yes | 当从库同主库失去连接或者复制正在进行,从机库有两种运行方式:1、设置为yes(默认设置),从库会继续响应客户端的读请求,此为建议值。2、设置为no,除去特定命令外的任何请求都会返回一个错误"SYNC with master in progress"。 |
replica-read-only yes | 是否设置从库只读,建议值为yes,否则主库同步从库时可能会覆盖数据,造成数据丢失 |
repl-diskless-sync no | 是否使用socket方式复制数据(无盘同步),新slave第一次连接master时需要做数据的全量同步,redis server就要从内存dump出新的RDB文件,然后从master传到slave,有两种方式把RDB文件传输给客户端:1、基于硬盘(disk-backed):为no时,master创建一个新进程dump生成RDB磁盘文件,RDB完成之后由父进程(即主进程)将RDB文件发送给slaves,此为默认值。2、基于socket(diskless):master创建一个新进程直接dump RDB至slave的网络socket,不经过主进程和硬盘。推荐使用基于硬盘(为no),是因为RDB文件创建后,可以同时传输给更多的slave,但是基于socket(为yes), 新slave连接到master之后得逐个同步数据。只有当磁盘I/O较慢且网络较快时,可用diskless(yes),否则一般建议使用磁盘(no) |
repl-diskless-sync-delay 5 | diskless时复制的服务器等待的延迟时间,设置0为关闭,在延迟时间内到达的客户端,会一起通过diskless方式同步数据,但是一旦复制开始,master节点不会再接收新slave的复制请求,直到下一次同步开始才再接收新请求。即无法为延迟时间后到达的新副本提供服务,新副本将排队等待下一次RDB传输,因此服务器会等待一段时间才能让更多副本到达。推荐值:30-60 |
repl-ping-replica-period 10 | slave根据master指定的时间进行周期性的PING master,用于监测master状态,默认10s |
repl-timeout 60 | 复制连接的超时时间,需要大于repl-ping-slave-period,否则会经常报超时 |
repl-disable-tcp-nodelay no | 是否在slave套接字发送SYNC之后禁用 TCP_NODELAY,如果选择"yes",Redis将合并多个报文为一个大的报文,从而使用更少数量的包向slaves发送数据,但是将使数据传输到slave上有延迟,Linux内核的默认配置会达到40毫秒,如果 “no” ,数据传输到slave的延迟将会减少,但要使用更多的带宽 |
repl-backlog-size 512mb | 复制缓冲区内存大小,当slave断开连接一段时间后,该缓冲区会累积复制副本数据,因此当slave 重新连接时,通常不需要完全重新同步,只需传递在副本中的断开连接后没有同步的部分数据即可。只有在至少有一个slave连接之后才分配此内存空间,建议建立主从时此值要调大一些或在低峰期配置,否则会导致同步到slave失败 |
repl-backlog-ttl 3600 | 多长时间内master没有slave连接,就清空backlog缓冲区 |
replica-priority 100 | 当master不可用,哨兵Sentinel会根据slave的优先级选举一个master,此值最低的slave会优先当选master,而配置成0,永远不会被选举,一般多个slave都设为一样的值,让其自动选择 |
min-replicas-to-write 3 | 至少有3个可连接的slave,mater才接受写操作 |
min-replicas-max-lag 10 | 和上面至少3个slave的ping延迟不能超过10秒,否则master也将停止写操作。 |
requirepass foobared | 设置redis连接密码,之后需要AUTH pass,如果有特殊符号,用" "引起来,生产建议设置 |
rename-command | 重命名一些高危命令,示例:rename-command FLUSHALL “” 禁用命令 #示例: rename-command FLUSHALL 123456 |
maxclients 10000 | Redis最大连接客户端 |
maxmemory | redis使用的最大内存,单位为bytes字节,0为不限制,建议设为物理内存一半,8G内存的计算方式。8(G)*1024(MB)1024(KB)*1024(Kbyte),需要注意的是缓冲区是不计算在maxmemory内,生产中如果不设置此项,可能会导致OOM |
appendonly no | 是否开启AOF日志记录,默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了,但是redis如果中途宕机,会导致可能有几分钟的数据丢失(取决于dump数据的间隔时间),根据save来策略进行持久化,Append Only File是另一种持久化方式,可以提供更好的持久化特性,Redis会把每次写入的数据在接收后都写入 appendonly.aof 文件,每次启动时Redis都会先把这个文件的数据读入内存里,先忽略RDB文件。默认不启用此功能。 |
appendfilename “appendonly.aof” | 文本文件AOF的文件名,存放在dir指令指定的目录中 |
appendfsync everysec | aof持久化策略的配置 1.no表示由操作系统保证数据同步到磁盘,Linux的默认fsync策略是30秒,最多会丢失30s的数据;2.always表示每次写入都执行fsync,以保证数据同步到磁盘,安全性高,性能较差;3.everysec表示每秒执行一次fsync,可能会导致丢失这1s数据,此为默认值,也生产建议值 。 |
同时在执行bgrewriteaof操作和主进程写aof文件的操作,两者都会操作磁盘,而bgrewriteaof往往会涉及大量磁盘操作,这样就会造成主进程在写aof文件的时候出现阻塞的情形,以下参数实现控制。 | |
no-appendfsync-on-rewrite no | 在aof rewrite期间,是否对aof新记录的append暂缓使用文件同步策略,主要考虑磁盘IO开支和请求阻塞时间。#默认为no,表示"不暂缓",新的aof记录仍然会被立即同步到磁盘,是最安全的方式,不会丢失数据,但是要忍受阻塞的问题 。为yes,相当于将appendfsync设置为no,这说明并没有执行磁盘操作,只是写入了缓冲区,因此这样并不会造成阻塞(因为没有竞争磁盘),但是如果这个时候redis挂掉,就会丢失数据。丢失多少数据呢?Linux默认fsync策略是30秒,最多会丢失30s的数据,但由于yes性能较好而且会避免出现阻塞因此比较推荐。rewrite 即对aof文件进行整理,将空闲空间回收,从而可以减少恢复数据时间 |
auto-aof-rewrite-percentage 100 | 当Aof log增长超过指定百分比例时,重写AOF文件,设置为0表示不自动重写Aof日志,重写是为了使aof体积保持最小,但是还可以确保保存最完整的数据。 |
auto-aof-rewrite-min-size 64mb | 触发aof rewrite的最小文件大小 |
aof-load-truncated yes | 是否加载由于某些原因导致的末尾异常的AOF文件(主进程被kill/断电等),建议yes |
aof-use-rdb-preamble no | redis4.0新增RDB-AOF混合持久化格式,在开启了这个功能之后,AOF重写产生的文件将同时包含RDB格式的内容和AOF格式的内容,其中RDB格式的内容用于记录已有的数据,而AOF格式的内容则用于记录最近发生了变化的数据,这样Redis就可以同时兼有RDB持久化和AOF持久化的优点(既能够快速地生成重写文件,也能够在出现问题时,快速地载入数据),默认为no,即不启用此功能。 |
lua-time-limit 5000 | lua脚本的最大执行时间,单位为毫秒 |
cluster-enabled yes | 是否开启集群模式,默认不开启,即单机模式 |
cluster-config-file nodes-6379.conf | 由node节点自动生成的集群配置文件名称 |
cluster-node-timeout 15000 | 集群中node节点连接超时时间,单位ms,超过此时间,会踢出集群 |
cluster-replica-validity-factor 10 | 单位为次,在执行故障转移的时候可能有些节点和master断开一段时间导致数据比较旧,这些节点就不适用于选举为master,超过这个时间的就不会被进行故障转移,不能当选master,计算公式:(node-timeout * replica-validity-factor) + repl-pingreplica-period |
cluster-migration-barrier 1 | 集群迁移屏障,一个主节点至少拥有1个正常工作的从节点,即如果主节点的slave节点故障后会将多余的从节点分配到当前主节点成为其新的从节点。 |
cluster-require-full-coverage yes | 集群请求槽位全部覆盖,如果一个主库宕机且没有备库就会出现集群槽位不全,那么yes时redis集群槽位验证不全,就不再对外提供服务(对key赋值时,会出现CLUSTERDOWN The cluster is down的提示,cluster_state:fail,但ping 仍PONG),而no则可以继续使用,但是会出现查询数据查不到的情况(因为有数据丢失) |
cluster-replica-no-failover no | 如果为yes,此选项阻止在主服务器发生故障时尝试对其主服务器进行故障转移。 但是,主服务器仍然可以执行手动强制故障转移,一般为no |
Slow log 是 Redis 用来记录超过指定执行时间的日志系统,执行时间不包括与客户端交谈,发送回复等I/O操作,而是实际执行命令所需的时间(在该阶段线程被阻塞并且不能同时为其它请求提供服务),由于slow log 保存在内存里面,读写速度非常快,因此可放心地使用,不必担心因为开启 slow log 而影响Redis 的速度 | |
slowlog-log-slower-than 10000 | 以微秒为单位的慢日志记录,为负数会禁用慢日志,为0会记录每个命令操作。默认值为10ms,一般一条命令执行都在微秒级,生产建议设为1ms-10ms之间 |
slowlog-max-len 128 | 最多记录多少条慢日志的保存队列长度,达到此长度后,记录新命令会将最旧的命令从命令队列中删除,以此滚动删除,即,先进先出,队列固定长度,默认128,值偏小,生产建议设为1000以上 |
CONFIG 动态修改配置
config命令用于查看当前redis配置,以及不重启redis服务实现动态更改redis配置等。
CONFIG SET parameter value
config set 参数值
时间复杂度:O(1)
CONFIG SET 命令可以动态地调整 Redis 服务器的配置(configuration)而无须重启。CONFIG GET parameter
时间复杂度: O(N),其中 N 为命令返回的配置选项数量。
CONFIG GET 命令用于取得运行中的 Redis 服务器的配置参数(configuration parameters),在Redis 2.4 版本中, 有部分参数没有办法用 CONFIG GET 访问,但是在最新的 Redis 2.6 版本中,所有配置参数都已经可以用 CONFIG GET 访问了。
config rewrite 可以将配置持久化到配置文件中。
慢查询
slowlog-log-slower-than 1
指定为超过1us即为慢的指令
slowlog-max-len 1024
指定保存1024条慢记录SLOWLOG LEN 查看慢日志的记录条数SLOWLOG RESET清空慢日志slowlog get查看全部 slowlog get 2查看 慢查询具体情况 看前2条
持久化
Redis 虽然是一个内存级别的缓存程序,也就是redis 是使用内存进行数据的缓存的,但是其可以将内存的数据按照一定的策略保存到硬盘上,从而实现数据持久保存的目的目前redis支持两种不同方式的数据持久化保存机制,分别是RDB和AOF。
持久化功能:Redis是内存数据库,所有数据都是保存在内存中,为了避免服务器断电等原因导致Redis进程异常退出后数据永久丢失,需要定期将Redis中的数据以某种形式(数据或者命令)从内存保存到硬盘;当下次Redis重启时,利用持久化文件实现数据恢复。除此之外为了进行灾难备份,可以持久将文件拷贝到一个远程位置(比如备份服务器)。
Redis 提供两种方式进行持久化:
- RDB 持久化:原理是将Redis在内存中的数据库记录,定时保存到磁盘上,类似于快照。
- AOF 持久化(append only file):原理是将Redis的操作日志已追加的方式写入文件,类似于mysql的 binlog。
由于AOF的持久性实时性更好,即发生特殊情况导致数据丢失时,丢失的数据更少,因此是目前主流的持久化方式,不过RDB持久化仍然有其用武之地。
RDB模式
RDB(Redis DataBase):基于时间的快照,其默认只保留当前最新的一次快照,特点是执行速度比较快,缺点是可能会丢失从上次快照到当前时间点之间未做快照的数据。
RDB bgsave实现快照的具体过程:
Redis从master主进程先fork出一个子进程,使用写时复制机制,子进程将内存的数据保存为一个临时文件,比如:tmp-.rdb,当数据保存完成之后再将上一次保存的RDB文件替换掉,然后关闭子进程,这样可以保证每一次做RDB快照保存的数据都是完整的因为直接替换RDB文件的时候,可能会出现突然断电等问题,而导致RDB文件还没有保存完整就因为突然关机停止保存,而导致数据丢失的情况。后续可以手动将每次生成的RDB文件进行备份,这样可以最大化保存历史数据。
执行流程
- Redis父进程首先判断 :当前是否在执行save,或bgsave/bgrewriteaof的子进程,如果在执行则bgsave命令直接返回。
bgsave/bgrewriteaof 的子进程不能同时执行,主要是基于性能方面的考虑:两个并发的子进程同时执行大量的磁盘写操作,可能引起严重的性能问题。 - 父进程执行fork操作创建子进程,这个过程中父进程是阻塞的,Redis不能执行来自客户端的任何命令。
- 父进程fork后,bgsave 命令返回 “Background saving started” 信息并不再阻塞父进程,并可以响应其他命令。
- 子进程创建RDB文件,根据父进程内存快照生成临时快照文件,完成后对原有文件进行替换。
- 子进程发送信号给父进程表示完成,父进程更新统计信息。
如何加载RDB文件?
RDB文件的载入是在服务器启动时自动执行的,并没有专门的命令。但是由于AOF的优先级更高,因此当AOF开启时,Redis会优先载入AOF文件来恢复数据;只有当A0F关闭时,才会在Redis服务器启动时检测RDB文件,并自动载入。服务器载入RDB文件期间处于阻塞状态,直到载入完成为止。
Redis载入RDB文件时,会对RDB文件进行校验,如果文件损坏,则日志中会打印错误,Redis启动失败。
在配置文件中忽略RDB的错误,即可直接启动。
ignore-rdb-errors yes
RDB持久化
RDB持久化触发条件可以分为手动触发和自动触发两种。
手动触发
save命令和bgsave命令都可以生成RDB文件。
save命令会阻塞Redis服务器进程,直到RDB文件创建完毕为止,在Redis服务器阻塞期间,服务器不能处理任何命令请求。
而bgsave命令会创建一个子进程,由子进程来负责创建RDB文件,父进程 (即Redis主进程) 则继续处理请求。bgsave命令执行过程中,只有fork 子进程时会阻塞服务器,而对于save命令,整个过程都会阻塞服务器,因此save已基本被废弃,线上环境要杜绝save的使用。往往生产环境 bgsave 依然不允许轻易使用。
自动触发
在自动触发RDB持久化时,Redis也会选择bgsave而不是save来进行持久化。
save m n
自动触发最常见的情况是在配置文件中通过save m n,指定当m秒内发生n次变化时,会触发bgsave。
注意:必须要两个条件同时满足。
ave 900 1
900s内修改了1个key即触发保存RDB
save 300 10
300s内修改了10个key即触发保存RDB
save 60 10000
60s内修改了10000个key即触发保存RDB
dbfilename dump.rdb
dir ./
编泽编译安装,默认RDB文件存放在启动redis的工作目录,建议明确指定存入目录
stop-writes-on-bgsave-error yes
当 Redis 在后台保存 RDB 文件失败时,停止接受写操作。
rdbcompression yes
在保存 RDB 文件时启用压缩。
rdbchecksum yes
在 RDB 文件末尾存储一个 CRC64 校验和
在定义RDB文件存放在哪里时,需要注意定义的文件夹需要有执行权限。
实现RDB方式
- save: 同步,会阻赛其它命令,不推荐使用。
- bgsave: 异步后台执行,不影响其它命令的执行。
- 自动: 制定规则,自动执行。
bgsave在后台执行备份,并不知道什么时候完成。
执行info Persistence
rdb_bgsave_in_progress:0
此处为0表示保存结束;1表示保存没结束。
RDB的优缺点
优点:
- RDB快照保存了某个时间点的数据,可以通过脚本执行redis指令bgsave(非阻塞,后台执行)或者save(会阻塞写操作,不推荐)命令自定义时间点备份,可以保留多个备份,当出现问题可以恢复到不同时间点的版本,很适合备份,并且此文件格式也支持有不少第三方工具可以进行后续的数据分析比如: 可以在最近的24小时内,每小时备份一次RDB文件,并且在每个月的每一天,也备份一个RDB文件。这样的话,即使遇上问题,也可以随时将数据集还原到不同的版本。
- RDB可以最大化Redis的性能,父进程在保存 RDB文件时唯一要做的就是fork出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。
- RDB在大量数据,比如几个G的数据,恢复的速度比AOF的快。
缺点:
- 不能实时保存数据, 可能会丢失自上一次执行RDB备份到当前的内存数据如果你需要尽量避免在服务器故障时丢失数据,那么RDB并不适合。虽然Redis允许设置不同的保存点(save point)来控制保存RDB文件的频率,但是,因为RDB文件需要保存整个数据集的状态,所以它并不是一个轻松快速的操作。因此一般会超过5分钟以上才保存一次RDB文件。在这种情况下,一旦发生故障停机,你就可能会丢失好几分钟的数据。
- 当数据量非常大的时候,从父进程fork子进程进行保存至RDB文件时需要一点时间,可能是毫秒或者秒,取决于磁盘IO性能在数据集比较庞大时,fork()可能会非常耗时,造成服务器在一定时间内停止处理客户端﹔如果数据集非常巨大,并且CPU时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒或更久。虽然 AOF重写也需要进行fork(),但无论AOF重写的执行间隔有多长,数据的持久性都不会有任何损失。
AOF模式
AOF:AppendOnylFile,按照操作顺序依次将操作追加到指定的日志文件末尾。
AOF 和 RDB 一样使用了写时复制机制,AOF默认为每秒钟 fsync一次,即将执行的命令保存到AOF文件当中,这样即使redis服务器发生故障最多只丢失1秒钟之内的数据,也可以设置不同的fsync策略always,即设置每次执行命令的时候执行fsync,fsync会在后台执行线程,所以主线程可以继续处理用户的正常请求而不受到写入AOF文件的I/O影响。
注意: AOF 模式默认是关闭的,第一次开启AOF后,并重启服务生效后,会因为AOF的优先级高于RDB,而先恢复AOF文件
AOF默认没有数据文件存在,从而导致所有数据丢失。
AOF相关配置:
是否开启AOF
appendonly yes
是否开启AOF日志记录,默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了,但是redis如果中途宕机,会导致可能有几分钟的数据丢失(取决于dump数据的间隔时间),根据save来策略进行持久化,Append Only File是另一种持久化方式,可以提供更好的持久化特性,Redis会把每次写入的数据在接收后都写入 appendonly.aof 文件,每次启动时Redis都会先把这个文件的数据读入内存里,先忽略RDB文件。默认不启用此功能。
存放路径
appendfilename "appendonly.aof"
设置储存aof的默认名字
保存规则
持久化的策略
appendfsync always
表示每次写入都执行fsync,以保证数据同步到磁盘,安全性高,性能较差。
appendfsync everysec
表示每秒执行一次fsync,可能导致丢失这1s数据,此为默认值,也是生产建议值。appendfsync no
表示由操作系统保证数据同步到磁盘,Linux的默认fsync策略是30秒,最多会丢失30s的数据。
如何修改aof文件纠正数据。当不小心执行了删库的命令时,可以进入文件数据中,将那条命令删除,并重新导入文件即可。
例如:同时启用AOF和RDB时如何正确恢复?
AOF优先级 比 RDB 要高,同时开启只会同步AOF文件。
需要先停止服务器,修改配置文件关闭AOF功能,开启服务,即可自动导入RDB文件,再开启AOF文件即可。
AOF重写机制
重写机制的作用,将一些重复的、可以合并的、过期的数据重新写入一个新的AOF文件,从而节约AOF备份占用的硬盘空间,也能加速恢复过程。同时也可以手动执行 bgrewriteaof触发AOF,也可以在配置文件中进行rewrite策略。
AOF rewrite过程
执行重写的操作的时候,父进程会开启一个子进程,这个子进程会分析 AOF 文件删除一些重复过期的数据将这些写入重写的缓存区,然后形成一个新的aof 临时文件,同时也有新的数据写入,会将新写入的数据放入 aof 缓存区,最后将临时文件和新写入的数据合并到旧的 aof 文件中。
AOF rewrite重写配置
同时在执行bgrewriteaof操作和主进程写aof文件的操作,两者都会操作磁盘,而bgrewriteaof往往会涉及大量磁盘操作,这样就会造成主进程在写aof文件的时候出现阻塞的情形,以下参数实现控制
-
no-appendfsync-on-rewrite no
简单来说,就是在AOF重写期间,是否暂停fsync的操作。
在aof rewrite期间,是否对aof新记录的append暂缓使用文件同步策略,主要考虑磁盘IO开支和请求阻塞时间。
默认为no,表示"不暂缓",新的aof记录仍然会被立即同步到磁盘,是最安全的方式,不会丢失数据,但是要忍受阻塞的问题;为yes,相当于将appendfsync设置为no,这说明并没有执行磁盘操作,只是写入了缓冲区,因此这样并不会造成阻塞(因为没有竞争磁盘),但是如果这个时候redis挂掉,就会丢失数据。丢失多少数据呢?Linux 的默认fsync策略是30秒,最多会丢失30s的数据,但由于yes性能较好而且会避免出现阻塞,因此比较推荐。 -
auto-aof-rewrite-percentage 100
当 AOF 文件的大小达到上次重写后的 100% 增长时,Redis 会自动触发 AOF 重写操作。例如,如果上次重写后的 AOF 文件大小是 64MB,当 AOF 文件增长到 128MB 时,会触发重写。 -
auto-aof-rewrite-min-size 64mb
触发aof rewrite的最小文件大小
即使 AOF 文件的增长百分比达到了 auto-aof-rewrite-percentage 的设置值,AOF 文件的大小也必须至少达到 64MB 才会触发重写操作。这是为了避免在 AOF 文件较小时频繁重写。 -
aof-load-truncated yes
如果 Redis 在启动时检测到 AOF 文件是截断的(可能是由于 Redis 崩溃导致的),它会接受并加载这个截断的 AOF 文件,而不是拒绝加载。
AOF模式的优缺点
优点
- 数据安全性相对较高,根据所使用的fsync策略(fsync是同步内存中redis所有已经修改的文件到存储设备),默认是appendfsync everysec,即每秒执行一次 fsync,在这种配置下,Redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据( fsync会在后台线程执行,所以主线程可以继续努力地处理命令请求)。
- 由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中不需要seek, 即使出现宕机现象,也不会破坏日志文件中已经存在的内容。然而如果本次操作只是写入了一半数据就出现了系统崩溃问题,不用担心,在Redis下一次启动之前,可以通过 redis-check-aof 工具来解决数据一致性的问题。
- Redis可以在 AOF文件体积变得过大时,自动地在后台对AOF进行重写,重写后的新AOF文件包含了恢复当前数据集所需的最小命令集合。整个重写操作是绝对安全的,因为Redis在创建新 AOF文件的过程中,append模式不断的将修改数据追加到现有的 AOF文件里面,即使重写过程中发生停机,现有的 AOF文件也不会丢失。而一旦新AOF文件创建完毕,Redis就会从旧AOF文件切换到新AOF文件,并开始对新AOF文件进行追加操作。
- AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事实上,也可以通过该文件完成数据的重建。
- AOF文件有序地保存了对数据库执行的所有写入操作,这些写入操作以Redis协议的格式保存,因此 AOF文件的内容非常容易被人读懂,对文件进行分析(parse)也很轻松。导出(export)AOF文件也非常简单:举个例子,如果不小心执行了FLUSHALL.命令,但只要AOF文件未被重写,那么只要停止服务器,移除 AOF文件末尾的FLUSHAL命令,并重启Redis ,就可以将数据集恢复到FLUSHALL执行之前的状态。
缺点:
- 即使有些操作是重复的也会全部记录,AOF 的文件大小要大于 RDB 格式的文件。
- AOF 在恢复大数据集时的速度比 RDB 的恢复速度要慢。
- 根据fsync策略不同,AOF速度可能会慢于RDB。
- bug 出现的可能性更多。
RDB和AOF的选择
- 如果主要充当缓存功能,或者可以承受数分钟数据的丢失, 通常生产环境一般只需启用RDB即可,此也是默认值。
- 如果数据需要持久保存,一点不能丢失,可以选择同时开启RDB和AOF。
- 一般不建议只开启AOF。
AOF与RDB持久化相对应,AOF的优点在于支持秒级持久化、兼容性好,缺点是文件大、恢复速度慢、对性能影响大
Redis多实例
测试环境中经常使用多实例,需要指定不同实例的相应的端口,配置文件,日志文件等相关配置。
做多实例之前记得把初始的数据库关了。
修改配置文件
cp /apps/redis/etc/redis.conf /apps/redis/etc/redis6379.conf
共用配置文件
sed -i 's/dbfilename dump.rdb/dbfilename dump6379.rdb/' redis6379.conf
修改备份文件的名字
sed -i 's#logfile ""#logfile /apps/redis/log/redis6379.log#' redis6379.conf
修改日志文件的名字
sed -i 's/redis_6379.pid/redis_6380.pid/' redis6380.conf
修改pid文件
sed -i 's/^port 6379/port 6380/' redis6380.conf
修改端口号
修改启动文件
cp /lib/systemd/system/redis.service /lib/systemd/system/redis6379.service
[Unit]
Description=Redis persistent key-value database
After=network.target[Service]
ExecStart=/apps/redis/bin/redis-server /apps/redis/etc/redis6379.conf --supervised systemd
ExecStop=/bin/kill -s QUIT $MAINPID
#Type=notify 如果支持systemd可以启用此行
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755[Install]
WantedBy=multi-user.target
注意配置文件的位置需要对应。
测试:
对应的文件
Redis命令相关
info
显示当前节点redis运行状态信息。
select
切换数据库,相当于mysql中的use database的命令。
redis中默认有16个数据库。
keys
查看当前库下的所有keys,此命令慎用!
如果redis的数据量过大,使用此命令会导致redis锁住,导致CPU飙升,从而引起后端数据库的雪崩效应。
keys支持通配符
MEST
一次性设置多个key
MSET one 1 two 2 three 3 four 4
一次设置了4个key
BGSAVE
手动在后台执行RDB持久化操作。
DBSIZE
返回当前库下的所有key 数量。
FLUSHDB
强制清空当前库中的所有key,此命令慎用。
FLUSHALL
强制清空当前redis服务器所有数据库中的所有key,即删除所有数据,此命令慎用!
SHUTDOWN
停止所有客户端
如果持久化被打开的话, SHUTDOWN 命令会保证服务器正常关闭而不丢失任何数据。
另一方面,假如只是单纯地执行 SAVE 命令,然后再执行 QUIT 命令,则没有这一保证。 因为在执行SAVE 之后、执行 QUIT 之前的这段时间中间,其他客户端可能正在和服务器进行通讯,这时如果执行 QUIT 就会造成数据丢失。
二、Redis数据类型
-
字符型(string): 普通字符串
-
哈希(hash): 键值对的 键值对
-
列表 (linked lists): 类似于 数组
-
集合(set): 无序 朋友圈共同好友
-
有序集合(sorted set): 排行榜
字符串string
字符串是所有编程语言中最常见的和最常用的数据类型,而且也是redis最基本的数据类型之一,而且redis 中所有的 key 的类型都是字符串。常用于保存 Session 信息场景,此数据类型比较常用。
SETkeyvalue [EX seconds] [PX milliseconds] [NX|XX]时间复杂度: O(1)
将字符串值value关联到key。
参数 | 含义 |
---|---|
EX seconds | 将键的过期时间设置为 seconds 秒。执行 SET key value EX seconds 的效果等同于执行 SETEX key seconds value 。 |
PX milliseconds | 将键的过期时间设置为 milliseconds 毫秒。执行 SET key value PX 。milliseconds 的效果等同于执行 PSETEX key milliseconds value 。 |
NX | 只在键不存在时,才对键进行设置操作。执行 SET key value NX 的效果等同于执行 SETNX key value 。 |
XX | 只在键已经存在时,才对键进行设置操作。 |
例子:
TYPE key1
判断类型SET title ceo ex 3
设置自动过期时间3ssetnx title coo
set key value nx
key值不存在时,才设置,相当于add。get title
"ceo"
set title coo xx
get title
"coo"
xx指令存在时才设置,相当于updatedel key1
删除keyMSET key1 value1 key2 value2
批量设置多个keyMGET key1 key2
批量获取多个keyset key1 123
append key1 "cxk"
get key1
"123cxk"
追加数据STRLEN key1
返回字符串key1对应值的字节数EXISTS name
判断key是否存在ttl key
查看key的剩余生存时间,如果key过期后,会自动删除。
-1 返回值表示永不过期,默认创建的key是永不过期,重新对key赋值,也会从有剩余生命周期变成永不过期。
-2 返回值表示没有此key。
num key的剩余有效期EXPIRE name 1000
重新设置key的过期时间PERSIST name (integer) 1
永不过期
列表list
列表是一个双向可读写的管道,其头部是左侧,尾部是右侧,一个列表最多可以包含2^32-1(4294967295)个元素,下标 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,元素值可以重复,常用于存入日志等场景,此数据类型比较常用。
特点
- 有序
- 可重复
- 左右都可以操作
列表操作命令
命令 | 解释 例子 |
---|---|
lpush | 从左边添加数据 例子:lpush name zhou wu zheng wang |
rpush | 从右边添加数据 例子: rpush car benz bmw |
llen | 获取列表长度 例子: llen 列表名称 |
lindex | 获取单个元数 例子: lindex name 0 ; lindex name -1 |
lrange | 获取多个元素 例子: lrange name 0 3 第1个到第三个元素 |
lset | 修改列表元素 例子: lset name 2 feng 将name的第二个元素改为feng |
lpop | 删除列表元素 例子: lpop name 删除左边第一个 |
rpop | 删除列表元素 例子: rpop name 删除右边第一个 |
ltrim | 对列表修剪, 例子: ltrim name 1 2 只留下编号为 1 2 的文件 |
del | 删除列表 例子:del name |
集合 set
Set 是 String 类型的无序集合,集合中的成员是唯一的,这就意味着集合中不能出现重复的数据,可以在两个不同的集合中对数据进行对比并取值,常用于取值判断,统计,交集等场景,例如: 实现共同的朋友,微信好友,qq好友。
集合特点
- 无序
- 无重复
- 集合间操作
集合操作
生成集合key
sadd set1 v1追加数值
注意:追加时,只能追加不存在的数据,不能追加已经存在的数值。
SADD set1 v2 v3 v4查看集合的所有数据
SMEMBERS set1删除集合中的元素
srem set1 v1
集合间操作
获取集合的交集
SINTER set1 set2获取集合的并集
SUNION set1 set2获取集合的差集
SDIFF set1 set2
差集:已属于A而不属于B的元素称为A与B的差(集)
有序集合sorted set
Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员,不同的是每个元素都会关联一个double(双精度浮点型)类型的分数,redis正是通过该分数来为集合中的成员进行从小到大的排序,有序集合的成员是唯一的,但分数(score)却可以重复,集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1), 集合中最大的成员数为 2^32 - 1 (4294967295, 每个集合可存储40多亿个成员),经常用于排行榜的场景。
有序集合特点
- 有序
- 无重复元素
- 每个元素是由score和value组成
- score 可以重复
- value 不可以重复
生成有序集合
ZADD zset1 1 v1 分数为1
ZADD zset1 2 v2 生成有序集合,定义内部元素和分数
注意:分数可以重复,元素值不可以重复。ZADD zset2 1 v1 2 v2 3 v3 4 v4 5 v5
一次生成多个数据有序集合实现排行榜
ZRANGE paihangbang 0 -1 (0 -1代表集合内从第一个到最后一个)
正序排序后显示集合内所有的key,score从小到大显示。ZREVRANGE paihangbang 0 -1
倒序排序后显示集合内所有的key,score从大到小显示。ZRANGE paihangbang 0 -1 WITHSCORES
正序显示指定集合内所有key和得分情况。获取集合的个数
ZCARD 集合名获取分数
zscore paihangbang 元素名删除元素
ZRANGE paihangbang 0-1
删除所有元素
哈希hash
hash 即字典, 是一个string类型的字段(field)和值(value)的映射表,Redis 中每个 hash 可以存储 2^32 -1 键值对,类似于字典,存放了多个k/v 对,hash特别适合用于存储对象场景。
生成hashkey
HSET 9527 name zhouxingxing age 20
新增hash表格新增字段
hset 9527 gender male查看字段
hgetall 9527获取hash key的对应字段的值
HMGET 9527 name age删除对应的字段
hdel 9527 age获取hash中的所有字段名
HMSET 9527获取hash中对应的字段值
HVALS 9527删除hash
DEL 9527
三、消息队列
消息队列:把要传输的数据放在队列中。
功能: 可以实现多个系统之间的解耦,异步,削峰/限流等。
常用的消息队列应用: kafka,rabbitMQ,redis 。
生产者消费者模式
在生产者/消费者(Producer/Consumer)模式下,上层应用接收到的外部请求后开始处理其当前步骤的操作,在执行完成后将已经完成的操作发送至指定的频道(channel,逻辑队列)当中,并由其下层的应用监听该频道并继续下一步的操作,如果其处理完成后没有下一步的操作就直接返回数据给外部请求,如果还有下一步的操作就再将任务发布到另外一个频道,由另外一个消费者继续监听和处理。此模式应用广泛。
模式介绍
生产者消费者模式下,多个消费者同时监听一个队列,但是一个消息只能被最先抢到消息的消费者消费,即消息任务是一次性读取和处理,此模式在分布式业务架构中很常用,比较常用的消息队列软件还有RabbitMQ、Kafka、RocketMQ、ActiveMQ等。
队列介绍
队列当中的消息由不同的生产者写入,也会有不同的消费者取出进行消费处理,但是一个消息一定是只能被取出一次也就是被消费一次。
发布者订阅者模式
在发布者订阅者模式下,发布者将消息发布到指定的channel里面,凡是监听该channel的消费者都会收到同样的一份消息,这种模式类似于是收音机的广播模式,即凡是收听某个频道的听众都会收到主持人发布的相同的消息内容。此模式常用语群聊天、群通知、群公告等场景。
- Publisher:发布者
- Subscriber:订阅者
- Channel:频道