redis-question

Redis

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可以自行指派主节点。

猜你喜欢

转载自www.cnblogs.com/yexifeng0214/p/9940997.html