对线面试官:Redis 夺命连环 38 问,你能抗住多少?

目录

1. 什么是Redis?

2. Redis的数据类型?

3. 使用Redis有哪些好处?

4. Redis相比Memcached 有哪些优势?

5. Memcache与Redis的区别都有哪些?

6. Redis是单进程单线程的?

7. 一个字符率类型的值能储最大容量是多少?

8. Redis的持久化机制是什么?各自的优缺点?

RDB

AOF

9. Redis性能优化方案有哪些

1. 基础性能优化方案

2.数据结构和 Key 的设计优化

3.Redis 调优经验和相关工具介绍

10. redis过期健的删除策略

11. Redis的回收策略 (淘汰策略) ?

12. 为什么Redis需要把所有数据放到内存中?

13. Redis的同步机制有哪些?

14. Pipeline有什么好处为什么要用pipeline?

一、pipeline出现的背景:redis客户端执行一条命令分4个过程:

15. Redis集群的原理是什么?

16. Redis集群方案什么情况下会导致整个集群不可用?

17. Redis支持的Java客户端都有哪些?官方推荐用哪个?

18. Jedis与Redisson对比有什么优缺点?

        19. Redis如何设置密码及验证密码?

20. 说说Redis哈希槽的概念?

21. Redis集群的主从复制模型是怎样的?

22. Redis集群会有写操作丢失吗? 为什么?

23. Redis集群之同是如何复制的?

24. Redis集群最大节点个数是多少?

25. Redis集群如何选择数据库?

26. 怎么测试Redis的连通

27. 怎么理解Redis事务?

28. Redis事务相关的命令有哪几个?

29. Redis key的过期时间和永久有效分别怎么设置?

30. Redis如何做内存优化

31. Redis回收进程如何工作的?

32. 都有哪些办法可以降低Redis的内存使用情况呢?

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

34. 一个Redis实例最多能存放多少的keys? List、SetSorted Set他们最多能存多少?

35. MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点?

36. Redis最适合的场景?

37. 使用过Redis做异步队列么,你是怎么用的?


1. 什么是Redis?

Redis(Remote Dictionary Server)是一个开源的内存数据存储系统,常被称为数据结构服务器。它以键值对的形式存储数据,适用于各种不同场景,从缓存数据库、消息中间件到实时分析等


2. Redis的数据类型?

String、List、Set、Sorted Set、hashes


3. 使用Redis有哪些好处?

  • 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
  • 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
  • 原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作合并后的原子性执行。(事务)
  • 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。 


4. Redis相比Memcached 有哪些优势?

  • memcached 所有的值均是简单的字符串,redis 作为其替代者,支持更为丰富的数据类型
  • redis 的速度比 memcached 快很多 redis 的速度比 memcached 快很多
  • redis 可以持久化其数据 redis 可以持久化其数据


5. Memcache与Redis的区别都有哪些?

1.存储方式不同

memcache 把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小;
redis有部分存在硬盘上,这样能保证数据的持久性,支持数据的持久化(笔者注:有快照和AOF日志日志两种持久化方式,在实际应用的时候,要特别注意配置文件快照参数,要不就很有可能服务器频繁满载做dump)。

2.数据支持类型不同

redis在数据支持上要比memcache多的多。

3.使用底层模型不同

新版本的redis直接自己构建了VM机制,因为一般的系统调用系统函数的话,会浪费一定是假去移动和请求。

4.运行环境不同

redis目前只支持LINUX上去行,从而省去了对于其他系统的支持,这样的话可以更好地把经理用于本系统环境上的优化,虽然后微软有一个小组为其写了补丁。但是没有放到主干上。


6. Redis是单进程单线程的?

官方解释如下:因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。

这里需要注意一个问题,我们所说的Redis的单线程,不是指Redis程序真的只会有一个线程。这里所说的单线程,指的是Redis处理客户端发来的数据操作请求(增删改查),只会使用一个线程去执行。但是实际上,Redis在执行其他操作的时候,可能会开启多个进程或线程,比如说持久化。Redis执行BGSAVE指令,进行快照持久化时,就会fork出一个子进程,然后子进程去创建快照,完成持久化操作。


7. 一个字符率类型的值能储最大容量是多少?

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


8. Redis的持久化机制是什么?各自的优缺点?

Redis持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失;

Redis提供两种持久化机制RDB(默认)和AOF机制;

RDB

RDB(Redis DataBase缩写快照)是Redis默认的持久化方式。按照一定的时间将内存的数据以快照的形式保存到硬盘中,对应产生的数据文件为dump.rdb。通过配置文件中的save参数来定义快照的周期;记录Redis数据库的所有键值对,在某个时间点将数据写入一个临时文件持久化结束后,用这个临时文件替换上次持久化的文件达到数据恢复;

优点:

  1. 只有一个文件 dump.rdb,方便持久化;
  2. 容灾性好,一个文件可以保存到安全的磁盘;
  3. 性能最大化,fork子进程来完成写操作,让主进程继续处理命令,所以是IO最大化。使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了Redis的高性能;
  4. 相对于数据集大时,比 AOF 的启动效率更高;

缺点:

  1. 数据安全性低;
  2. RDB 是间隔一段时间进行持久化,如果在持久化时Redis发生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候; 

AOF

      AOF持久化(即Append Only File持久化),是将Redis执行的每次写命令记录到单独的日志文件中,当重启Redis会重新将持久化的日志中文件恢复数据。当两种方式同时开启时数据恢复Redis会优先选择AOF恢复

优点:

  1. 数据安全,AOF持久化可以配置 appendfsync 属性,有always属性,每进行一次命令操作就记录到AOF文件中一次;
  2. 通过append模式写文件,即使中途服务器宕机,可以通过 redis-check-aof 工具解决数据一致性问题;
  3. AOF机制的rewrite模式。AOF文件没被 rewrite 之前(文件过大时会对命令 进行合并重写),可以删除其中的某些命令(比如误操作的 flushall);

缺点:

  1. AOF文件比RDB文件大,且恢复速度慢;
  2. 数据集大的时候,比RDB启动效率低; 

9. Redis性能优化方案有哪些

1. 基础性能优化方案

  • 设置合适的内存大小:根据实际需要去配置内存的大小,且建议内存预留 30%左右给操作系统,防止 Redis 使用内存过多影响系统性能或发生意外情况。
  • 开启数据持久化:开启 Redis 的数据持久化可以避免因意外原因造成数据丢失问题。
  • 配置适当的并发数: 根据实际负载,设置 Redis 监听的套接字并发数。
  • 避免使用 SELECT 命令:最好为每个应用程序提供单独的 Redis 实例,不要使用 Redis 的 SELECT 命令切换数据库。
  • 避免使用大量的命令管道:会占用大量内存,应使用 emit 等低水平 API,这些更直接地与套接字进行交互。
  • 关闭命令调试:Redis 是以响应时间为优先考量的。

2.数据结构和 Key 的设计优化

  • 尽可能少地使用 Redis 通配符和扫描功能:HVALS 和 SCAN 遍历整个数据库以寻找所有键值,性能比较差,并且削弱网络安全能力。
  • 清理数据:在数据过期或不需要时,通过定期清理过期的或冗余的数据,以保证 Redis 运行的性能。
  • 锁或队列:需要合理使用其数据结构。

3.Redis 调优经验和相关工具介绍

  • redis-cli 使用:使用 redis-cli 可以方便地进行数据操作、监控缓存命中率,以及模拟测试数据等。
  • slow log 命令使用:慢查询日志可以输出所有时长大于指定毫秒的 Redis 命令,方便进行性能问题的定位。
  • redis-benchmark 命令使用:该命令用于进行性能和压力测试,一般常用于 Cluster 测试。 

10. redis过期健的删除策略

  1. 定时删除:在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时,立即执行对键的删除操作
  2. 惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键
  3. 定期删除: 每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。至于要删除多个过期键,以及要检查多少个数据库,则由算法决定

11. Redis的回收策略 (淘汰策略) ?

  1. volatile-lru,针对设置了过期时间的key,使用lru算法进行淘汰。
  2. allkeys-lru,针对所有key使用lru算法进行淘汰。
  3. volatile-lfu,针对设置了过期时间的key,使用lfu算法进行淘汰。
  4. allkeys-lfu,针对所有key使用lfu算法进行淘汰。
  5. volatile-random,从所有设置了过期时间的key中使用随机淘汰的方式进行淘汰。
  6. allkeys-random,针对所有的key使用随机淘汰机制进行淘汰。
  7. volatile-ttl,删除生存时间最近的一个键。
  8. noeviction(默认),不删除键,值返回错误。 

主要是4种算法,针对不同的key,形成的策略,算法:

  • lru 最近很少的使用的key(根据时间,最不常用的淘汰)
  • lfu 最近很少的使用的key (根据计数器,用的次数最少的key淘汰)
  • random 随机淘汰
  • ttl 快要过期的先淘汰

key :

  • volatile 有过期的时间的那些key
  • allkeys 所有的key 

12. 为什么Redis需要把所有数据放到内存中?

因为Redis的定位就是一个内存数据库。
内存的读取数据是最快的,如果放到硬盘,磁盘IO的速度势必会严重影响Redis的性能,那就和一般的关系型数据库相比没什么优势可言,而且随着现在内存硬件成本的降低,内存已经不是问题,性能才是关键,现在硬盘只是成为了一种持久化方案而已。


13. Redis的同步机制有哪些?

Redis提供了多种数据同步机制,包括主从复制、哨兵、集群等。
主从复制:
主从复制是Redis最基本的数据同步机制,它可以将一个Redis实例的数据同步到多个从Redis实例中。主Redis实例向从Redis实例发送复制命令,并将自己的数据同步给从Redis实例。从Redis实例只能读取数据,不能修改数据,它们的主要作用是为主Redis实例提供读取负载均衡和数据备份。
哨兵:
哨兵是Redis的高可用方案之一,它可以监控Redis实例的状态,当主Redis实例出现故障时,哨兵会自动将一个从Redis实例提升为新的主Redis实例,保证系统的可用性。
集群:
集群是Redis的分布式方案之一,它可以将Redis的数据分布在多个节点上,提高系统的并发性和扩展性。Redis集群采用哈希槽分片的方式将数据分配到不同的节点上,每个节点负责维护一部分数据的读写操作。


14. Pipeline有什么好处为什么要用pipeline?

一、pipeline出现的背景:
redis客户端执行一条命令分4个过程:

  发送命令-〉命令排队-〉命令执行-〉返回结果

1.使用 Pipeline 执行多个 Redis 命令,通常比逐条执行要快。这是因为 Pipeline 可以将多个命令一次性发送给 Redis 服务器,并一次性接收多个命令的返回结果,从而减少了网络传输和等待时间,提高了 Redis 的性能和响应速度。

2.客户端和服务端之间的网络延迟越大,Pipeline 的优势越明显。这是因为在网络延迟较大的情况下,每个命令执行完成后需要等待很长时间才能执行下一个命令。而使用 Pipeline,客户端可以将多个命令一次性发送给 Redis 服务器,并一次性接收多个命令的返回结果,从而减少了等待时间,提高了 Redis 的性能和可靠性。

Pipeline 并不是一个新的技术或机制,而是一种已经被广泛使用的技术。在其他技术中,例如数据库、消息队列和分布式系统等领域,也有类似的机制用于减少网络延迟。


15. Redis集群的原理是什么?

1.Redis集群是一个由多个节点组成的分布式服务集群,它具有复制、高可用和分片特性

2.Redis的集群没有中心节点,并且带有复制和故障转移特性,这可用避免单个节点成为性能瓶颈,或者因为某个节点下线而导致整个集群下线

3.集群中的主节点负责处理槽(储存数据),而从节点则是主节点的复制品

4.Redis集群将整个数据库分为16384个槽,数据库中的每个键都属于16384个槽中的其中一个

5.集群中的每个主节点都可以负责0个至16384个槽,当16384个槽都有节点在负责时,集群进入上线状态,可以执行客户端发送的数据命令

6.主节点只会执行和自己负责的槽有关的命令,当节点接收到不属于自己处理的槽的命令时,它将会处理指定槽的节点的地址返回给客户端,而客户端会向正确的节点重新发送

7.如果需要完整地分片、复制和高可用特性,并且要避免使用代理带来的性能瓶颈和资源消耗,那么可以选择使用Redis集群;

如果只需要一部分特性(比如只需要分片,但不需要复制和高可用等),那么单独选用twemproxy、Redis的复制和Redis Sentinel中的一个或多个


16. Redis集群方案什么情况下会导致整个集群不可用?

有A,B,C三个节点的集群,在没有复制模型的情况下,如果节点B失败了,那么整个集群就会因为缺少5501-11000这个范围的槽而不可用。


17. Redis支持的Java客户端都有哪些?官方推荐用哪个?

Redisson、Jedis、lettuce 等等,官方推荐使用 Redisson。

Redission 是高级的分布式协调Redis客户端,可以帮助用户在分布式环境实现一些java对象


18. Jedis与Redisson对比有什么优缺点?

Jedis是Redis的java实现客户端,其API提供了比较全面的Redis命令的支持;Redisson实现了分布式和可扩展的Java数据结构,和Jedis相比,功能较为简单,不支持字符串操作,不支持排序、事务‘管道、分区等Redis特性。Redisson的宗旨是促进使用者对Redis的关注分离,从而让使用者能够将精力更集中地放在处理业务逻辑上。

        
19. Redis如何设置密码及验证密码?

一、查看现有的 Redis 密码:
config get requirepass 
二、设置 Redis 密码:
设置密码:
config set requirepass 123456
查看结果
config get requirepass 
三、Redis 客户端使用密码验证
如果 Redis Server 设置了密码的话,使用 redis-cli 连接时有两种密码验证方式:
1、连接时添加密码参数
reids-cli -h hostname -p port -a password
2、或者不输入密码连接后使用 auth 命令来验证
keys *
(error) NOAUTH Authentication required.
auth 123456
OK 


20. 说说Redis哈希槽的概念?

Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点。


21. Redis集群的主从复制模型是怎样的?

主从复制模型中,有多个redis节点。其中,有且仅有一个为主节点Master。从节点Slave可以有多个。只要网络连接正常,Master会一直将自己的数据更新同步给Slaves,保持主从同步。

  • 主节点Master可读、可写.
  • 从节点Slave只读。(read-only)

22. Redis集群会有写操作丢失吗? 为什么?

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

23. Redis集群之同是如何复制的?

  1. 从数据库向主数据库发送sync命令。
  2. 主数据库接收同步命令后,会保存快照,创建一个rdb。
  3. 当主数据库执行完保持快照后,会向从数据库发送RDB文件,从而从数据库会接收并载入该文件。
  4. 主数据库将缓冲区的所有写命令发给从服务器执行。
  5. 以上处理完之后,主数据库每执行一个写命令都会将执行的写命令发送给从数据库。

24. Redis集群最大节点个数是多少?

16384 个


25. Redis集群如何选择数据库?

通常是用select命令的,但是在集群模式下是不起作用的,集群客户端是不支持多数据库db的,只能使用数据库0;


26. 怎么测试Redis的连通

  1. 确保redis服务器正在运行,可以使用netstat和ping等实用程序来检查redis服务器是否正在监听。
  2.  使用redis命令行客户端尝试连接redis服务器,确保已正确设置,主机名和端口号,以及正确的密码。
  3.  以编程语言方式测试连接redis数据库,连接redis数据库的方式有很多,比如在Java中使用Jedis库,在Ruby中使用Redis Gem,在PHP中使用phpredis等。
  4.  使用redis实用程序ping和info检查服务器是否成功连接,如果存在连接问题,则会显示报错信息。
  5.  一旦连接成功,使用redis服务器上的set、get、del、expire等命令,正确的设置、存储和删除key,确保连接是正常的。


27. 怎么理解Redis事务?

Redis 事务是一组 Redis 命令的集合,这些 Redis 命令会被批量地发送到 Redis 服务器执行。Redis 事务严格保证了其中的一系列操作是以原子方式执行的,即 Redis 事务中的所有操作都能够被看作一个整体,要么全部执行成功,要么全部失败,从而确保了数据库的一致性。

Redis 事务的运作方式与传统关系型数据库的事务有所不同。在传统关系型数据库中,事务分为三个阶段:开始事务、执行事务、提交或回滚事务。而在 Redis 中,事务是在 multi 命令发出后,到 exec 命令执行时这个时间窗口内的所有命令都被视为一个事务。事务中的命令并不会立即被执行,而是被缓存到内存中,等到整个事务提交时再一次性执行。由此,Redis 事务的执行过程都是在一瞬间完成的,并没有显式的提交或回滚事务的过程。


28. Redis事务相关的命令有哪几个?

MULTI 、 EXEC 、 DISCARD 和 WATCH 是 Redis 事务相关的命令。

  • MULTI :开启事务,redis会将后续的命令逐个放入队列中,然后使用EXEC命令来原子化执行这个命令系列。
  • EXEC:执行事务中的所有操作命令。
  • DISCARD:取消事务,放弃执行事务块中的所有命令。
  • WATCH:监视一个或多个key,如果事务在执行前,这个key(或多个key)被其他命令修改,则事务被中断,不会执行事务中的任何命令。
  • UNWATCH:取消WATCH对所有key的监视。


29. Redis key的过期时间和永久有效分别怎么设置?

过期时间:

使用EXPIRE命令。EXPIRE命令允许用户设置Key的过期时间,时间单位为秒

永久有效: 

        1.设置过期时间为极大值:  EXPIRE key 2147483647

        2. 不设置过期时间: SET key value


30. Redis如何做内存优化

1. 使用压缩:Redis可以对存储在内存中的数据进行压缩,以减少内存占用。可以通过配置文件中的"redis.conf"文件中的"maxmemory-policy"参数来启用压缩。
2. 使用数据结构:Redis提供了多种数据结构,如字符串、列表、集合、有序集合等。根据实际需求选择合适的数据结构,以减少内存占用。
3. 使用哈希:当存储的值比较大时,可以将其存储为哈希结构,以减少内存占用。
4. 使用过期时间:对于不再需要的数据,可以设置过期时间,以便在一定时间后自动删除,减少内存占用。
5. 使用持久化:Redis支持将数据持久化到磁盘中,以便在重启时可以重新加载数据。可以选择合适的持久化方式,如RDB快照或AOF日志,以减少内存占用。
6. 使用分片:可以将数据分片存储在多个Redis实例中,以减少单个实例的内存占用。
7. 限制最大内存使用:可以通过配置文件中的"maxmemory"参数来限制Redis实例使用的最大内存,当达到该限制时,Redis将根据指定的策略删除一些数据,以保持内存占用在限制范围内。
8. 内存淘汰策略:可以通过配置文件中的"maxmemory-policy"参数来指定内存淘汰策略,如LRU、LFU等,以保持内存占用在限制范围内。
9. 使用Redis Cluster:当需要存储大量数据时,可以使用Redis Cluster将数据分布在多个节点上,以减少单个节点的内存占用。
10. 使用Redis Sentinel:Redis Sentinel可以监控Redis实例的状态,并在主节点故障时自动进行故障转移,以保证数据的可用性和一致性。使用Redis Sentinel可以将数据分布在多个节点上,以减少单个节点的内存占用。


31. Redis回收进程如何工作的?

Redis 内存回收进程的基本原理是周期性地扫描存储数据库中所有的键,并一步步对所有键进行检测:
(1)、判断键是否已经过期
(2)、是否使用了LRU算法,以及它最后一次被访问的时间
(3)、是否被删除但仍然留在内存中(当多个客户端同时访问同一个 key VALUE 时,如果没有正确处理引用计数,则会发生这种情况)
首先检查是否有需要根据过期时间自动删除的键(expired key)。每次检查只对一小部分键进行处理。如果有符合条件的 key,内存回收线程就把它们标记为过期,在之后立即回收并释放为其分配的内存。
然后,Redis 检查那些没有被过期,但仍然占用大量内存的键。如果所选键比快满了,Redis 就选择其中最早要删除的几个键,并释放它们所占用的空间。
除了定期回收外,Redis 还支持手动释放 key VALUE 占用内存的方法:通过向 Redis 发送一个 flushall 命令和可使用“shutdown”断开连接的方式来清除所有数据


32. 都有哪些办法可以降低Redis的内存使用情况呢?

1、清除过期key
一般来说,Redis中的key都有一个过期时间(TTL),当一个key到达了过期时间后,Redis会自动把它删除掉。如果切实情况下发现过期key很少被清理,可以通过手动扫描和清理的方式解决该问题。可以通过手动执行DEL <key>命令或者设置自动定时清理已标记为过期的键值对。
2、开启压缩机制
开启Redis的压缩机制是减少内存占用的一种有效方式。 开启后,数据将被压缩后存储,Redis就可以使用更小的空间来存储相同数量的数据。但是,在压缩数据时使用CPU势必会带来一定的系统负荷。因此,在开启前应该进行全面评估。
3、启用LRU算法
大规模使用设置 Redis 的 maxmemory 属性最好开启 LRU 超出时删除策略,以确保 Redis 服务器不会无限添加项目并从而导致内存耗尽。Redis可以根据“最近最少的访问时间”(Least Recently Used)算法,删除过时的、很久没有使用过的键值对。同时,redis还提供上下文相关的LRU算法(Comte-Tournier),不同于简单的链表实现。
4、对键值进行优化
Redis目前支持五种数据类型:字符串,列表,哈希表,集合和有序集合。在使用这些类型时,我们可以采取以下措施来优化内存:
字符串(String)类型:使用整数或布尔值代替字符串,可以显著降低内存占用。
列表(List)类型:对于含有大量重复元素的列表,可以使用Redis List压缩来降低其内存消耗。
哈希表(Hash)类型:如果key-value 对数量很少,这种类型的空间效率非常低。尽量避免在哈希表里使用一些"tiny keys"。
集合(Set)类型:使用基数估计法(BloomFilter)等技术来节约空间。
有序集合(Sorted Set)类型: 针对只存储分数(score)但是成员(member)本身很小的功能需求,可以通过配置Redis启用ziplist和small ziplist。
5、分割数据库
将数据拆分多个数据库,各自独立运行,从而有效地分散每个数据库的负载,减少数据库内存压力。在使用多个数据库时,必须小心控制它们的大小并注意细节处理,以免耗尽可用资源。
6、使用Redis集群
当单台 Redis 服务器无法满足业务需求或者需要提高死活性和升级能力时,可以考虑将其扩展到Redis集群中。通过搭建分布式集群,即使其中一台主机发生崩溃或停机,整个系统也可以保证数据的完整性和可用性。此外,集群模式下每个节点暴露出的单独的内存限制,还可以更好地控制内存占用情况。
7、随时了解Redis内存使用情况
Redis提供命令、日志等多种方法来随时查看内存使用情况,并进行相关调整。理解Redis内存特性是优化Redis内存使用的前提条件,同时还应该综合考虑当前硬件配置、业务需求及实际情况等因素。
总之,由于Redis完全基于内存操作,因此它的内存越大,对服务器的要求就越高。为了避免性能问题和故障,我们必须采取一系列措施来降低Redis的内存使用率。在实际运行过程中,根据业务特点、数据类型和目标等因素,可以采取上述措施或他们的组合来进一步优化Redis的内存使用效率。


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

写操作失败:当 Redis 内存用尽时,无法再接受新的写入操作。此时,任何尝试写入数据的操作(如 SET、INCRBY、LPUSH 等)都会失败,并返回错误消息。

读操作仍可继续:尽管 Redis 的内存用完,但仍然可以执行读取操作(如 GET、HGET、LINDEX 等)。这是因为 Redis 的数据仍然保存在磁盘上的持久化文件中,而不是完全依赖于内存。但是,需要注意的是,读操作的性能可能会受到影响,因为 Redis 需要频繁地从磁盘加载数据到内存中。

内存淘汰策略:Redis 提供了多种内存淘汰策略来处理内存耗尽的情况。当内存用完时,根据配置的淘汰策略,Redis 会尝试清理一些数据以腾出空间给新的写入操作。常见的淘汰策略包括:

LRU(Least Recently Used):选择最近最少使用的键进行淘汰。
LFU(Least Frequently Used):选择最不经常使用的键进行淘汰。
Random(随机):随机选择键进行淘汰。
通过配置合适的内存淘汰策略,可以在内存耗尽时保持系统的正常运行,并根据业务需求决定哪些数据是可以牺牲的。

Out-of-Memory 错误:在某些情况下,Redis 可能无法执行内存淘汰策略来腾出空间。例如,当 Redis 没有配置内存淘汰策略、配置的最大内存限制为 0、或者其他配置问题导致无法执行淘汰策略时,Redis 可能会抛出 Out-of-Memory 错误并终止服务。


34. 一个Redis实例最多能存放多少的keys? List、SetSorted Set他们最多能存多少?

一个Redis实例最多能存放理论上2的32次方个keys(40亿),并且在实际中进行了测试,每个实例至少存放了2亿5千万的keys
任何_hash、_list、set、和sorted set都可以放2的32次方个keys(40亿)个元素。
所以总共是4000000000×4000000000=1600 0000 0000 0000 0000个元素,换句话说,Redis的存储极限是系统中的可用内存值。 


35. MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点?

  1. 保留热点数据:对于保留 Redis 热点数据来说,我们可以使用 Redis 的内存淘汰策略来实现,可以使用allkeys-lru淘汰策略,该淘汰策略是从 Redis 的数据中挑选最近最少使用的数据删除,这样频繁被访问的数据就可以保留下来了。
  2. 保证 Redis 只存20w的数据:1个中文占2个字节,假如1条数据有100个中文,则1条数据占200字节,20w数据 乘以 200字节 等于 4000 字节(大概等于38M);所以要保证能存20w数据,Redis 需要38M的内存。


36. Redis最适合的场景?

1、缓存
缓存现在几乎是所有中大型网站都在用的必杀技,合理的利用缓存不仅能够提升网站访问速度,还能大大降低数据库的压力。Redis提供了键过期功能,也提供了灵活的键淘汰策略,所以,现在Redis用在缓存的场合非常多。
2、排行榜
很多网站都有排行榜应用的,如京东的月度销量榜单、商品按时间的上新排行榜等。Redis提供的有序集合数据类构能实现各种复杂的排行榜应用。
3、计数器
什么是计数器,如电商网站商品的浏览量、视频网站视频的播放数等。为了保证数据实时效,每次浏览都得给+1,并发量高时如果每次都请求数据库操作无疑是种挑战和压力。Redis提供的incr命令来实现计数器功能,内存操作,性能非常好,非常适用于这些计数场景。
4、分布式会话
集群模式下,在应用不多的情况下一般使用容器自带的session复制功能就能满足,当应用增多相对复杂的系统中,一般都会搭建以Redis等内存数据库为中心的session服务,session不再由容器管理,而是由session服务及内存数据库管理。
5、分布式锁
在很多互联网公司中都使用了分布式技术,分布式技术带来的技术挑战是对同一个资源的并发访问,如全局ID、减库存、秒杀等场景,并发量不大的场景可以使用数据库的悲观锁、乐观锁来实现,但在并发量高的场合中,利用数据库锁来控制资源的并发访问是不太理想的,大大影响了数据库的性能。可以利用Redis的setnx功能来编写分布式的锁,如果设置返回1说明获取锁成功,否则获取锁失败,实际应用中要考虑的细节要更多。
6、 社交网络
点赞、踩、关注/被关注、共同好友等是社交网站的基本功能,社交网站的访问量通常来说比较大,而且传统的关系数据库类型不适合存储这种类型的数据,Redis提供的哈希、集合等数据结构能很方便的的实现这些功能。
7、最新列表
Redis列表结构,LPUSH可以在列表头部插入一个内容ID作为关键字,LTRIM可用来限制列表的数量,这样列表永远为N个ID,无需查询最新的列表,直接根据ID去到对应的内容页即可。
8、消息系统
消息队列是大型网站必用中间件,如ActiveMQ、RabbitMQ、Kafka等流行的消息队列中间件,主要用于业务解耦、流量削峰及异步处理实时性低的业务。Redis提供了发布/订阅及阻塞队列功能,能实现一个简单的消息队列系统。另外,这个不能和专业的消息中间件相比。


37. 使用过Redis做异步队列么,你是怎么用的?

一般使用list结构作为队列,rpush生产消息,lpop消费消息。当lpop没有消息的时候,要适当sleep一会再重试。
如果对方追问可不可以不用sleep呢?
list还有个指令叫blpop,在没有消息的时候,它会阻塞住直到消息到来。如果对方追问能不能生产一次消费多次呢?使用pub/sub主题订阅者模式,可以实现1:N的消息队列。
如果对方追问pub/sub有什么缺点?
在消费者下线的情况下,生产的消息会丢失,得使用专业的消息队列如RabbitMQ等。
如果对方追问redis如何实现延时队列?
使用sortedset,拿时间戳作为score,消息内容作为key调用zadd来生产消息,消费者用zrangebyscore指令获取N秒之前的数据轮询进行处理。


38. 使用过Redis分布式锁么,它是什么回事?

分布式锁,即分布式系统中的锁。在单体应用中我们通过锁解决的是控制共享资源访问的问题,而分布式锁,就是解决了分布式系统中控制共享资源访问的问题。与单体应用不同的是,分布式系统中竞争共享资源的最小粒度从线程升级成了进程。

  • 在分布式系统环境下,一个方法在同一时间只能被一个机器的一个线程执行
  • 高可用的获取锁与释放锁
  • 高性能的获取锁与释放锁
  • 具备可重入特性(可理解为重新进入,由多于一个任务并发使用,而不必担心数据错误)
  • 具备锁失效机制,即自动解锁,防止死锁
  • 具备非阻塞锁特性,即没有获取到锁将直接返回获取锁失败 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值