动态配置
config get/set 配置名称
可以在redis-cli里面使用config命令来获取或设置redis配置,可以不用重新启动redis。- 并不是所有的配置参数都可以通过config命令在运行期修改,比如:
deamonize
pidfile
port
database
dir
slaveof
rename-command
等。
静态配置
参数配置在redis.conf文件中,你可以在安装目录中找到它,我将对里面每部分作一个介绍。
通用部分
- 度量单位
1k => 1000 bytes
1kb => 1024 bytes
1m => 1000000 bytes
1mb => 1024*1024 bytes
1g => 1000000000 bytes
1gb => 1024*1024*1024 bytes
单位不区分大小写,所以 1GB 1Gb 1gB
都一样。基础的单位不支持bit只支持bytes。
- 子配置文件
include /path/to/local.conf
include /path/to/other.conf
可以把一些通用的配置移到外面,供多个实例共享,而不必重复去配置。
daemonize
是否以后台守护进程方式启动redis服务pidfile
pid文件位置,默认会生成在/var/run/redis.pid
bind
指定要绑定的IP,默认会响应梧桐所有可用网卡的连接请求。port
监听的端口号,默认服务端口6379,0表示不监听端口;如果redis不监听端口可以通过unix socket文件来接收请求。tcp-backlog
设置tcp的backlog,它其实是一个连接队列,backlog队列总和 = 未完成三次握手队列 + 已经完成三次握手队列。在高并发环境下需要一个高的backlog值来避免慢客户端连接问题。timeout
连接空闲超时时间,0表示永不关闭tcp-keepalive
单位为秒,如果设置为0则不会进行在线检测。loglevel
log信息级别,共分四个级别:debug、verbose、notice和warninglogfile
log文件位置,如果设置为空字符串,则redis会将日志输出到标准输出,即控制台。syslog-enabled
是否把日志输出到syslog中syslog-ident
指定日志标志syslog-facility
指定syslog设置databases
开启数据库的数量,编号从0开始。maxclients
设置redis同时可以与多少个客户端连接,默认为1万个客户端。当连接超过此限制时会报错max number of clients reached
maxmemory
设置redis可以使用的内存量。一旦达到内存使用上限,redis将试图移除内部数据,移除规则可以通过maxmemory-policy
指定。maxmemory-policy
设置内存移除规则,redis提供了多达6种规则。
volatile-lru
使用LRU算法移除key,只对设置了过期时间的键操作allkeys-lru
使用LRU算法移除keyvolatile-random
在过期集合中移除随机的key,只对设置了过期时间的键allkeys-random
移除随机的keyvolatile-ttl
移除那些ttl值最小的key,即那些最近要过期的keynoeviction
不进行移除,针对写操作返回错误信息。
maxmemory-samples
设置样本数量,LRU算法和最小TTL算法都并非精确的算法,而是估算值。
持久化
redis持久化分成两种方式
RDB(Redis Data Base)
和AOF(Append Only File)
。
RDB
在不同的时间点,将redis某一时刻的数据生成快照并存储到磁盘上。AOF
只允许追回不允许改写的文件,将redis执行过的所有写指令记录下来,在下次redis重新启动时,把这些指令从前到后再重复执行一次。RDB
和AOF
可以同时使用,在这种情况下如果redis重启的话,则会优先采用AOF方式来进行数据恢复,这是因为AOF方式的数据恢复完整度更高。- 可以关闭执久化,即redis变成一个纯内存数据库,类似于Memcache一样。
- 在配置文件
redis.conf
中可以开启AOF功能appendonly yes
RDB
redis会单独创建(fork)一个子进程来进行持久化,会先将内存中的数据写入到一个临时文件中,当持久化过程结束完再用这个临时文件替换上次持久化的文件。整个过程中主进程不进行任何IO操作,从而确保极高的性能。
配置
save * *
保存快照的频率。第一个*
表示多长时间(单位秒),第二个*
表示至少执行写操作的次数;在一定时间内至少执行一定数量的写操作时,就自动保存快照;可以设置多个条件。如果想禁用RDB持久化策略,只需要不设置快照频率或给save传空字符串即可。save 900 1 save 300 10 save 60 10000
如果用户开启了RDB快照功能,那么在redis持久化数据到磁盘时如果出现失败,默认情况下redis会停止接收所有的写请求。这样做是为了让用户很明确的知道内存中的数据和磁盘上的数据已经不一致了,如果下一次RDB持久化成功,redis会自动恢复接收写请求。
stop-writes-on-bgsave-error yes
如果配置成no
表示你不在乎数据不一致或者有其它手段发现和控制这种不一致,那么在快照写入失败时也能确保redis继续接收新的写入请求。rdbcompression yes
对于存储到磁盘的快照进行压缩,redis会采用LZF算法进行压缩,如果你不想消耗CPU来进行压缩的话可以关闭此功能。rdbchecksum yes
在存储快照后可以让redis使用CRC64算法进行数据校验,但是这样会增加大约10%的性能消耗,如果希望获取最大的性能提升可以关闭此功能。dbfilename dump.rdb
数据快照文件名dir ./
数据快照保存目录,默认当前路径
如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。它的缺点是最后一次持久化后的数据可能丢失。
问题
- fork一个进程时内存的数据也被复制了,即内存会是原来的两倍。
- 每次快照持久化都是将内存数据完整写入到磁盘一次,并不是增量的只同步脏数据。如果数据量大而且写操作比较多,必然会引起大量的磁盘IO操作,可能会严重影响性能。
- 由于快照方式是在一定间隔时间做一次,所以当redis意外down掉时就会丢失最后一次快照后的所有修改。
触发快照的情况
- 根据配置规则自动快照
- 用户执行
save
或bgsave
命令
- 执行save命令时redis会阻塞所有客户端的请求, 然后再同步进行快照操作。
- 执行bgsave命令时redis在后台异步进行快照操作,同时还可以响应客户端请求。可以通过
lastsave
命令获取最后一次成功执行快照的时间。
- 执行
flushall
命令 - 执行复制
replication
命令
AOF
默认的AOF持久化策略是每秒钟fsync一次,fsync是指把缓存中的写指令记录到磁盘中,在这种情况下redis仍可以保持很高的性能。
由于OS会在内核中缓存write做的修改,所以可能不是立即写到磁盘上。这样AOF方式的持久化也还是有可能会丢失部分修改。可以通过配置文件告诉redis,通过fsync函数强制OS写入指令到磁盘的时机。
配置
appendonly no
是否开启AOFappendfilename "appendonly.aof"
设置AOF日志文件名appendfsync everysec
设置AOF日志同步磁盘的策略,fsync()调用用来告诉操作系统立即将缓存的指令写入磁盘,有三个选项:
always
每次写都强制调用fsync,在这种模式下redis会相对较慢,但数据最安全。everysec
每秒调用一次fsyncno
不调用fsync()。而是让操作系统自行决定sync的时间。在这种模式下redis性能会更快。
no-appendfsync-on-rewrite no
设置当redis在rewite的时候是否允许appendsync。因为redis进程在进行AOF重写的时候,fsync()在主进程中的调用会被阻止,也就是redis的持久化功能暂时失效,默认为no这样能保证数据安全。auto-aof-rewrite-percentage 100
设置自动进行AOF重写的基准值。也就是重写启动时的AOF文件大小,假如redis自启动至今还没有进行过重写,那么启动时AOF文件的大小会被作为基准值,这个基准值会和当前的AOF大小进行比较。如果当前AOF大小超出所设置的增长比例,则会触发重写。如果设置的值为0则会关闭重写功能。auto-aof-rewrite-min-size 64mb
设置一个最小值是为了防止在AOF很小时就触发重写。
AOF方式在同等数据规模的情况下,AOF文件要比RDB文件体积大,因为AOF方式的恢复速度也要慢于RDB方式。
日志恢复
如果在追回日志时恰好遇到磁盘空间满或断电等情况,导致日志写入不完整也没有关系,redis提供了redis-check-aof工具用来进行日志修复
- 备份受损的aof文件
- 运行
redis-check-aof -fix
进行修复 - 用diff -u查看两份文件差异以确认问题点
- 重启redis加载修复后的aof文件
重写
由于AOF采用文件追回方式,这会导致AOF文件起来越大,为此redis提供了AOF文件重写(rewrite)机制,当AOF文件的大小超过所设定的阈值,redis就会启动aof文件的内容压缩,只保留可以恢复数据的最小指令集。
也可以手动使用命令bgrewriteaof
强制要求进行上面的操作。
触发机制
redis会记录上次重写时的AOF大小,假如自启动至今还没有进行过重写,那么启动时AOF文件的大小会被作为基准值,拿它和当前的AOF大小进行比较,如果当前AOF大小超出所设置的增长比例
auto-aof-rewrite-percentage 100
则会触发重写。另外你还需要设置一个最小值auto-aof-rewrite-min-size 64mb
防止在AOF很小时就触发重写。
基本原理
- 在重写开始前redis会创建一个重写子进程,这个进程会读取再有的AOF文件,并将其包含的指令进行分析压缩并写入到一个临时文件中。
- 与此同时主进程会将新接收到的写指令一边累积到内存缓冲区中,一边继续写入到原有的AOF文件中,这样做是保证原有的AOF文件可用性,避免在重写过程中出现意外。
- 当重写子进程完成工作后会给父进程发一个信号,父进程收到信号后就会将内存中缓存的写指令追回到新AOF文件中。
- 当追回结束后redis会用新AOF文件代替旧AOF文件,之后再有新的写指令都会追回到新AOF文件中。
- 重写AOF文件的操作,并没有读取旧的AOF文件,而是将整个内存中的数据库内容用户命令的方式重写了一个新的AOF文件,这点和快照有点类似。