四. 核心原理

Redis的单线程和高性能
Redis 单线程为何还能这么快?

由于它全部的数据都在内存中,全部的运算都是内存级别的运算,并且单线程避免了多线程的切换性能损耗问题。正由于 Redis 是单线程,因此要当心使用 Redis 指令,对于那些耗时的指令(好比keys),必定要谨慎使用,一不当心就可能会致使 Redis 卡顿。redis

官方提供的数据: 10万+QPS(query per second,每秒内查询次数)数据库

彻底基于内存,绝大部分请求是纯粹的内存操做,执行效率高缓存

数据结构简单,对数据操做也简单(它不使用表,它的数据库不会预约义或者强制去要求用户对redis的存储进行关联。存储结构就是键值对,相似于hashMap,查找和操做时间的复杂度都是低的)安全

采用单线程,单线程也能处理高并发请求,想多核也能够启动多个实例。(redis的主线程是单线程的,主线程负责io事件的处理以及io对应的相关请求的事件处理,还负责过时键的处理,赋值协调,集群协调等等。这些除了io事件的逻辑会被封装成周期性的任务,由主线程周期性处理。全部对于客户端的全部读写请求都是由一个主线程的串行处理。所以多个客户端对一个键进行写操做的时候,不会有并发的问题。避免了频繁的上下文切换和锁竞争的问题。这效率更高。)服务器

使用多路I/O复用模型,非阻塞IO数据结构

Redis 单线程如何处理那么多的并发客户端链接?

Redis的IO多路复用:redis利用epoll来实现IO多路复用将链接信息和事件放到队列中,依次放到文件事件分派器,事件分派器将事件分发给事件处理器。多线程

Nginx也是采用IO多路复用原理解决C10K问题并发

持久化
RDB快照(snapshot)

在默认状况下, Redis 将内存数据库快照保存在名字为 dump.rdb 的二进制文件中。保存某个时间点的全量数据快照。app

  1. 配置文件redis.conf

save 900 1 ==>900秒内有1条是更改(增删改)指令,就产生一次快照,进行了一次备份 save 300 10 ==>300秒内有10条是更改(增删改)指令,就产生一次快照,进行了一次备份,若是300秒内没有到达10条写入,就要等待900秒。 save 60 10000 ==>60秒内有10000条是更改(增删改)指令,就产生一次快照,进行了一次备份,若是60秒内没有到达10000条写入,就要等待300秒。高并发

stop-writes-on-bgsave-error yes ==>yes:当备份进程出错的时候,主进程就中止接受新的写入操做,保护持久化的数据一致性的问题。

rdbcompression yes ==>在备份的时候,须要将rdb文件进行压缩后采起保存。这边通常不开启,设置为no,由于redis自己属于cpu密集型服务器,在开启压缩会带来更多的cpu消耗,相比硬盘成本,cpu更值钱。

dbfilename dump.rdb ===>建立备份文件名

dir ./ ===>备份文件的路径

在save的最后配置 : save "" ===>此时将RDB的配置开启了

RDB文件在: src/dump.rdb。此文件是一个二进制文件

SAVE:阻塞Redis的服务进程,直到RDB文件被建立完成

BGSAVE:Fork出一个子进程来传解RDB文件,不阻塞服务器进程。

举例: 先删除dump.rdb,开启一个客户端:save ===>此时服务器卡顿,直到dump.rdb建立出来。

lastsave ===>返回一个相似时间戳的数字,记录上次执行save的时间。

bgsave ===>保存数据,而且服务器不卡顿,通常在设计的时候按照:mv dump.rdb dumpxxxx.rdb,以这种时间戳的方式记录某个时间点的备份。

自定触发RDB持久化

根据redis.conf配置里的SAVE m n定时触发(用的是BGSAVE)

主从复制时,主节点自定触发

直到Debug Reload

执行Shutdown且没有开启AOF持久化

系统调用fork():建立进程,实现Copy- on -write

RDB持久化缺点:

内存数据的全量同步,数据量大会因为I/O而严重影响性能

可能会由于Redis挂掉而丢失从当前最忌一次快照期间的数据

查看rdb: src/redis-check-rdb dump.rdb

AOF快照(append-only file)

快照功能并非很是耐久(durable): 若是 Redis 由于某些缘由而形成故障停机, 那么服务器将丢失最近写入、且仍未保存到快照中的那些数据.

AOF(Append-Only-File)持久化:保存写状态 ===>redis默认是关闭的

记录下除了查询之外的全部变动数据库状态的指令

以append的形式追加保存到AOP文件中(增量)

配置文件redis.conf:

appendonly no ==>修改成yes,开启aof持久化,默认生成文件的路径redis/src/appendonly.aof

appendfilename "appendonly.aof" ===>aof格式持久化文件名

appendfsync everysec ==>配置aof文件写入的方式:

always:一旦缓存区的数据发生变化,就老是及时将缓存区的内容写入到AOF中

everysec:将缓存区的内容每隔1秒写入AOF文件中 ===>经常使用的方式

no:将缓存区数据写入AOF文件的操做交给操做系统来决定。

推荐(而且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略能够兼顾速度和安全性。

第一次启动要开启AOF操做,生成文件,客户端命令:config set appendonly yes

日志重写解决AOF文件大小不断增大的问题,原理以下:

调用fork(),建立一个子进程

子进程把新的AOF写道一个临时文件里,不依赖原来的AOF文件

主进程持续将新的变更同时写到内存和原来的AOF里

主进程获取子进程重写AOF的完成信号,往新AOF同步增量变更

是用新的AOF文件替换调旧的AOF文件

RDB和AOF的比较:

RDB优势:全量数据快照,文件小,恢复快

RDB缺点:没法保存最忌一次快照以后的数据

AOF优势:可读性高,时候保存增量数据,数据不易丢失

AOF缺点:文件体积大,恢复时间长。

RDB 和 AOF ,我应该用哪个?

若是你很是关心你的数据, 但仍然能够承受数分钟之内的数据丢失, 那么你能够只使用 RDB 持久化。有不少用户都只使用 AOF 持久化, 但咱们并不推荐这种方式: 由于定时生成 RDB 快照(snapshot)很是便于进行数据库备份, 而且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快

Redis 4.0 混合持久化

重启 Redis 时,咱们不多使用 rdb 来恢复内存状态,由于会丢失大量数据。咱们一般使用 AOF 日志重放,可是重放 AOF 日志性能相对 rdb 来讲要慢不少,这样在 Redis 实例很大的状况下,启动须要花费很长的时间。 Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。AOF在重写(aof文件里可能有太多没用指令,因此aof会按期根据内存的最新数据生成aof文件)时将重写这一刻以前的内存rdb快照文件的内容和增量的 AOF修改内存数据的命令日志文件存在一块儿,都写入新的aof文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行更名,原子的覆盖原有的AOF文件,完成新旧两个AOF文件的替换;

AOF根据配置规则在后台自动重写,也能够人为执行命令bgrewriteaof重写AOF。 因而在 Redis 重启的时候,能够先加载 rdb 的内容,而后再重放增量 AOF 日志就能够彻底替代以前的 AOF 全量文件重放,重启效率所以大幅获得提高。

开启混合持久化:aof-use-rdb-preamble yes

混合持久化aof文件结构: appendonly.aof = RDB格式+ AOF格式

开启混合持久化以后,set数据以后,查看生成的appendonly.aof文件:more appendonly.aof
此时生成的文集中包含RDB二进制快照数据+ AOF追加的命令数据

AOF重写功能: 通常是redis后台进程去作,能够手动触发命令: bgrewriteaof.

其实是把那些大规模的对同一个key全部的操做把它变成最终的一条set值的操做.

eg: incr requestlock
incr requestlock
incr requestlock
incr requestlock
=====>重写以后的命令 : set requestlock 4

问题1: 混合重写必需要aof和rdb同时设置为yes么 仍是混合的这个设为yes就行?

aof和混合那个都要设为yes,混合那个是基础aof的

问题2: 手动重写aof文件,若是文件很大,重写 须要花很长时间,这个时候恰好又有新操做的数据怎么办?

新操做会存在内存里,等到aof重写完再最加到aof文件的末尾,aof重写的数据就是重写开始以前的内存数据

问题3: redis hash冲突后进行rehash 若是再冲突继续rehash?到最后还会不会有冲突的结果?

不是hash冲突后立刻进行rehash,是redis扩容后以前的元素再作rehash从新定位,扩容是根据redis内部的扩容因子来计算的,跟hashmap扩容相似,冲突一直均可能有,只不过redis会尽可能经过扩容来减少冲突

相关文章
相关标签/搜索