redis_基础学习

1 介绍一下Redis

Redis 是一款使用 C 语言编写的高性能 key-value 数据库,开源免费,遵守 BSD 协议。BSD开源协议是一个给于使用者很大自由的协议。可以自由的使用,修改源代码,也可以将修改后的代码作为开源或者专有软件再发布。

特点:
性能极高,能到 100000 次/s 读写速度
支持数据的持久化,对数据的更新采用Copy-on-write技术,可以异步地保存到磁盘上
丰富的数据类型,String(字符串)、List(列表)、Hash(字典)、Set(集合)、Sorted Set(有序集合)
原子性:Redis 的所有操作都是原子性的,多个操作通过 MULTI 和 EXEC 指令支持事务
丰富的特性:key 过期、publish/subscribe、notify
支持数据的备份,快速的主从复制
节点集群,很容易将数据分布到多个Redis实例中

2、Copy-on-write

RDB持久化:bgsave触发,Redis调用fork()函数,创建一个子进程(子进程与父进程共内存),子进程执行持久化操作,将内存中的缓存持久化到一个rdb临时文件,待到持久化完成,临时文件替换旧的dump.rdb文件。自此一次RDB持久化操作就完成了。

AOF持久化:AOF持久化时,会将新写入的命令放入aof_buff中,然后检测时间(这个时间就是redis.conf中配置的aof执行频率),再决定是否持久化。当发生aof日志重写时,Redis同样会调用fork()函数,创建一个子进程,对当前内存中的数据进行持久化到一个临时aof文件,这个期间产生的写操作会存入缓冲区,待到持久化完成后,再将缓冲区的操作写入aof后面。
上面对redis持久化的解释在很多文章中都有介绍。咋一看,好像很严谨,但是细心的朋友可能会有个疑问,在子进程持久化数据的过程中,若客户端对内存数据有改动,这时子进程持久化的数据是旧数据还是新数据呢?
这是个比较细节的问题,涉及到的是Redis的写时复制(copy-on-write)策略。我们以RDB持久化讲解。 redis有一个主进程,
在写数据, 这时候有一个命令(bgsave)过来了, 说要把数据持久化到磁盘.(下图为redis没有开始bgsave的模型图)

在这里插入图片描述

我们知道redis的worker是单线程的, 如果要持久化这个行为也放在单线程里, 那么如果需要持久化数据特别多, 将会影响用户的使用. 所以单开一个进程专门来做持久化的操作.那么写数据, 写什么呢? 肯定是要把redis内存中的数据写入. 这时候, 其实redis内存中的数据保存的是一个虚拟地址. 他真实指向的是物理内存的地址(绿色部分)

在这里插入图片描述

这时候, 要拷贝, 就是把真实数据的地址拷贝一份到需要持久化的进程中,注意这边是拷贝地址,执行很快。

在这里插入图片描述

其实持久化进程这个时候只是指向了数据的地址, 内存消耗并不多. 如果这时候, 原来的数据修改了, 怎么办呢?Redis会开辟一块新的空间, 让写数据的地址指向新的空间,这里就是copy-on-write策略,持久化的还是修改之前的数据,修改的数据已经是复制出来的另一份数据了。

在这里插入图片描述

AOF日志重写过程中也是用到了copy-on-write策略(如上)。

2 Redis支持哪些数据类型?

Redis 支持五种数据类型
string:字符串
hash:哈希
list:列表
set:集合
sorted set:有序集合

3 Redis有哪些优缺点?

优点: 性能极高,能到 100000 次/s 读写速度
支持数据的持久化,对数据的更新采用Copy-on-write技术,可以异步地保存到磁盘上
丰富的数据类型,String(字符串)、List(列表)、Hash(字典)、Set(集合)、Sorted Set(有序集合)
原子性:Redis 的所有操作都是原子性的,多个操作通过 MULTI 和 EXEC 指令支持事务 丰富的特性:key
过期、publish/subscribe、notify 支持数据的备份,快速的主从复制 节点集群,很容易将数据分布到多个Redis实例中

缺点:
数据库容量受到物理内存的限制,不能用作海量数据的高性能读写
适合的场景主要局限在较小数据量的高性能操作和运算上

4 Redis与Memcached的区别

区别
数据结构:Redis 支持 5 种数据结构;Memcached 只支持字符串
性能对比:单核小数据量存储 Redis 比 Memcached 快;大数据存储 Redis 稍逊
持久化:Redis 支持持久化;Memecached 数据都在内存之中
线程模型:Redis 使用单线程模型,基于非阻塞的 IO 多路复用机制,无线程切换;Memecached 使用多线程模型,一个 master 线程,多个 worker 线程
灾难恢复:Redis数据丢失后可以通过 aof 恢复;Memecached 挂掉后数据不可恢复
集群模式:Redis 原生支持cluster模式;Memcached 没有原生的集群模式

5 Redis使用单线程为什么性能好?

为什么?
避免了线程切换的资源消耗
单线程不存在资源共享与竞争,不用考虑锁的问题
基于内存的,内存的读写速度非常快
使用非阻塞的 IO 多路复用机制
数据存储进行了压缩优化
使用了高性能数据结构,如 Hash、跳表等

6 Redis各数据类型最大容量是多少?

容量?
Strings:一个 String 类型的 value 最大可以存储512M
Lists:元素个数最多为 2^32-1 个,即 4294967295 个
Sets:元素个数最多为 2^32-1 个,即 4294967295 个
Hashes:键值对个数最多为 2^32-1 个,即 4294967295 个
Sorted sets类型:同 Sets

7 Redis持久化机制有哪些?

7.1、 持久化机制

Redis 提供两种持久化机制: RDB 和 AOF

RDB Redis DataBase:
指用数据集快照的方式半持久化模式,记录 redis 数据库的所有键值对,在某个时间点将数据写入一个临时文件,持久化结束后,用这个临时文件替换上次持久化的文件,可恢复数据
优点:
只有一个文件 dump.rdb,恢复操作简单,容灾性好
性能较高,fork 子进程进行写操作,主进程继续处理命令
大数据集比 AOF 的恢复效率高
缺点:
数据安全性低,RDB 是每间隔一段时间进行持久化,若期间 redis 发生故障,可能会发生数据丢失

AOF Append-only file
指所有的命令行记录以 redis 命令请求协议的格式完全持久化存储,保存为 aof 文件
优点:
数据安全,aof 持久化可以配置 appendfsync 属性为 always,记录每个命令操作到 aof 文件中一次;通过 append 模式写文件,即使中途服务器宕机,也可以通过 redis-check-aof 工具解决数据一致性问题
AOF 机制的 rewrite 模式,AOF 文件没被 rewrite 之前可以进行处理,如删除文件中的 flushall 命令
缺点:
AOF 的持久化文件比 RDB 大,恢复速度慢

7.2、Redis AOF 简介

基于Redis的AOF持久化及数据恢复
AOF持久化配置
AOF持久化默认是关闭的;默认打开的是RDB的持久化。
生产环境里面AOF都是要打开的
在这里插入图片描述
打开AOF持久化机制之后,redis每次接收到一条写命令,就会写入日志文件中:先写入os cache的,然后每隔一定时间再fsync一下;
而且即使AOF和RDB都开启了,redis重启的时候,也是优先通过AOF进行数据恢复的,因为aof数据比较完整。

AOF的fsync策略有三种可以选择:
每次写入一条数据就执行一次fsync;
每隔一秒执行一次fsync;
一种是不主动执行fsync。

always: 每写入一条数据立即写日志fsync到磁盘上去,性能非常非常差,吞吐量很低;
everysec: 每秒将os cache中的数据fsync到磁盘,性能很高,QPS还是可以上万的;
no: 仅负责将数据写入os cache,os根据自己的策略将数据刷入磁盘。

mysql和redis对比(QPS):
mysql内存策略:大量磁盘,QPS到一两千;
redis基于内存: 磁盘持久化,QPS到多少上万。

AOF持久化数据恢复
修改配置:打开AOF的开关
appendonly yes
重启
redis-cli SHUTDOWN
./redis_6379 start
写入一些数据,观察AOF文件中的日志内容
root@VM-0-10-ubuntu:/etc/init.d# redis-cli 127.0.0.1:6379> set myhello aaaOK
ls /var/redis/6379/
appendonly.aof dump.rdb

root@VM-0-10-ubuntu:/etc/init.d# cat /var/redis/6379/appendonly.aof 2
$6SELECT
$10
3
$3
set
$7
myhello
$3
aaa

在appendonly.aof文件中,可以看到刚写的日志。其实是先写入os cache的,然后1秒后才fsync到磁盘中。
-kill -9杀掉redis进程,重新启动redis进程
root@VM-0-10-ubuntu:/etc/init.d# ps -ef|grep redis
root 10302 1 0 18:34 ? 00:00:00 /usr/local/bin/redis-server 127.0.0.1:6379
root 11164 8229 0 18:40 pts/0 00:00:00 grep --color=auto redis
root@VM-0-10-ubuntu:/etc/init.d# kill -9 10302root@VM-0-10-ubuntu:/etc/init.d# ./redis_6379 start/var/run/redis_6379.pid exists, process is already running or crashedroot@VM-0-10-ubuntu:/etc/init.d# rm -rf /var/run/redis_6379.pidroot@VM-0-10-ubuntu:/etc/init.d# ./redis_6379 startroot@VM-0-10-ubuntu:/etc/init.d# redis-cli127.0.0.1:6379> get myhello"aaa"127.0.0.1:6379> get k1(nil)

发现数据被恢复了,但是之前保存在RDB里的数据没有了。
这也说明了redis启动的时候,直接从appendonly.aof中加载所有的日志来恢复数据。

7.3、rdb切换到aof 安全保留数据

问题
redis默认持久化配置rdb,但是如果贸然切换配置到aof方式,重启会导致数据丢失
如果数据不重要,都是缓存数据则没什么,如果是重要临时数据,不能丢失的情况,则需要特殊处理,保证数据不丢失
根本原因
rdb方式默认将数据持久化存储到dump.rdb文件下
aof方式默认将数据写操作记录到appendonly.aof文件下
如果同时开启2种方式,重启会默认加载aof方式
redis默认只开启rdb
综上,如果你是默认rdb方式,然后贸然切换到aof,重启后会读取aof文件,但是这个时候aof文件是空的,则会导致redis被清空

原理:在redis控制台动态配置打开 aof方式, bigsavewrite 命令后,重启,自动记录了当前所有记录到 aof文件,再修改redis文件配置打开 aof方式,启动redis时会自动加载之前安全退出保存的 aof数据

7.4、AOF rewrite

redis中的数据其实有限的,很多数据可能会自动过期。
AOF会自动在后台每隔一定时间做rewrite操作, 确保AOF日志文件不会过大,保持跟redis内存数据量一致。目前redis会自动进行rewrite操作。
通过在redis.conf中配置rewrite策略:
auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
比如说上一次AOF rewrite 是100mb,然后就会接着100mb继续写AOF的日志,如果发现增长的比例,超过了之前的100% 也就是200mb,就可能会去触发一次rewrite;
但是此时还要去跟min-size,64mb去比较,200mb > 64mb,才会去触发rewrite。
fork子进程,基于当前内存中的数据,往一个新的临时的AOF文件中写入日志;
redis主进程在接收到新的写操作之后,在内存中写入日志,同时也继续写入旧的AOF文件
子进程写完新的日志文件之后,redis主进程将内存中的新日志再次追加到新的AOF文件中
用新的日志文件替换掉旧的日志文件

7.5、AOF破损文件的修复

如果redis在append数据到AOF文件时,机器宕机会导致AOF文件损坏。如将appendonly.aof删掉最后一行来模拟宕机:
在这里插入图片描述用redis-check-aof --fix命令来修复AOF文件

在这里插入图片描述

7.6、AOF和RDB同时工作

  1. 如果RDB执行snapshotting,那么redis就不会再去执行AOF rewrite。反之,如果redis在执行AOF rewrite,那么也不会执行RDB snapshotting;
  2. 如果RDB执行snapshotting,此时用户也在执行BGREWRITEAOF命令,那么只有等RDB快照生成之后,才会执行AOF rewrite;
  3. 如果同时拥有RDB snapshot文件和AOF日志文件,那么redis重启的时候会优先使用AOF进行恢复,因为其日志更完整。

总结
同时有rdb的dump和aof的appendonly,优先使用AOF进行恢复,rdb的数据不会恢复到内存中
模拟aof破损,然后通过命令fix,破损的数据会被删除,数据恢复完全依赖于磁盘持久化,如果rdb和aof上都没有数据,数据就无法恢复了。

8 Redis使用过程中的注意事项?

主库压力很大,可以考虑读写分离
Master 最好不要做持久化工作,如 RDB 内存快照和 AOF 日志文件。(Master 写内存快照,save 命令调度 rdbSave 函数,会阻塞主线程,文件较大时会间断性暂停服务;AOF 文件过大会影响 Master 重启的恢复速度)
如果数据比较重要,使用 AOF 方式备份数据,设置合理的备份频率
保证主从复制的速度和网络连接的稳定性,主从机器最好在同一内网
官方推荐,使用 sentinel 集群配合多个主从节点集群,解决单点故障问题实现高可用

9 Redis(设计与实现):

RDB持久化之RDB文件的创建与载入(SAVE命令、BGSAVE命令、rdbSave函数、rdbLoad函数)
数据库状态
Redis是一个键值对数据库服务器,服务器中通常包含着任意个非空数据库,而每个非空数据库中又可以包含任意个键值对,为了方便起见,我们将服务器中的非空数据库以及它们的键值对统称为数据库状态

9.1、RDB持久化介绍

因为Redis是内存数据库,它将自己的数据库状态储存在内存里面,所以如果不想办法将储存在内存中的数据库状态保存到磁盘里面,那么一旦服务器进程退出,服务器中的数据库状态也会消失不见
为了解决这个问题,Redis提供了RDB持久化功能,这个功能可以将Redis在内存中的数据库状态保存到磁盘里面,避免数据意外丢失
RDB持久化既可以手动执行,也可以根据服务器配置选项定期执行,该功能可以将某个时间点上的数据库状态保存到一个RDB文件中,如下图所示:
在这里插入图片描述
RDB持久化功能所生成的RDB文件是一个经过压缩的二进制文件,通过该文件可以还原生成RDB文件时的数据库状态,如下图所示:
在这里插入图片描述

9.2、RDB文件的创建(SAVE、BGSAVE)

有两个Redis命令可以用于生成RDB文件,一个是SAVE,另一个是BGSAVE
SAVE:SAVE命令会阻塞Redis服务器进程,直到RDB文件创建完毕为止,在服务器进程阻塞期间,服务器不能处理任何命令请求
BGSAVE: 和SAVE命令直接阻塞服务器进程的做法不同,BGSAVE命令会派生出一个子进程,然后由子进程负责创建RDB文件,服务器进程(父进程)继续处理命令请求
SAVE命令执行时服务器的状态
当SAVE命令执行时,Redis服务器会被阻塞,所以当SAVE命令正在执行时,客户端发送的所有命令请求都会被拒绝
只有在服务器执行完SAVE命令、重新开始接受命令请求之后,客户端发送的命令才会被处理
BGSAVE命令执行时服务器的状态 因为BGSAVE命令的保存工作是由子进程执行的,所以在子进程创建RDB文件的过程中,服务器仍然可以继续处理客户端的命令请求
,但在BGSAVE命令执行期间,服务器处理SAVE、BGSAVE、BGREWRITEAOF三个命令的方式会和平时有所不同
特点如下:
①在BGSAVE命令执行期间,客户端发送的SAVE命令会被服务器拒绝,服务器禁止SAVE命令和BGSAVE命令同时执行是为了避免父进程(服务器进程)和子进程同时执行两个
rdbSave调用,防止产生竞争条件
②在BGSAVE命令执行期间,客户端发送的BGSAVE命令会被服务器拒绝,因为同 时执行两个BGSAVE命令也会产生竞争条件
BGREWRITEAOF和BGSAVE两个命令不能同时执行:
如果BGSAVE命令正在执行,那么客户端发送的BGREWRITEAOF命令会被延迟到
BGSAVE命令执行完毕之后执行如果BGREWRITEAOF命令正在执行,那么客户端发送的BGSAVE命令会被服务器拒 绝。
因为BGREWRITEAOF和BGSAVE两个命令的实际工作都由子进程执行,所以这两个命令在操作方面并没有什么冲突的地方,不能同时执行它们只是一个性能方面的考虑——并发出两个子进程,并且这两个子进程都同时执行大量的磁盘写入操作,这怎么想都不会是一个好主意
rdbSave函数
创建RDB文件的实际工作由rdb.c/rdbSave函数完成,SAVE命令和BGSAVE命令会以不同的方式调用这个函数。以下伪代码可以明显地看出这两个命令之间的区别:

在这里插入图片描述

9.3、RDB文件的载入

RDB文件的载入工作是在服务器启动时自动执行的,所以Redis并没有专门用于载入RDB文件的命令,只要Redis服务器在启动时检测到RDB文件存在,它就会自动载入RDB文件

RDB文件载入时服务器的状态
服务器在载入RDB文件期间,会一直处于阻塞状态,直到载入工作完成为止
以下是Redis服务器启动时打印的日志记录,其中第二条日志DB loaded from disk:…就是服务器在成功载入RDB文件之后打印的:
在这里插入图片描述

AOF持久化对RDB持久化的影响:

如果服务器开启了AOF持久化功能,那么服务器会优先使用AOF文件来还原数据库状 态,那么就不会使用RDB文件了
只有在AOF持久化功能处于关闭状态时,服务器才会使用RDB文件来还原数据库状态
服务器判断该用AOF文件文件还是RDB文件来还原数据库状态的流程如下图所示:

在这里插入图片描述

载入RDB文件的实际工作由rdb.c/rdbLoad函数完成,这个函数和rdbSave函数之间的关系可以如下图所示:

在这里插入图片描述

10 Redis过期键的删除策略有哪些?

定时删除:在设置键的过期时间的同时,创建一个定时器,达到过期时间,执行键的删除操作
惰性删除:不主动删除过期键,从键空间中获取键时,都检查取得的键是否过期,过期则删除;没过期则返回
定期删除:每隔一段时间对数据库进行一次检查,删除里面的过期键。删除多少过期键、检查多少个数据库,由算法决定。

11 说说Redis的回收策略

volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中,淘汰最近最少使用的数据
volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中,淘汰最早会过期的数据
volatile-random:从已设置过期时间的数据集(server.db[i].expires)中,随机淘汰数据
allkeys-lru:从数据集(server.db[i].dict)中,淘汰最近最少使用的数据
allkeys-random:从数据集(server.db[i].dict)中,随机淘汰数据
noenviction:Redis 的默认策略,不回收数据,当达到最大内存时,新增数据返回 error
注:
volatile 是对已设置过期时间的数据集淘汰数据
allkeys 是从全部数据集淘汰数据
lru 是 Least Recently Used 的缩写,即最近最少使用
ttl 指令可以获取键到期的剩余时间(秒),这里的意思是淘汰最早会过期的数据

12 为什么Redis所有数据放到内存中?

Redis 为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘,所以 Redis 具有高速读写和数据持久化的特征
如果程序直接与磁盘交互,磁盘 IO 速度会严重影响 Redis 的性能
内存的硬件成本降低,使得 Redis 更受欢迎

13 说说Redis的同步机制?

2.8 版以前
Redis 通过同步(sync)和指令传播(command propagate)两个操作完成同步
同步(sync):将从节点的数据库状态更新至与主节点的数据库状态一致
从节点向主节点发送 SYNC 指令
收到 SYNC 指令,主节点执行 BGSAVE 指令,在后台生成一个 RDB 文件,并使用一个缓冲区记录从现在开始执行的所有写指令
主节点 BGSAVE 指令执行后,会将生成的 RDB 文件发送给从节点
从节点接收、载入 RDB 文件,将数据库状态更新至主节点执行 BGSAVE 指令时的数据库状态
从节点加载完 RDB 文件,通知主节点将记录在缓冲区里面的所有写指令发送给从节点,从节点执行这些写指令,将数据库状态更新至主节点当前数据库状态

指令传播(command propagate):主节点数据被修改,会主动向从节点发送执行的写指令,从节点执行之后,两个节点数据状态又保持一致

为了解决主从节点断线复制低效的问题(SYNC过程中生成、传输、载入 RDB 文件耗费大量 CPU、内存、磁盘 IO 资源),2.8 版开始新增 PSYNC 指令。
PSYNC 具有两种模式
完整重同步(full resynchronization),与SYNC过程基本一致
部分重同步(partial resynchronization),借助复制偏移量、复制积压缓冲区、服务器运行 ID ,完成主从节点断开连接后,从节点重连主节点后,条件允许,主节点将连接断开期间执行的写指令发送给从节点,从节点接收并执行写指令,将数据库更新至主节点当前状态

14 Pipeline有什么好处?

多个指令之间没有依赖关系,可以使用 pipeline 一次性执行多个指令,减少 IO,缩减时间。

15 说说Redis集群?

Redis Sentinel,哨兵机制,解决主从节点高可用的问题。监控主从服务器运行状态;检测到 master 宕机时,会发布消息进行选举,自动将 slave 提升为 master
Redis Cluster,分布式解决方案,解决单点故障与扩展性的问题。如在单个 redis 发生故障或内存不足时,使用 Cluster 进行分片存储

16 说说遇到的Redis集群方案不可用的情况?

集群主库半数宕机(根据 failover 原理,fail 掉一个主需要一半以上主都投票通过才可以)
集群某一节点的主从全数宕机

17 接触过哪些Redis客户端?

Redisson
Jedis
Lettuce

18 Redisson、Jedis、Lettuce各有什么优缺点?

Redisson
优点:
实现了分布式特性和可扩展的 Java 数据结构,适合分布式开发
API 线程安全
基于 Netty 框架的事件驱动的通信,可异步调用
缺点:
API 更抽象,学习使用成本高

Jedis
优点:
提供了比较全面的 Redis 操作特性的 API
API 基本与 Redis 的指令一一对应,使用简单易理解
缺点:
同步阻塞 IO
不支持异步
线程不安全

Lettuce
优点:
线程安全
基于 Netty 框架的事件驱动的通信,可异步调用
适用于分布式缓存
缺点:
API 更抽象,学习使用成本高

19 Redis如何设置密码?

命令行设置密码
运行cmd切换到redis根目录,先启动服务端
redis-server.exe

另开一个cmd切换到redis根目录,启动客户端
redis-cli.exe -h 127.0.0.1 -p 6379
客户端使用config get requirepass命令查看密码

config get requirepass
“requirepass”
“” //默认空

客户端使用config set requirepass yourpassword命令设置密码
config set requirepass 123456 >OK
一旦设置密码,必须先验证通过密码,否则所有操作不可用
config get requirepass
(error)NOAUTH Authentication required
使用auth password验证密码
auth 123456
OK
config get requirepass
“requirepass”
“123456”

也可以退出重新登录
redis-cli.exe -h 127.0.0.1 -p 6379 -a 123456
命令行设置的密码在服务重启后失效,所以一般不使用这种方式。

配置文件设置密码
在redis根目录下找到redis.windows.conf配置文件,搜索requirepass,找到注释密码行,添加密码如下:
requirepass foobared
requirepass tenny //注意,行前不能有空格
重启服务后,客户端重新登录后发现
config get requirepass
“requirepass”
“”
密码还是空?
网上查询后的办法:创建redis-server.exe 的快捷方式, 右键快捷方式属性,在目标后面增加redis.windows.conf, 这里就是关键,你虽然修改了.conf文件,但是exe却没有使用这个conf,所以我们需要手动指定一下exe按照修改后的conf运行,就OK了。
所以,这里我再一次重启redis服务(指定配置文件)
redis-server.exe redis.windows.conf
客户端再重新登录,OK了。
redis-cli.exe -h 127.0.0.1 -p 6379 -a 123456
config get requirepass
1)“requirepass”
2)“123456”

20 Redis哈希槽

Redis 集群没有使用一致性 hash,而是引入了哈希槽的概念。
Redis 集群有 16384 个哈希槽,每个 key 通过 CRC16 算法计算的结果,对 16384 取模后放到对应的编号在 0-16383 之间的哈希槽,集群的每个节点负责一部分哈希槽

21 Redis 集群会有写操作丢失吗?

过期 key 被清理
最大内存不足,导致 Redis 自动清理部分 key 以节省空间
主库故障后自动重启,从库自动同步
单独的主备方案,网络不稳定触发哨兵的自动切换主从节点,切换期间会有数据丢失

22 Redis集群之间是如何复制?

2.8 版以前,Redis 通过同步(sync)和指令传播(command propagate)两个操作完成同步
同步(sync):将从节点的数据库状态更新至与主节点的数据库状态一致
指令传播(command propagate):主节点数据被修改,会主动向从节点发送执行的写指令,从节点执行之后,两个节点数据状态又保持一致

2.8 版开始新增 PSYNC 指令,PSYNC 具有两种模式:
完整重同步(full resynchronization),与 SYNC 过程基本一致
部分重同步(partial resynchronization),借助复制偏移量、复制积压缓冲区、服务器运行 ID ,完成主从节点断开连接后,从节点重连主节点后,条件允许,主节点将连接断开期间执行的写指令发送给从节点,从节点接收并执行写指令,将数据库更新至主节点当前状态

23 Redis集群支持最大节点数是多少?

16384 个。原因如下:
Redis 集群有 16384 个哈希槽,每个 key 通过 CRC16 算法计算的结果,对 16384 取模后放到对应的编号在 0-16383 之间的哈希槽,集群的每个节点负责一部分哈希槽

24 Redis如何选择数据库?

SELECT index
切换到指定的数据库,数据库索引号 index 用数字值指定,0 作为起始索引值
连接建立后,如果不 select,默认对 db 0 操作

25 怎么测试Redis的连通性?

使用 ping 指令,如:
redis-cli -h host -p port -a password
127.0.0.1:6379> ping
PONG
127.0.0.1:6379>

Java 代码对 Redis 连通性测试,可以使用 Redis 客户端类库包里的 api 发送 ping 指令
//连接redis
Jedis jedis=new Jedis(“127.0.0.1”,6379);//查看服务器是否运行,打出 pong 表示OK
System.out.println(“ping redis:” + jedis.ping());

26 说一说你对Redis的事务的理解?

redis事务的特性:
事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
没有隔离级别,事务提交前结果不可见,事务提交执行后可见
不保证原子性,Redis 同一个事务中有命令执行失败,其后的命令仍然会被执行,不会回滚

27 Redis如何设置永久有效?

PERSIST key
持久化 key 和 value
Redis 在默认情况下会采用 noeviction 回收策略,即不淘汰任何键值对,当内存己满时只能提供读操作,不能提供写操作

28 Redis事务相关的命令有哪些?

multi,标记一个事务块的开始,返回 ok
exec,执行所有事务块内,事务块内所有命令执行的先后顺序的返回值,操作被,返回空值 nil
discard,取消事务,放弃执行事务块内的所有命令,返回 ok
watch,监视 key 在事务执行之前是否被其他指令改动,若已修改则事务内的指令取消执行,返回 ok
unwatch,取消 watch 命令对 key 的监视,返回 ok

29 Redis如何设置过期时间?

redis.expire(key, expiration)
低于 2.1.3 版,只能对 key 设置一次过期时间
2.1.3 版开始,可以更新 key 的过期时间
set、del 命令会移除 key 的过期时间设置
过期处理策略:
定时删除:在设置 key 的过期时间时,创建一个定时器,当过期时间到的时候立马执行删除操作
惰性删除:不会在 key 过期时立马删除,而是当外部指令获取这个 key 的时候才会主动删除
定期删除:设置一个时间间隔,每个时间段都会检测是否有过期键,如果有执行删除操作

30 Redis如何做内存优化?

缩减键值对象:满足业务要求下 key 越短越好;value 值进行适当压缩
共享对象池:即 Redis 内部维护[0-9999]的整数对象池,开发中在满足需求的前提下,尽量使用整数对象以节省内存
尽可能使用散列表(hashes)
编码优化,控制编码类型
控制 key 的数量

31 Redis的内存用完了会发生什么?

这个跟 Redis 的内存回收策略有关。
Redis 的默认回收策略是 noenviction,当内存用完之后,写数据会报错。
Redis 的其他内存回收策略含义:
volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中,淘汰最近最少使用的数据
volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中,淘汰最早会过期的数据
volatile-random:从已设置过期时间的数据集(server.db[i].expires)中,随机淘汰数据
allkeys-lru:从数据集(server.db[i].dict)中,淘汰最近最少使用的数据
allkeys-random:从数据集(server.db[i].dict)中,随机淘汰数据

32 单个Redis实例最多能存放多少个key?

官方给出,理论值是 2 的 32 次方个
实际使用中单个 Redis 实例最小储存 2.5 亿个 key

33 List、Set、Sorted Set最多能存放多少元素?

官方 FAQ 上说明,理论上 List、Set、Sorted Set 可以放 2 的 32 次方个元素

34 如何保证Redis中存的都是热点数据?

Redis存储在内存中的数据升到配置大小时,就进行数据淘汰
使用 allkeys-lru 策略,从数据集(server.db[i].dict)中挑选最近最少使用的数据优先淘汰,即可满足保存热点数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吹老师个人app编程教学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值