Java面试——Redis

2024-07-13 1405阅读

优质博文:IT-BLOG-CN

一、Redis 为什么那么快

【1】完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中。

【2】数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的。

【3】采用单线程,避免不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗。

【4】使用多路IO复用模型,非阻塞IO。利用epoll可以同时监察多个流的 IO事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 IO事件时,就从阻塞态中唤醒,epoll就轮询哪些真正发生了事件的流,并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。多路指的是多个网络连接,“复用”指的是复用同一个线程。

二、Redis 与 Memcached 的区别

Redis 与 Memcached 的相似之处:

【1】Redis 和 Memcached 都是内存数据存储系统,都用作内存中的键值数据存储;

【2】Redis 和 Memcached 都属于NoSQL系列数据管理解决方案,两者都基于键值数据模型;

【3】Redis 和 Memcached 都将所有数据保存在 RAM 中,这当然使它们作为缓存层非常有用;

Redis 与 Memcached 的区别:

【1】Redis 和 Memcached都是将数据存放在内存中,都是内存数据库。不过Memcached 还可用于缓存其他东西,例如图片、视频等等;

【2】Redis 不仅仅支持简单的 k/v 类型的数据,同时还提供 list,set,zset,hash等数据结构的存储;

【3】虚拟内存 Redis 当物理内存用完时,可以将一些很久没用到的 value 交换到磁盘;

【4】过期策略 Memcached 在 set 时就指定,例如:set key1 0 0,即永不过期。Redis 可以通过例如 expire 设定,例如:expire name 10;

【5】存储数据安全性 Memcached 挂掉后,数据就没了。Redis可以定期保存到磁盘(持久化);

【6】灾难恢复 Memcached 挂掉后,数据不可恢复。Redis 数据丢失后可以通过 rdb 或 aof恢复;

【7】Memcached不支持复制,Redis支持主从复制,允许从属 Redis服务器成为主服务器的精确副本;来自任何 Redis服务器的数据都可以复制到任意数量的从属服务器;

【8】应用场景不一样:Redis 除了作为 NoSQL数据库使用外,还能用做消息队列、数据堆栈和数据缓存等;Memcached适合于缓存SQL语句、数据集、用户临时性数据、延迟查询数据和 session等;

【9】Memcached 的读写速度高于 Redis,因为Redis 是单线程的,而 Memcached 是多线程的;

【10】Memcached 单个 key-value大小有限,一个 value最大只支持1MB,而 Redis最大支持512MB;

三、Redis 有哪几种数据淘汰策略

Redis 检查内存使用情况,如果已使用的内存大于 maxmemory的值则开始根据用户配置的不同淘汰策略来淘汰内存(key),从而换取一定的内存。maxmemory=0 的时候表示我们对 Redis的内存使用没有限制。淘汰策略如下:

【1】noeviction: 返回错误。当内存使用达到阈值的时候,所有引起申请内存的命令会报错。

【2】allkeys-lru: 在主键空间中,优先移除最近未使用的key。

【3】volatile-lru: 在设置了过期时间的键空间中,优先移除最近未使用的key。

【4】allkeys-random: 回收随机的键使得新添加的数据有空间存放。

【5】volatile-random: 回收随机的键使得新添加的数据有空间存放,但仅限于在过期集合的键。

【6】volatile-ttl: 回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间存放。

四、Redis 支持哪几种数据类型

Reids 支持7中数据结构,最常用的是 String、List、Set、Sorted Set、Hash 其内部结构及使用参照博客链接;

五、Redis 集群方案什么情况下会导致整个集群不可用

假如有A,B,C三个节点的集群,在没有主从复制模型的情况下,其中一个节点挂掉,那么整个集群就会缺少某个范围的槽而不可用。所以从节点很重要。

六、Redis 哈希槽的概念

Redis 集群没有使用一致性 hash,而是引入了哈希槽的概念,Redis 集群有 16384个哈希槽,每个 key通过 CRC16校验后对16384 取模来决定放置哪个槽,集群的每个节点负责一部分 hash槽。

七、Redis 集群会有写操作丢失吗

Redis 并不能保证数据的强一致性,这意味这在实际生产中集群在特定的条件下可能会丢失写操作。

八、Redis 集群之间是如何复制的

【博客连接】:优质链接

九、Redis 集群如何选择数据库

Redis 集群目前无法做数据库选择,默认在0数据库。

十、Redis 中的管道(Pipeline)有什么用

客户端将请求传送给服务器,服务器处理完毕后,再将响应回复给客户端。这要花费一个网络数据包来回的时间。如果连续执行多条指令,那么就会花费多个网络数据包来回的时间(多条指令,一条一条发送给服务器)。

管道的本质是: 将多个连续的读写操作合并后总共花费一次网络来回。就好像连续的写操作合并了,连续的读操作也合并了一样。服务器根本没有任何区别对待,还是走着收着一条消息、执行一条消息、回复一条消息的正常流程。Redis 自带了管道的压力测试工具 redis-benchmark,使用此工具可以进行管道测试:

redis-benchmark -t set -q
SET: 54938.05 requests per second
# -P 表示管道内并行的请求数量。  当P=2 时,QPS 达到 9W/s
# 当P达到一定值时,会下降,因为单线程CPU消耗已经达到 100%,所以无法上升
redis-benchmark -t set -P 2 -q
SET: 93238.15 requests per second

将多个命令发送到服务器,而不用等待回复,最后在一个步骤中读取该答复。这就是管道(pipelining),是一种几十年来广泛使用的技术。例如许多 POP3协议已经实现支持这个功能,大大加快了从服务器下载新邮件的过程。

十一、怎么理解 Redis事务

事务是一个单独的隔离操作: 事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。但是如果某个事务执行失败,也不会进行回滚的。

十二、Redis key 的过期时间和永久有效分别怎么设置

EXPIRE 和 PERSIST命令。

十三、Redis 如何做内存优化

尽可能使用散列表(hashes),散列表(是说散列表里面存储的数少)使用的内存非常小,所以你应该尽可能的将你的数据模型抽象到一个散列表里面。比如你的 web系统中有一个用户对象,不要为这个用户的名称,姓氏,邮箱,密码设置单独的key,而是应该把这个用户的所有信息存储到一张散列表里面。

十四、Redis 回收进程如何工作的

【1】一个客户端运行了新的命令,添加了新的数据。

【2】Redis 检查内存使用情况,如果大于 maxmemory的限制, 则根据设定好的策略进行回收。

【3】一个新的命令被执行,等等。

【4】所以我们不断地穿越内存限制的边界,通过不断达到边界然后不断地回收回到边界以下。

如果一个命令的结果导致大量内存被使用(例如很大的集合的交集保存到一个新的键),不用多久内存限制就会被这个内存使用量超越。

十五、Redis 回收使用的是什么算法

Redis 中采用两种算法进行内存回收,引用计数算法以及LRU算法(最近最久未使用算法)。

十六、Redis 如何做大量数据插入

Redis2.6 开始 redis-cli 支持一种新的被称之为 pipe mode 的新模式用于执行大量数据插入工作。

十七、为什么要做 Redis分区

分区可以让 Redis管理更大的内存,Redis 将可以使用所有机器的内存。如果没有分区,你最多只能使用一台机器的内存。分区使 Redis的计算能力通过简单地增加计算机得到成倍提升,Redis 的网络带宽也会随着计算机和网卡的增加而成倍增长。

十八、你知道有哪些 Redis分区实现方案

【1】客户端分区: 就是在客户端就已经决定数据会被存储到哪个 Redis节点或者从哪个 Redis节点读取。大多数客户端已经实现了客户端分区。

【2】代理分区: 意味着客户端将请求发送给代理,然后代理决定去哪个节点写数据或者读数据。代理根据分区规则决定请求哪些 Redis实例,然后根据 Redis的响应结果返回给客户端。Redis 和 memcached 的一种代理实现就是 Twemproxy。

【3】查询路由(Query routing) : 意思是客户端随机地请求任意一个 Redis实例,然后由 Redis将请求转发给正确的 Redis节点。Redis Cluster 实现了一种混合形式的查询路由,但并不是直接将请求从一个 Redis节点转发到另一个 Redis节点,而是在客户端的帮助下直接 Redirected到正确的 Redis节点。

十九、Redis 持久化数据和缓存怎么做扩容

【1】如果 Redis被当做缓存使用,使用一致性哈希实现动态扩容缩容。

【2】如果 Redis被当做一个持久化存储使用,必须使用固定的 keys-to-nodes 映射关系,节点的数量一旦确定不能变化。否则的话(即 Redis节点需要动态变化的情况),必须使用可以在运行时进行数据再平衡的一套系统,而当前只有Redis集群可以做到这样。

二十、分布式 Redis是前期做还是后期规模上来了再做好?为什么?

既然 Redis是如此的轻量(单实例只使用1M内存),为防止以后的扩容,最好的办法就是一开始就启动较多实例。即便你只有一台服务器,你也可以一开始就让 Redis以分布式的方式运行,使用分区,在同一台服务器上启动多个实例。

一开始就多设置几个Redis实例,例如 32或者 64个实例,对大多数用户来说这操作起来可能比较麻烦,但是从长久来看做这点牺牲是值得的。

这样的话,当你的数据不断增长,需要更多的 Redis服务器时,你需要做的就是仅仅将 Redis实例从一台服务迁移到另外一台服务器而已(而不用考虑重新分区的问题)。一旦你添加了另一台服务器,你需要将你一半的 Redis实例从第一台机器迁移到第二台机器。

二十一、Twemproxy 是什么

Twemproxy 是 Twitter 维护的(缓存)代理系统,代理 Memcached 的 ASCII协议和 Redis协议。它是单线程程序,使用C语言编写,运行起来非常快。它是采用 Apache 2.0 license的开源软件。 Twemproxy 支持自动分区,如果其代理的其中一个 Redis节点不可用时,会自动将该节点排除(这将改变原来的 keys-instances的映射关系,所以你应该仅在把 Redis当缓存时使用Twemproxy)。 Twemproxy 本身不存在单点问题,因为你可以启动多个 Twemproxy实例,然后让你的客户端去连接任意一个Twemproxy 实例。 Twemproxy 是 Redis客户端和服务器端的一个中间层,由它来处理分区功能应该不算复杂,并且应该算比较可靠的。

二十二、Redis 与其他 key-value存储有什么不同

【1】Redis 有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis 的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。

【2】Redis 运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,应为数据量不能大于硬件内存。在内存数据库方面的另一个优点是, 相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。 同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。

二十三、Redis 的内存占用情况怎么样

举个例子: 100万个键值对(键是0到999999值是字符串“hello world”)在我的 32位的Mac笔记本上用了100MB。同样的数据放到一个 key里只需要16MB, 这是因为键值有一个很大的开销。 在 Memcached上执行也是类似的结果,但是相对 Redis的开销要小一点点,因为 Redis会记录类型信息引用计数等等。当然,大键值对时两者的比例要好很多。64位的系统比32位的需要更多的内存开销,尤其是键值对都较小时,这是因为 64位的系统里指针占用了8个字节。 但是,当然,64位系统支持更大的内存,所以为了运行大型的 Redis服务器或多或少的需要使用 64位的系统。

二十四、哪些办法可以降低 Redis的内存使用情况

如果你使用的是 32位的 Redis实例,可以好好利用 Hash、list、sorted set、set等集合类型数据,因为通常情况下很多小的 Key-Value 可以用更紧凑的方式存放到一起。

二十五、查看 Redis使用情况及状态信息用什么命令

Redis 可以使用以下命令查看使用情况及状态信息:

【1】INFO 命令: 该命令可以查看 Redis 的各项统计信息,包括内存使用情况、连接数、命中率等等。

具体使用步骤:

1、在 Redis 客户端中输入 INFO 命令。

2、程序会返回一份详细的统计信息,包括服务器的基本信息、客户端信息、内存信息、持久化信息等等。

127.0.0.1:6379> INFO

【2】MONITOR 命令: 该命令可以监视 Redis 服务器正在处理的命令,并以实时日志的形式输出。

具体使用步骤:

1、在 Redis 客户端中输入 MONITOR 命令。

2、程序会开始输出 Redis 服务器正在处理的命令及其执行结果。

127.0.0.1:6379> MONITOR

【3】CLIENT LIST 命令: 该命令可以查看当前连接到 Redis 服务器的客户端信息。

具体使用步骤:

1、在 Redis 客户端中输入 CLIENT LIST 命令。

2、程序会返回连接到Redis服务器的所有客户端的详细信息,包括客户端 IP 地址、端口号、连接时间等等。

127.0.0.1:6379> CLIENT LIST

【4】DBSIZE 命令: 该命令可以查看当前 Redis 数据库中的键值对数量。

具体使用步骤:

1、在 Redis 客户端中输入 DBSIZE 命令。

2、程序会返回当前数据库中键值对的数量。

127.0.0.1:6379> DBSIZE

二十六、Redis 的内存用完了会发生什么

如果达到设置的上限,Redis 的写命令会返回错误信息(但是读命令还可以正常返回。)或者你可以将 Redis当缓存来使用配置淘汰机制,当 Redis达到内存上限时会冲刷掉旧的内容。

二十七、Redis 是单线程的,如何提高多核CPU的利用率

可以在同一个服务器部署多个 Redis的实例,并把他们当作不同的服务器来使用,在某些时候,无论如何一个服务器是不够的, 所以,如果你想使用多个 CPU,你可以考虑一下分片(shard)。

二十八、一个 Redis实例最多能存放多少的keys?List、Set、Sorted Set他们最多能存放多少元素

【1】理论上 Redis可以处理多达 232的 keys,并且在实际中进行了测试,每个实例至少存放了 2亿5千万的 keys。我们正在测试一些较大的值。

【2】任何 list、set、和 sorted set都可以放 232个元素。换句话说,Redis 的存储极限是系统中的可用内存值。

二十九、Redis 常见性能问题和解决方案

【1】Master 最好不要做任何持久化工作,如 RDB内存快照和 AOF日志文件;

【2】如果数据比较重要,某个 Slave 开启 AOF备份数据,策略设置为每秒同步一次;

【3】为了主从复制的速度和连接的稳定性,Master 和 Slave最好在同一个局域网内;

【4】尽量避免在压力很大的主库上增加从库;

【5】主从复制不要用图状结构,用单向链表结构更为稳定,即:Master

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]