目录
14. Pipeline有什么好处为什么要用pipeline?
一、pipeline出现的背景:redis客户端执行一条命令分4个过程:
17. Redis支持的Java客户端都有哪些?官方推荐用哪个?
29. Redis key的过期时间和永久有效分别怎么设置?
34. 一个Redis实例最多能存放多少的keys? List、SetSorted Set他们最多能存多少?
35. MySQL里有2000w数据,redis中只存20w的数据,如何保证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数据库的所有键值对,在某个时间点将数据写入一个临时文件持久化结束后,用这个临时文件替换上次持久化的文件达到数据恢复;
优点:
- 只有一个文件 dump.rdb,方便持久化;
- 容灾性好,一个文件可以保存到安全的磁盘;
- 性能最大化,fork子进程来完成写操作,让主进程继续处理命令,所以是IO最大化。使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了Redis的高性能;
- 相对于数据集大时,比 AOF 的启动效率更高;
缺点:
- 数据安全性低;
- RDB 是间隔一段时间进行持久化,如果在持久化时Redis发生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候;
AOF
AOF持久化(即Append Only File持久化),是将Redis执行的每次写命令记录到单独的日志文件中,当重启Redis会重新将持久化的日志中文件恢复数据。当两种方式同时开启时数据恢复Redis会优先选择AOF恢复;
优点:
- 数据安全,AOF持久化可以配置 appendfsync 属性,有always属性,每进行一次命令操作就记录到AOF文件中一次;
- 通过append模式写文件,即使中途服务器宕机,可以通过 redis-check-aof 工具解决数据一致性问题;
- AOF机制的rewrite模式。AOF文件没被 rewrite 之前(文件过大时会对命令 进行合并重写),可以删除其中的某些命令(比如误操作的 flushall);
缺点:
- AOF文件比RDB文件大,且恢复速度慢;
- 数据集大的时候,比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过期健的删除策略
- 定时删除:在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时,立即执行对键的删除操作
- 惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键
- 定期删除: 每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。至于要删除多个过期键,以及要检查多少个数据库,则由算法决定
11. Redis的回收策略 (淘汰策略) ?
- volatile-lru,针对设置了过期时间的key,使用lru算法进行淘汰。
- allkeys-lru,针对所有key使用lru算法进行淘汰。
- volatile-lfu,针对设置了过期时间的key,使用lfu算法进行淘汰。
- allkeys-lfu,针对所有key使用lfu算法进行淘汰。
- volatile-random,从所有设置了过期时间的key中使用随机淘汰的方式进行淘汰。
- allkeys-random,针对所有的key使用随机淘汰机制进行淘汰。
- volatile-ttl,删除生存时间最近的一个键。
- 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集群之同是如何复制的?
- 从数据库向主数据库发送sync命令。
- 主数据库接收同步命令后,会保存快照,创建一个rdb。
- 当主数据库执行完保持快照后,会向从数据库发送RDB文件,从而从数据库会接收并载入该文件。
- 主数据库将缓冲区的所有写命令发给从服务器执行。
- 以上处理完之后,主数据库每执行一个写命令都会将执行的写命令发送给从数据库。
24. Redis集群最大节点个数是多少?
16384 个
25. Redis集群如何选择数据库?
通常是用select命令的,但是在集群模式下是不起作用的,集群客户端是不支持多数据库db的,只能使用数据库0;
26. 怎么测试Redis的连通
- 确保redis服务器正在运行,可以使用netstat和ping等实用程序来检查redis服务器是否正在监听。
- 使用redis命令行客户端尝试连接redis服务器,确保已正确设置,主机名和端口号,以及正确的密码。
- 以编程语言方式测试连接redis数据库,连接redis数据库的方式有很多,比如在Java中使用Jedis库,在Ruby中使用Redis Gem,在PHP中使用phpredis等。
- 使用redis实用程序ping和info检查服务器是否成功连接,如果存在连接问题,则会显示报错信息。
- 一旦连接成功,使用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中的数据都是热点?
- 保留热点数据:对于保留 Redis 热点数据来说,我们可以使用 Redis 的内存淘汰策略来实现,可以使用allkeys-lru淘汰策略,该淘汰策略是从 Redis 的数据中挑选最近最少使用的数据删除,这样频繁被访问的数据就可以保留下来了。
- 保证 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分布式锁么,它是什么回事?
分布式锁,即分布式系统中的锁。在单体应用中我们通过锁解决的是控制共享资源访问的问题,而分布式锁,就是解决了分布式系统中控制共享资源访问的问题。与单体应用不同的是,分布式系统中竞争共享资源的最小粒度从线程升级成了进程。
- 在分布式系统环境下,一个方法在同一时间只能被一个机器的一个线程执行
- 高可用的获取锁与释放锁
- 高性能的获取锁与释放锁
- 具备可重入特性(可理解为重新进入,由多于一个任务并发使用,而不必担心数据错误)
- 具备锁失效机制,即自动解锁,防止死锁
- 具备非阻塞锁特性,即没有获取到锁将直接返回获取锁失败