Redis面试总结
Posted dai-zhe
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis面试总结相关的知识,希望对你有一定的参考价值。
简介 redis3.0以上支持redis cluster
redis :remote dictionary server 远程字典服务
nosql非关系型数据库:redis/memcached/mongoDB/hbase
redis和memcached区别
1)redis支持存储多种数据结构
redis不仅仅支持简单的K/V数据类型的存储,同时还提供string(字符串)、list(列表)、set(集合)、zset(有序集合),hash(哈希数据)等数据结构的存储
支持更大的value数据:memcache单个key value最大,支持1MB,而redis最大支持512MB。
2)redis支持数据的备份
redis支持数据的备份,即master<----->slave模式的数据备份,redis通过哨兵(sentlinet)来进行主从的切换
从redis 3.0开始支持redis cluster 集群
3)redis支持数据持久化(RDB/AOF)
1:在redis中并不是所有的数据都一直存储在内存中的,这是redis和memcache最致命的优势,反之memcached存储的数据是完全存储在内存中的
2:另外redis单线程,memcached多线程(多线程的好处-->可以使用多核心cpu)
3:虽然:redis是单线程但是功能也不是比memcached差,单线程并不会成为是redis的瓶颈
redis组件
1:redis-server --->redis的服务端
2:redis-cli --->redis的客户端
3:redis-benchmark--->压力测试工具
4:redis-check-dump / redis-check-aof --->检查redis持久化工具
redis持久化
1:redis会缓存所有的key的信息,如果redis发现内存的使用量超过了某一个阈值,可以触发启用swap,redis根据内部的算法机制计算出哪些key存储的对应的value需要swap,再将key对应的value持久化到磁盘中,同时在内存中清除
2:这种特性可以使得redis可以保持超过机器本身的大小数据,当然机器本身的内存必须要能保持所有的key
意思就是可以将值存储到磁盘中,但是键要保存在内存中
redis并发相关介绍
官网声明:
1:redis存储一百万key仅占用100m左右大小的磁盘容量
2:redis单线程,cpu不会成为redis存储大数值的瓶颈
3:redis支持每秒500W并发,较好的硬件经过测试支持百万的并发是完全没有问题的
redis持久化的两种方式
1)快照RDB (保存文件类型为二进制格式)
1:周期性的缓存数据,需要指定一个时间间隔
2:RDB持久性执行时间点快照的数据集在指定的时间间隔。二进制格式显示为dump.rdb
2)AOF实时同步
1:实时同步
每往redis中写入数据库AOF方式就会向磁盘中写入记录数据--->实时同步
2:你也可以关闭持久化就等于当服务器关机或者突然宕机时,redis的数据则将会完全丢失了,生产中建议将两种模式都启用,为RDB持久化的方式设置时间间隔,在redis服务器启动用于恢复数据时,会优先使用aof
3:在redis服务器启动用于恢复数据时,会优先使用aof
RDB模式:
-
RDB:基于时间的快照,只保留当前最新的一次快照,特点是执行速度比较快,缺点是可能会丢失从上次快照到当前快照未完成之间的数据。
-
RDB实现的具体过程Redis从主进程先fork出一个子进程,使用写时复制机制,子进程将内存的数据保存为一个临时文件,比如dump.rdb.temp,当数据保存完成之后再将上一次保存的RDB文件替换掉,然后关闭子进程,这样可以保存每一次做RDB快照的时候保存的数据都是完整的,因为直接替换RDB文件的时候可能会出现突然断电等问题而导致RDB文件还没有保存完整就突然关机停止保存而导致数据丢失的情况,可以手动将每次生成的RDB文件进程备份,这样可以最大化保存历史数据。
-
RDB模式的优缺点:
-
优点:
-
RDB快照保存了某个时间点的数据,可以通过脚本执行bgsave(非阻塞)或者save(阻塞)命令自定义时间点北备份,可以保留多个备份,当出现问题可以恢复到不同时间点的版本。
-
可以最大化io的性能,因为父进程在保存RDB 文件的时候唯一要做的是fork出一个子进程,然后的-操作都会有这个子进程操作,父进程无需任何的IO操作
-
RDB在大量数据比如几个G的数据,恢复的速度比AOF的快
-
-
缺点:
-
不能时时的保存数据,会丢失自上一次执行RDB备份到当前的内存数据
-
数据量非常大的时候,从父进程fork的时候需要一点时间,可能是毫秒或者秒
-
AOF模式:
-
AOF:按照操作顺序依次将操作添加到指定的日志文件当中,特点是数据安全性相对较高,缺点是即使有些操作是重复的也会全部记录。
-
AOF和RDB一样使用了写时复制机制,AOF默认为每秒钟fsync一次,即将执行的命令保存到AOF文件当中,这样即使redis服务器发生故障的话顶多也就丢失1秒钟之内的数据,也可以设置不同的fsync策略,或者设置每次执行命令的时候执行fsync,fsync会在后台执行线程,所以主线程可以继续处理用户的正常请求而不受到写入AOF文件的IO影响
-
AOF模式优缺点:
-
AOF的文件大小要大于RDB格式的文件
-
根据所使用的fsync策略(fsync是同步内存中redis所有已经修改的文件到存储设备),默认是appendfsync everysec即每秒执行一次fsync
-
-
redis配置
redis主要配置项:
-
bind 0.0.0.0 #监听地址,可以用空格隔开后多个监听IP
-
protected-mode yes #redis3.2 之后加入的新特性,在没有设置bind IP和密码的时候只允许访问127.0.0.1:6379
-
port 6379 #监听端口
-
tcp-backlog 511 #三次握手的时候server端收到client ack确认号之后的队列值。
-
timeout 0 #客户端和Redis服务端的连接超时时间,默认是0,表示永不超时。
-
tcp-keepalive 300 #tcp 会话保持时间
-
daemonize no #认情况下 redis 不是作为守护进程运行的,如果你想让它在后台运行,你就把它改成 yes,当redis作为守护进程运行的时候,它会写一个 pid 到 /var/run/redis.pid 文件里面
-
supervised no #和操作系统相关参数,可以设置通过upstart和systemd管理Redis守护进程,centos 7以后都使用systemd
-
pidfile /var/run/redis_6379.pid #pid文件路径,确定生成的日志目录是有权限的,实际上存放的就是进程号。
-
loglevel notice #日志级别
-
logfile “” #日志路径
-
databases 16 #设置db 库数量,默认16个库,可以连接到redis后使用select # ,切换库
-
always-show-logo yes #在启动redis 时是否显示log
-
save 900 1 #在900秒内有一个键内容发生更改就出就快照机制
-
save 300 10
-
save 60 10000
-
stop-writes-on-bgsave-error yes #快照出错时是否禁止redis 写入操作(默认为yes,建议使用no,出错的原因,磁盘满了,权限问题,改为no的原因是系统是由监控的,所以不会等磁盘满了防止数据丢失)
-
rdbcompression yes #持久化到RDB文件时,是否压缩,”yes”为压缩,”no”则反之
-
rdbchecksum yes #是否开启RC64校验,默认是开启(检查RDB文件是否完整)
-
dbfilename dump.rdb #快照文件名
-
dir ./ #快照文件保存路径
-
replica-serve-stale-data yes #当从库同主库失去连接或者复制正在进行,从机库有两种运行方式:1) 如果replica-serve-stale-data设置为yes(默认设置),从库会继续响应客户端的请求。2) 如果replica-serve-stale-data设置为no,除去指定的命令之外的任何请求都会返回一个错误”SYNC with master in progress”。
-
replica-read-only yes #是否设置从库只读
-
repl-diskless-sync no #是否使用socket方式复制数据,目前redis复制提供两种方式,disk和socket,如果新的slave连上来或者重连的slave无法部分同步,就会执行全量同步,master会生成rdb文件,有2种方式:disk方式是master创建一个新的进程把rdb文件保存到磁盘,再把磁盘上的rdb文件传递给slave,socket是master创建一个新的进程,直接把rdb文件以socket的方式发给slave,disk方式的时候,当一个rdb保存的过程中,多个slave都能共享这个rdb文件,socket的方式就是一个个slave顺序复制,只有在磁盘速度缓慢但是网络相对较快的情况下才使用socket方式,否则使用默认的disk方式
-
repl-diskless-sync-delay 5 #diskless复制的延迟时间,设置0为关闭,一旦复制开始还没有结束之前,master节点不会再接收新slave的复制请求,直到下一次开始
-
repl-ping-slave-period 10 #slave根据master指定的时间进行周期性的PING 监测
-
repl-timeout 60 #复制链接超时时间,需要大于repl-ping-slave-period,否则会经常报超时
-
repl-disable-tcp-nodelay no #在socket模式下是否slave套接字发送SYNC之后禁用 TCP_NODELAY, 如果你选择“yes”Redis将使用更少的TCP包和带宽来向slaves发送数据。但是这将使数据传输到slave上有延迟,Linux内核的默认配置会达到40毫秒,如果你选择了 “no” 数据传输到salve的延迟将会减少但要使用更多的带宽
-
repl-backlog-size 1mb #复制缓冲区大小,只有在slave连接之后才分配内存。
-
repl-backlog-ttl 3600 #多次时间master没有slave连接,就清空backlog缓冲区。
-
replica-priority 100 #当master不可用,Sentinel会根据slave的优先级选举一个master。最低的优先级的slave,当选master。而配置成0,永远不会被选举。
-
requirepass foobared #设置redis 连接密码
-
rename-command #重命名一些高危命令
-
maxclients 10000 #最大连接客户端(根据生产进行调整)
-
maxmemory #最大内存,单位为bytes字节,8G内存的计算方式8(G)1024(MB)1024(KB)*1024(Kbyte),需要注意的是slave的输出缓冲区是不计算在maxmemory内。(如果不限制,则redis无限使用物理内存,最后将服务器的进程kill掉,最好给予系统内存的一半,生产使用redis建议服务器16G给redis服务器8G)
-
appendonly no #是否开启AOF日志记录,默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了。但是redis如果中途宕机,会导致可能有几分钟的数据丢失,根据save来策略进行持久化,Append Only File是另一种持久化方式,可以提供更好的持久化特性。Redis会把每次写入的数据在接收后都写入 appendonly.aof 文件,每次启动时Redis都会先把这个文件的数据读入内存里,先忽略RDB文件。
-
appendfilename “appendonly.aof” #AOF文件名
-
appendfsync everysec #aof持久化策略的配置,no表示不执行fsync,由操作系统保证数据同步到磁盘,always表示每次写入都执行fsync,以保证数据同步到磁盘,everysec表示每秒执行一次fsync,可能会导致丢失这1s数据。
-
no-appendfsync-on-rewrite no在aof rewrite期间,是否对aof新记录的append暂缓使用文件同步策略,主要考虑磁盘IO开支和请求阻塞时间。默认为no,表示”不暂缓”,新的aof记录仍然会被立即同步,Linux的默认fsync策略是30秒,如果为yes 可能丢失30秒数据,但由于yes性能较好而且会避免出现阻塞因此比较推荐。
-
auto-aof-rewrite-percentage 100 # 当Aof log增长超过指定比例时,重写log file, 设置为0表示不自动重写Aof 日志,重写是为了使aof体积保持最小,而确保保存最完整的数据。
-
auto-aof-rewrite-min-size 64mb #触发aof rewrite的最小文件尺寸
-
aof-load-truncated yes #是否加载由于其他原因导致的末尾异常的AOF文件(主进程被kill/断电等)
-
aof-use-rdb-preamble yes #redis4.0新增RDB-AOF混合持久化格式,在开启了这个功能之后,AOF重写产生的文件将同时包含RDB格式的内容和AOF格式的内容,其中RDB格式的内容用于记录已有的数据,而AOF格式的内存则用于记录最近发生了变化的数据,这样Redis就可以同时兼有RDB持久化和AOF持久化的优点(既能够快速地生成重写文件,也能够在出现问题时,快速地载入数据)。
-
lua-time-limit 5000 #lua脚本的最大执行时间,单位为毫秒
-
cluster-enabled yes #是否开启集群模式,默认是单机模式
-
cluster-config-file nodes-6379.conf #由node节点自动生成和的集群配置文件
-
cluster-node-timeout 15000 #集群中node节点连接超时时间
-
cluster-replica-validity-factor 10 #在执行故障转移的时候可能有些节点和master断开一段时间数据比较旧,这些节点就不适用于选举为master,超过这个时间的就不会被进行故障转移
-
cluster-migration-barrier 1 #一个主节点拥有的至少正常工作的从节点,即如果主节点的slave节点故障后会将多余的从节点分配到当前主节点成为其新的从节点。
-
cluster-require-full-coverage yes #集群槽位覆盖,如果一个主库宕机且没有备库就会出现集群槽位不全,那么yes情况下redis集群槽位验证不全就不再对外提供服务,而no则可以继续使用但是会出现查询数据查不到的情况(因为有数据丢失)。
-
cluster-replica-no-failover no#Slow log 是 Redis 用来记录查询执行时间的日志系统,slow log 保存在内存里面,读写速度非常快,因此你可以放心地使用它,不必担心因为开启 slow log 而损害 Redis 的速度。
-
slowlog-log-slower-than 10000 #以微秒为单位的慢日志记录,为负数会禁用慢日志,为0会记录每个命令操作。
-
slowlog-max-len 128 #记录多少条慢日志保存在队列,超出后会删除最早的,以此滚动删除
redis对事务的支持
事务:一组相关的操作是原子性的,要么都执行,要么都不执行
一组事务,要么成功;要么撤回。
mysql 事务简介:http://www.runoob.com/mysql/mysql-transaction.html
redis通过multi exec watch 等命令实现事务功能
开始事务:multi命令开始事务
在事务进行过程中,其他对redis的操作都会被阻塞
Exec:一并返回
redis主从复制
一个master可以有多个slave
一个slave还可以再有slave,所以支持链式复制
Master 以非阻塞方式同步数据至salve ,master可以同时处理多个slave的操作
redis安全简介
1).禁止一些高危命令
修改 redis.conf 文件,添加
rename-command FLUSHALL "" #配置文件中执行清空当前的数据库时,定义空值,则不执行任何操作
rename-command CONFIG ""
rename-command EVAL ""
来禁用远程修改 DB 文件地址
2).以低权限运行 Redis 服务
为 Redis 服务创建单独的用户和家目录,并且配置禁止登陆
3).为 Redis 添加密码验证
修改 redis.conf 文件,添加
requirepass mypassword
4).禁止外网访问 Redis
修改 redis.conf 文件,添加或修改
bind 10.0.140.84
使得 Redis 服务只在当前主机可用
redis cluster
1)集群作用
-
master和slave角色的无缝切换,让业务无感知从而不影响业务使用
-
可以横向动态扩展Redis服务器,从而实现多台服务器并行写入以实现更高并发的目的。
-
Redis 集群实现方式:客户端分片 代理分片 Redis Cluster(做集群一般使用奇数台服务器做集群,3、5、7,损坏的节点剩余要大于总节点的一半)
2)集群特征
在哨兵sentinel机制中,可以解决redis高可用的问题,即当master故障后可以自动将slave提升为master从而可以保证redis服务的正常使用,但是无法解决redis单机写入的瓶颈问题,即单机的redis写入性能受限于单机的内存大小、并发数量、网卡速率等因素,因此redis官方在redis 3.0版本之后推出了无中心架构的redis cluster机制,在无中心的redis集群汇中,其每个节点保存当前节点数据和整个集群状态,每个节点都和其他所有节点连接,特点如下:
-
1:所有Redis节点使用(PING-PING机制)互联
-
2:集群中某个节点的实效是整个集群中超过半数的节点监测都实效才算真正的实效
-
3:客户端不需要proxy即可直接连接redis,且客户端不需要连接集群中的所有节点,只要连接集群中的任何一个节点即可。
-
4:redis cluster把所有的redisnode映射到 0-16383个槽位(slot)上,读写需要到指定的redis node上进行操作,因此有多少个reids node相当于redis 并发扩展了多少倍。
-
5:Redis集群预先分配16384个(slot)槽位,当需要在redis集群中写入一个key -value的时候,会使用CRC16(key) mod 16384之后的值,决定将key写入值哪一个槽位从而决定写入哪一个Redis节点上,从而有效解决单机瓶颈。
redis哨兵(sentinel)port:26379
什么是哨兵机制?
Redis的哨兵(sentinel) 系统用于管理多个 Redis 服务器,该系统执行以下三个任务: ? 监控(Monitoring): 哨兵(sentinel) 会不断地检查你的Master和Slave是否运作正常。 ? 提醒(Notification):当被监控的某个 Redis出现问题时, 哨兵(sentinel) 可以通过 API 向管理员或者其他应用程序发送通知。
自动故障迁移(Automatic failover):当一个Master不能正常工作时,哨兵(sentinel) 会开始一次自动故障迁移操作,它会将失效Master的其中一个Slave升级为新的Master, 并让失效Master的其他Slave改为复制新的Master; 当客户端试图连接失效的Master时,集群也会向客户端返回新Master的地址,使得集群可以使用Master代替失效Master。
哨兵(sentinel) 是一个分布式系统,你可以在一个架构中运行多个哨兵(sentinel) 进程,这些进程使用流言协议(gossipprotocols)来接收关于Master是否下线的信息,并使用投票协议(agreement protocols)来决定是否执行自动故障迁移,以及选择哪个Slave作为新的Master。 ? 每个哨兵(sentinel) 会向其它哨兵(sentinel)、master、slave定时发送消息,以确认对方是否”活”着,如果发现对方在指定时间(可配置)内未回应,则暂时认为对方已挂(所谓的”主观认为宕机” Subjective Down,简称sdown). 若“哨兵群”中的多数sentinel,都报告某一master没响应,系统才认为该master"彻底死亡"(即:客观上的真正down机,Objective Down,简称odown),通过一定的vote算法,从剩下的slave节点中,选一台提升为master,然后自动修改相关配置。 ? 虽然哨兵(sentinel) 释出为一个单独的可执行文件 redis-sentinel ,但实际上它只是一个运行在特殊模式下的 Redis 服务器,你可以在启动一个普通 Redis 服务器时通过给定 --sentinel 选项来启动哨兵(sentinel)。 ? 哨兵(sentinel) 的一些设计思路和zookeeper非常类似
以上是关于Redis面试总结的主要内容,如果未能解决你的问题,请参考以下文章