上次咱们简单的说了一下咱们的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集群。
最进弄了一个公众号,小菜技术,欢迎你们的加入