1、什么是Redis?
redis全称是Remote Dictionary Server,是一个基于内存的高性能键值对数据库,redis每秒可以处理超过10万次读写操作,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据刷新到硬盘上进行保存。
2、Redis支持哪几种数据类型?
五种数据类型,字符串、散列、列表、集合、有序集合
3、Redis特性有哪些?
速度快:所有数据放在内存中,读写性能10万/秒。
持久化:提供两种持久化方式,RDB和AOF。
主从复制:复制功能是分布式redis的基础。
高可用:sentinel监控节点故障并自动切换。
分布式:提供高可用、读写和容量扩展。
支持的客户端语言多,涵盖了主流的编程语言。
4、Redis应用场景有哪些?
缓存:通过键值过期时间设置降低后端数据源的压力。
排行榜:列表和有序集合构建排行榜系统。
计数器:保证数据实时性。
位操作:大数据处理。
Redis不适用哪些场景
不适用反复操作冷数据,浪费内存
冷数据:不需要加速读写的数据
热数据:需要频繁操作的数据
5、Redis相比memcached有哪些优势?
(1) memcached所有的值均是简单的字符串,redis支持五种数据类型
(2) redis的速度比memcached快很多
(3) redis可以持久化其数据
6、Redis有哪几种数据淘汰策略?
六种淘汰策略
volatile & all keys 最近最久未使用、随机删除
volatile 设置过期时间的,马上要过期的删除
no eviction 不删除任意数据(默认)
规则名称 |
规则说明 |
volatile-lru |
使用LRU算法删除一个键(只对设置了生存时间的键) |
allkeys-lru |
使用LRU算法删除一个键 |
volatile-random |
随机删除一个键(只对设置了生存时间的键) |
allkeys-random |
随机删除一个键 |
volatile-ttl |
删除生存时间最近的一个键 |
noeviction |
不删除键,只返回错误 |
7、一个字符串类型的值能存储最大容量是多少?
512M
8、为什么Redis需要把所有数据放到内存中?
Redis为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘。所以redis具有快速和数据持久化的特征。如果不将数据放在内存中,磁盘I/O速度为严重影响redis的性能。如果设置了最大使用的内存,则数据已有记录数达到内存限值后不能继续插入新值。
9、Redis的持久化机制是什么?
由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据。
RDB(全量备份)和AOF(实时备份)
RDB持久化是把当前进程数据生成快照保存到硬盘的过程,触发RDB持久化过程分为手动触发和自动触发。
save命令:阻塞当前Redis服务器,直到RDB过程完成为止,对于内存比较大的实例会造成长时间阻塞,线上环境不建议使用。
bgsave命令:Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。
AOF(append only file)持久化:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性。
10、RDB和AOF的优缺点分别是什么
RDB优势:
RDB是一个紧凑压缩的二进制文件,代表Redis在某个时间点上的数据快照。非常适用于全量复制。比如每6小时执行bgsave备份,并把RDB文件拷贝到远程机器或者文件系统中(如hdfs),用于灾难恢复。
Redis加载RDB恢复数据远远快于AOF的方式。
RDB劣势:
RDB方式数据没办法做到实时持久化/秒级持久化。因为bgsave每次运行都要执行fork操作创建子进程,属于重量级操作,频繁执行成本过高。
RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个格式的RDB版本,存在老版本Redis服务无法兼容新版RDB格式的问题。
AOF优势:
(1)AOF有3种同步策略,“每秒同步、每修改同步和不同步。”
每秒同步是异步完成的,其效率也是非常高的,所差的是一旦系统出现宕机现象,那么这一秒钟之内修改的数据将会丢失。
每修改同步,我们可以将其视为同步持久化,即每次发生的数据变化都会被立即记录到磁盘中。这种方式在效率上是最低的。
无同步如字面意思。
(2)AOF对日志文件的写入操作是append模式,写入过程中即使出现宕机也不会破坏日志文件中已经存在的内容。如果我们只写入了一半数据就出现了系统崩溃问题,在Redis下一次启动之前,可以通过redis-check-aof工具来解决数据一致性的问题。
(3)如果日志过大,Redis可以自动启用rewrite机制。以append模式不断的将修改数据写入到老的磁盘文件中,同时Redis还会创建一个新的文件用于记录此期间有哪些修改命令被执行。
AOF劣势:
(1)对于相同数量的数据集而言,AOF文件通常要大于RDB文件。AOF在恢复大数据集时的速度比RDB的恢复速度慢。
(2)根据同步策略的不同,AOF在运行效率上往往会慢于RDB。总之,每秒同步策略的效率是比较高的,同步禁用策略的效率和RDB一样高效。
二者选择的标准
牺牲一些性能,换取更高的缓存一致性(aof)
写操作频繁的,不启用备份来换取更高的性能,待手动运行save的时候,再做备份(rdb)。
Redis4.0之后有了混合持久化的功能,将bgsave的全量和aof的增量做了融合处理,这样既保证了恢复的效率又兼顾了数据的安全性。
那如果突然机器掉电会怎样?
取决于aof日志sync属性的配置,如果不要求性能,在每条写指令时都sync一下磁盘,就不会丢失数据。但是在高性能的要求下每次都sync是不现实的,一般都使用定时sync,比如1s1次,这个时候最多就会丢失1s的数据。
11、简述Redis的读写分离模型。
通过增加Slave DB的数量,读的性能可以线性增长。为了避免Master DB的单点故障,集群一般都会采用两台Master DB做双机热备,所以整个集群的读和写的可用性都非常高。
读写分离架构的缺陷在于,不管是Master还是Slave,每个节点都必须保存完整的数据,如果在数据量很大的情况下,集群的扩展能力还是受限于单个节点的存储能力,而且对于Write-intensive(写密集型)类型的应用,读写分离架构并不适合。
12、哨兵是什么?
Redis Sentinel是redis高可用性解决方案。监控master和slave的状态并自动切换。
在使用sentinel监控主从节点时,从节点需要使用动态方式配置[slaveof masterIP PORT],
尽可能在不同物理机上部署Redis Sentinel所有节点。
Redis Sentinel在对节点做失败判定时分为主观下线和客观下线。
主观下线
单个sentinel认为某个节点下线(通过判断ping回复是有效回复,还是无效回复来判断实例时候在线)
客观下线
sentinel监视的某个节点主观下线后,sentinel会询问其它监视该服务的sentinel,看它们是否也认为该服务主观下线,接收到足够数量(这个值可以配置)的sentinel判断为主观下线,既任务该服务客观下线,并对其做故障转移操作。
选举领头sentinel
一个redis服务被判断为客观下线时,多个监视该服务的sentinel协商,选举一个领头sentinel,对该redis服务进行故障转移操作。选举领头sentinel遵循以下规则:
所有的sentinel都有且只有一次将某个sentinel选举成领头的机会(在一轮选举中),一旦选举某个sentinel为领头,不能更改,sentinel设置领头sentinel是先到先得,一旦当前sentinel设置了领头sentinel,以后要求设置sentinel为领头请求都会被拒绝
每个发现服务客观下线的sentinel,都会要求其他sentinel将自己设置成领头
如果某个sentinel被半数以上的sentinel设置成领头,那么该sentinel既为领头
如果在限定时间内,没有选举出领头sentinel,暂定一段时间,再选举
13、简述Redis集群。
Redis集群是一个无中心的分布式存储架构,在3.0版本正式推出,可以在多个节点之间进行数据共享,解决了Redis高可用、可扩展等问题。redis集群提供了以下两个好处
(1)将数据自动切分(split)到多个节点
(2)当集群中的某一个节点故障时,redis还可以继续处理客户端的请求。
一个 Redis 集群包含 16384 个哈希槽(hash slot),数据库中的每个数据都属于这16384个哈希槽中的一个。集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽。集群中的每一个节点负责处理一部分哈希槽。
(3)如果某一个主节点和他所有的从节点都下线的话,redis集群就会停止工作
14、Redis集群方案有哪些?
(1) twemproxy,类似于一个代理方式,使用方法和普通redis无任何区别,设置好它下属的多个redis实例后,使用时在本需要连接redis的地方改为连接twemproxy,它会以一个代理的身份接收请求并使用一致性hash算法,将请求转接到具体redis,将结果再返回twemproxy。使用方式简便(相对redis只需修改连接端口),对旧项目扩展的首选。 问题:twemproxy自身单端口实例的压力,使用一致性hash后,对redis节点数量改变时候的计算值的改变,数据无法自动移动到新的节点。
(2)codis,目前用的最多的集群方案,基本和twemproxy一致的效果,但它支持在节点数量改变情况下,旧节点数据可恢复到新hash节点。
(3)redis cluster3.0自带的集群,特点在于他的分布式算法不是一致性hash,而是hash槽的概念,以及自身支持节点设置从节点。
15、Redis集群的模型是怎样的?
Redis集群节点数量至少为6个才能保证组成完整高可用的集群。整个集群便有三个master节点和三个slave节点组成,每个节点需要开启配置cluster-enabled yes,让Redis运行在集群模式下。主节点负责处理哈希槽,从节点负责在主节点失效时替代主节点。
16、简述Redis哈希槽的概念?
Redis集群没有使用一致性hash算法,而是使用哈希函数把所有数据映射到一个固定范围的整数集合中,整数定义为槽(slot)。这个范围一般远远大于节点数,比如Redis Cluster槽范围是0~16383。每个key通过CRC16校验后对16384取模来决定放置哪个槽。槽是集群内数据管理和迁移的基本单位。采用大范围槽的主要目的是为了方便数据拆分和集群扩展。每个节点会负责一定数量的槽。由于采用高质量的哈希算法,每个槽所映射的数据通常比较均匀,将数据平均划分若干个节点进行数据分区。
17、Redis集群会有写操作丢失吗?为什么?
Redis并不能保证数据的强一致性,这意味这在实际中集群在特定的条件下可能会丢失写操作。
18、Redis集群之间是如何复制的?
使用异步复制(asynchronous replication)是Redis集群可能会丢失写命令的其中一个原因,有时候由于网络原因,如果网络断开时间太长,redis集群就会启用新的主节点,之前发给主节点的数据就会丢失。
19、Redis集群最大节点个数是多少?
16384个。
20、怎么测试Redis的连通性?
ping
21、怎么理解Redis事务?
事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。
事务
一组命令要么全部执行,要么全部不执行
redis将一组需要一起执行的命令放到multi和exec两个命令之间。
multi代表事务开始,exec代表事务结束。
22、部署哨兵的方法
(1)修改sentinel.conf文件
sentinel monitor mymaster [IP] [PORT] [个数]
需要判定客观下线所需的主观下线sentinel个数不可以大于sentinel个数
(2)sentinel命令
sentinel的基本状态信息
info
列出所有被监视的主服务器,以及这些主服务器的当前状态
sentinel masters
列出给定主服务器的所有从服务器,以及这些从服务器的当前状态
sentinel slaves <master name>
重置所有名字和给定模式 pattern 相匹配的主服务器。重置操作清除主服务器目前的所有状态, 包括正在执行中的故障转移,并移除目前已经发现和关联的,主服务器的所有从服务器和 Sentinel 。
sentinel reset <pattern>
23、构建Redis集群的方法?
(1)创建至少6个节点,3主3从
安装redis:
yum install -y gcc tcl
tar zxvf redis-3.2.9.tar.gz
make && make install
安装redis-cluster环境:
yum install -y ruby ruby-rdoc #安装ruby
yum install -y rubygems #安装rubygems
下载redis-3.0.0.gem #安装redis的api接口
gem install -l redis-3.0.0.gem #执行安装
修改主配置文件:
[root@localhost ~]# vim /usr/local/rediscluster/7000/redis.conf
bind 192.168.81.1
protected-mode yes
port 7000
tcp-backlog 511
timeout 0
tcp-keepalive 60
daemonize yes
supervised no
pidfile /usr/local/rediscluster/7000/redis.pid
loglevel notice
logfile "/usr/local/rediscluster/7000/logs/rediscluster_7000.log"
databases 16
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir "/usr/local/rediscluster/7000/redisdata"
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
rename-command CONFIG ""
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command EVAL ""
maxmemory 50g
maxmemory-policy allkeys-lru
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
cluster-enabled yes
cluster-config-file nodes-7000.conf
cluster-node-timeout 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
(2) 构建集群操作(节点握手&分槽,在任意一台上操作即可)
./redis-trib.rb create --replicas 1 192.168.81.1:7000 192.168.81.2:7000 192.168.81.3:7000 192.168.81.4:7000 192.168.81.5:7000 192.168.81.6:7000
检查集群状态:
./redis-trib.rb check 192.168.81.1:7000
redis-cli -h 192.168.81.1 -p 7000
192.168.81.1:7000> cluster nodes
24、Redis客户端的常用命令?
(1) Redis服务启动停止
redis-server [配置文件] #启动
killall redis-server #停止
(2) Redis客户端使用
redis-cli -h ip -p 7000 #进入客户端:
rediscluster-cli #该命令为自定义命令,集成ip和端口参数得输入
Redis客户端常用命令
> info replication #查看当前节点的主从对应关系等
> cluster nodes #查看节点id和主从关系等
> cluster info #查看集群信息,健康状态等
(3)集群管理工具redis-trib.rb
①检查集群状态
cd /usr/local/redis-3.2.9/src && ./redis-trib.rb check ip:port
或
rediscluster-check #该命令为自定义命令,集成了ip和端口等参数的输入
②添加主节点
# cd /usr/local/redis-3.2.9/src
# ./redis-trib.rb add-node new_host:new_port existing_host:existing_port
③添加从节点
# cd /usr/local/redis-3.2.9/src
# ./redis-trib.rb add-node \
--slave --master-id ******** \
new_host:new_port existing_host:existing_port
④添加重新分片
# cd /usr/local/redis-3.2.9/src
# ./redis-trib.rb reshard ip:port
需要迁移多少槽位(slot)到新节点上? 按需填写(通常是16384/master数量=?)
需要迁移的新节点id是多少? 输入新加入主节点的id
需要从指定节点还是所有节点抽出槽位进行分配? 输入all表示全部,done表示指定
然后开始从别的主节点迁移哈希槽,并且确认...
⑤删除节点
# cd /usr/local/redis-3.2.9/src
# ./redis-trib.rb del-node host:port node_id #注:从节点可直接删除,主节点需要迁移slot后再删除。
注意:
new_host:new_port为新添加的ip地址和端口
existing_host:existing_port 为现有集群中的任意ip地址和端口
--master-id 后为检查集群时master的id
add-node 不加参数的话默认添加成主节点,只加 --slave参数会给该从节点随机指派一个主节点,加 --slave --master-id可以自行指派主节点。
原文:https://www.cnblogs.com/yexifeng0214/p/9940997.html