java架构之路-(Redis专题)Redis的高性能和持久化

  上次咱们简单的说了一下咱们的redis的安装和使用,此次咱们来讲说redis为何那么快和持久化数据redis

  在咱们现有的redis中(5.0.*以前的版本),Redis都是单线程的,那么单线程的Redis为何还会有那么高的效率呢?由于它全部的数据都在内存中,全部的运算都是内存级别的运算,并且单线程避免了多线程的切换中性能损耗的问题,正由于Redis是单线程,因此咱们要当心使用Redis指令,对于那些耗时的指令(好比keys),咱们必定要谨慎使用。数据库

  在并发环境中,咱们Redis的单线程并非线程1请求了,而咱们的线程2就没法继续请求了,而他的内部是采用了IO多路复用,redis利用epoli来实现IO多路复用,将链接信息和事件放在队列中,依次放到事件分派器,事件分派器将事件分发给咱们的事件处理器来执行指令操做。安全

 

  redis默认支持最大链接数是10000,咱们经过设置咱们的redis.conf来指定咱们的最大链接数,# maxclients 10000 => maxclients 100,大体在539行,或者咱们输入/maxclients 能够快速查找到咱们须要改的配置,进入咱们的客户端,输入$ CONFIG GET maxclients,便可查看咱们的客户端最大链接数。服务器

127.0.0.1:6379> CONFIG GET maxclients
1) "maxclients"
2) "100"

高级命令多线程

  咱们输入keys *,既能够返回咱们的所有键的数据,通常不推荐使用,若是数据量过大,会至关消耗性能的。并发

  scan,scan提供了三个参数,第一个是cursor整数值,第二个是key的正则模式。第三个是第一次遍历的key的数量,并非符合条件的结果的数量,第一次遍历时,cursor值为0,而后咱们将返回结果中第一个整数做为下一次遍历的cursor。一直遍历到cursor值为0时结束。app

127.0.0.1:6379> scan 0 match key* count 5
1) "6"
2) 1) "key6"
   2) "key4"
   3) "key1"
127.0.0.1:6379> scan 6 match key* count 5
1) "0"
2) 1) "key5"
   2) "key2"
   3) "key3"

Info:查看redis服务运行信息,分为 9 大块,每一个块都有很是多的参数,这 9 个块分别是: 异步

Server 服务器运行的环境参数 函数

Clients 客户端相关信息 性能

Memory 服务器运行内存统计数据 

Persistence 持久化信息 

Stats 通用统计数据 

Replication 主从复制相关信息 

CPU CPU 使用状况 

Cluster 集群信息 

KeySpace 键值对统计数量信息

日志

redis.conf文件配置logfile来配置咱们的log日志信息。大概在137行。

logfile "logForRedis.log"

 Redis持久化

  持久化主要分为三种,RDB,AOF和混合模式(4.0.*之后的模式)。

RDB快照模式

  在默认状况下,Redis将内存数据库快照保存为*.rdb的二进制文件。我用的是5.0.5版本,默认是开启咱们的RDB快照模式的,大体在253行,咱们看到dbfilename dump.rdb,就是咱们要以dump.rdb的文件来存储,存储位置在263行的dir ./ 也就是咱们的当前路径(这里能够设置绝对路径)。  

  咱们在大概218行能够看到三个save,也就是咱们RDB的保存策略

save 900 1 //表示在900秒内,发生了一次变更,咱们就生成一次快照,变更只是数据的变更,get并不算变更

save 300 10 //表示在300秒内,发生了十次变更,咱们就生成一次快照

save 60 10000 //表示在60秒内,发生了一万次变更,咱们就生成一次快照

三者条件知足其一就保存一次,他们之间是一个或者的关系,若是三个条件都未知足,这时宕机可能形成数据的丢失。

  咱们还能够经过进入redis-cli客户端之后,咱们手动输入save或者bgsave来生成咱们的dump.rdb文件。咱们的redis服务端配置是采用bgsave的方式来保存的。咱们来看一下save和bgsave的比较。

命令 save bgsave
IO类型 同步 异步
是否阻塞redis其它命令 否(在生成子进程执行调用fork函数时会有超级短暂的阻塞)
时间复杂度 O(n) O(n)
优势 不会消耗额外内存 不阻塞客户端命令
缺点 阻塞客户端命令 须要fork子进程,消耗内存

AOF命令模式

  咱们为何成为AOF叫作命令模式呢?咱们的AOF实际上是保存了咱们每个操做的动做,也就是咱们每个Redis指令,咱们只须要设置appendonly yes便可,大概在699行。下面的appendfilename是咱们须要保存aof的文件名,rdb中提到的dir对应的也是aof文件的保存路径。这样的持久化,其实也不是每次都要向磁盘写入数据的,他有三个选项供咱们来修改。

  appendfsync always:每次有新命令追加到 AOF 文件时就执行一次 fsync ,很是慢,也很是安全。

  appendfsync everysec:每秒 fsync 一次,足够快(和使用 RDB 持久化差很少),而且在故障时只会丢失 1 秒钟的数据。

  appendfsync no:从不 fsync ,将数据交给操做系统来处理。更快,也更不安全的选择。

  大概在728-730行设置这三种策略,默认的每秒一次,也是推荐使用的,三种策略只能选择其中一种生效。一组set testkey testvalue命令大概这样的

*3 表示占了几个位置,*3表示占了三个位置,也就是*** *** *** 样式的命令
$3  表示下面命令占位的长度
set  就是咱们实际的命令
$7  表示下一个命令占位的长度
testkey  就是咱们实际的命令
$9  表示下一个命令占位的长度
testvalue  就是咱们实际的命令

  咱们假象一下输入了一百次incr article:xiaocai命令,咱们如今要使用AOF来恢复咱们的文件,那么指令incr article:xiaocai就要存储100次,恢复100次,貌似效率不高啊。这里就提到了咱们的AOF文件重写。也就是把一些指令从新组合生成新的指令,但保证数据的准确性。咱们来看一下,咱们先经历三次set命令,key值是同样的,我很容易知道,这里set了三次,但前两次并无什么卵用,最后一次将咱们的值已经覆盖掉了。

127.0.0.1:6379> set xiaocai 123
OK
127.0.0.1:6379> set xiaocai 456
OK
127.0.0.1:6379> set xiaocai 666
OK
127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started
127.0.0.1:6379> 

这时应该生产三条AOF指令,咱们来执行咱们的AOF重写命令$ BGREWRITEAOF,重写以后,前面的set就不见了,相同键的set,只保留最后一次的set。可能形成乱码(咱们5.0.5默认开启了混合模式,后面会说),可是确实压缩了,恢复也是能够成功的。咱们来看一下我该掉默认配置后的AOF重写文件。

咱们能够看到咱们前两条指令被优化去掉了,这也就是咱们的AOF重写。

auto-aof-rewrite-min-size 64mb //表示当咱们的aof文件达到64M时,咱们就重写一次,建议使用默认配置就能够,太多了,重写耗时长,过小了,常常重写,消耗性能。

auto-aof-rewrite-percentage 100 这个表示。//当咱们的配置增长了100%咱们就重写一次
  说到这,两种持久化的方式就都说完了,咱们来看一下谁才是王者,谁才是最优质的。

命令 RDB AOF
启动优先级
体积
恢复速度
数据安全性 容易丢失数据 根据策略决定

注意:当咱们同时开启RDB和AOF时,当咱们重启redis时,Redis会优先去加载AOF文件来恢复咱们的数据,相对来讲AOF的数据更完整

混合模式

  重启redis时,咱们不多使用RDB来恢复内存数据,由于会丢失大量的数据。一般咱们使用AOF指令来恢复,但AOF的性能相比RDB要慢不少,看到这咱们仍是以为并无一种完美的解决方案,来持久化咱们的数据,这时Redis4.0就引出了咱们混合持久化。咱们能够经过设置 # aof-use-rdb-preamble yes来开启咱们的混合持久化,这时咱们生成的持久化文件内部仍是AOF的,但咱们重写的时候,会将这些AOF的指令重写为二进制文件。这样咱们就综合了RDB和AOF的优点,在恢复数据的时候大部分是执行二进制文件的,小部分来执行咱们的AOF指令操做,使咱们的恢复数据的效率更高,在备份的时候是以AOF来备份的,也保证了数据的安全性。

总结

  此次咱们主要说了咱们的Redis的内存高性能,Redis在内存来计算的,再就是咱们的高级设置keys *(少用或者别用)和咱们的scan命令,再就是Redis的持久化,两种RDB和AOF,RDB持久化可能数据丢失,可是二进制文件恢复的快,AOF持久化几乎不会丢数据,可是是指令的模式,恢复数据效率低。因为都有缺点咱们引入了混合模式,保存用AOF来存,恢复用RDB+AOF来恢复。再就是一个重点是save和bgsave的区别。记住bgsave是后台执行的,须要fork子进程,消耗内存,可是不阻塞Redis的其它线程。

  今天就说这么多,下次博文咱们说说咱们的主从模式,哨兵模式和咱们的Redis集群。


 


 最进弄了一个公众号,小菜技术,欢迎你们的加入

相关文章
相关标签/搜索