Redis详解

时间:2024-05-31 19:52:25

文章目录

    • Redis详解
    • Redis优缺点
    • Redis 的 Java 客户端库
    • Redis是AP的还是CP的
    • redis为什么不用做数据库,只用做缓存
    • redis和memcached区别
    • Redis key 的过期时间和永久有效分别怎么设置
    • Redis 回收进程如何工作的
    • 为什么要做 Redis 分区
    • 分布式 Redis 是前期做还是后期规模上来了再做好?为什么
    • Twemproxy 是什么
    • Redis 中的管道有什么用

Redis详解

Redis(Remote Dictionary Server)是一个开源的内存数据存储系统,它可以用作数据库、缓存和消息中间件。Redis以其高性能、支持丰富的数据结构以及灵活的特性而闻名。以下是关于Redis的一些详细信息:

  1. 数据结构:Redis支持多种数据结构,包括字符串、哈希、列表、集合、有序集合等。这使得Redis不仅仅可以用作简单的键值存储,还可以处理更复杂的数据结构和相关操作。
  2. 持久化:Redis提供了两种持久化选项,分别是快照(snapshotting)和追加式文件(append-only file, AOF)。这些机制可以让Redis在重启后恢复数据,从而保证数据的持久性。
  3. 主从复制:Redis支持主从复制,可以将一个Redis服务器的数据复制到多个从服务器上。这使得Redis能够实现读写分离、负载均衡和故障恢复。
  4. 发布与订阅:Redis提供了发布与订阅机制,允许客户端订阅特定的频道,并在该频道上接收消息。这使得Redis可以用作消息中间件。
  5. 事务:Redis支持事务,可以将一系列命令打包成一个原子操作来执行,保证这些命令要么全部成功,要么全部失败。
  6. Lua脚本:Redis支持通过Lua脚本进行复杂的操作,客户端可以将Lua脚本发送到服务器执行。
  7. 性能:由于Redis数据存储在内存中,因此具有非常高的读写性能。此外,Redis还支持集群模式,可以横向扩展以应对大规模的数据和流量。
    总的来说,Redis是一个功能丰富、高性能的内存数据存储系统,它适用于多种场景,包括缓存、会话存储、排行榜、实时数据分析等。如果您有任何关于Redis的具体问题,欢迎随时向我提问。

Redis优缺点

优点
qps:10w/s
Redis 是一个基于内存的高性能key-value数据库。
(1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)
(2) 支持丰富数据类型,支持string,list,set,sorted set,hash
(3) 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
(4) 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除

  1. 性能高效。读写性能可以达到10w/s的频率。
  2. 支持数据类型丰富。除了String类型的value,还支持hash,set,sortedset,list等数据类型
  3. 支持主从复制。主机可以将数据同步到从机,可以经行读写分离。
  4. 支持数据持久化。采用AOF和RDB两种方式将数据存储在本地。
    缺点
  5. 数据库容量受到了物理内存的限制,不能用作海量数据的高性能读写,
  6. 内存消耗较大
  7. Redis不支持回滚(Roll Back)

Redis 的 Java 客户端库

以下是一些流行的 Redis 的 Java 客户端库:

  1. Jedis:Jedis 是一个广泛使用的 Redis Java 客户端,提供了丰富的功能和易用的 API,支持连接池、管道等特性,使得与 Redis 服务器进行交互更加方便。
  2. Lettuce:Lettuce 是一个基于 Netty 的高性能 Redis 客户端库,提供了异步、同步以及响应式编程风格的 API,支持 Redis Sentinel 和 Redis Cluster,适用于构建高性能的分布式系统。
  3. Redisson:Redisson 不仅是一个分布式处理框架,也是一个优秀的 Redis Java 客户端库,提供了丰富的分布式对象和服务,可以方便地与 Redis 进行交互。
  4. Spring Data Redis:Spring Data Redis 是 Spring Framework 的一个子项目,提供了对 Redis 的集成支持和封装,通过使用 Spring Data Redis 可以方便地在 Spring 应用中操作 Redis。
  5. RedisTemplate:RedisTemplate 是 Spring Framework 提供的 Redis 客户端模板,通过它可以方便地在 Spring 应用中使用 Redis,提供了丰富的操作方法和功能。
    这些 Redis 的 Java 客户端库都具有不同的特点和优势,开发者可以根据自己的需求选择合适的客户端库来与 Redis 进行交互。无论是 Jedis、Lettuce、Redisson 还是 Spring Data Redis,它们都提供了丰富的功能和易用的 API,可以帮助开发者构建高性能、可靠的 Redis 应用。
    Jedis 与 Redisson 对比有什么优缺点
    Jedis 是 Redis 的 Java 实现的客户端,其 API 提供了比较全面的 Redis 命令的支持;
    Redisson 实现了分布式和可扩展的 Java 数据结构,和 Jedis 相比,功能较为简单,不支持 字符串操作,不支持排序、事务、管道、 分区等 Redis 特性。 Redisson 的宗旨是促进使用者对 Redis 的关注分离,从而让使用者能够将精 力更集中地放在 处理业务逻辑上。

Redis是AP的还是CP的

Redis被认为是一个AP(可用性和分区容忍性)系统,根据CAP定理,分布式系统无法同时保证一致性(Consistency, C)、可用性(Availability, A)和分区容忍性(Partition Tolerance, P)。因此,根据其设计目标和特性,Redis更偏向于强调可用性和分区容忍性,而在某些情况下可能牺牲一定程度的一致性。
具体来说,Redis实现了主从复制机制和哨兵机制(Sentinel),以增强其可用性和分区容忍性。在主从架构中,即使部分节点发生故障,整个系统仍然可以继续提供服务,因为客户端可以通过访问其他可用的节点来获取数据。这使得Redis更倾向于AP模型。
然而,需要注意的是,作为开发者或架构师,在使用Redis时,仍然需要根据具体的业务需求和数据一致性要求来权衡在可用性、一致性和分区容忍性之间的取舍。在某些情况下,可以通过配置Redis的参数,如持久化策略、复制级别等,来调整其在CAP三个要素中的表现。

redis为什么不用做数据库,只用做缓存

Redis本身就是内存数据库,但缺点也很明显

  1. 受限于内存大小
  2. 不能支持ACID里的一些要求,比如:关系型数据、事务要求
    ● 1:数据量,毕竟内存数据库,还是受限于内存的容量,虽然可以redis可以持久化。
    ● 2:数据的结构,是否能够将关系型数据结构都转换为key/value的形式。
    ● 3:查询的效率,对范围查询等,是否能转换为高效的hash索引查询
    如果只用关系数据库,如MySQL,PostgreSQL,它的问题是:
  3. 太慢,一般是10倍量级的降低
  4. 太复杂,管理、开发、硬件成本等加大
    所以,很多时候,我们又将Redis和一些关系型数据库(如MySQL\PostgreSQL)混用,此时,Redis是缓存。我们希望能得到内存数据库和关系型数据库的两个好处。
    但天下没有免费的午餐,用Redis做缓存,带来下面的问题
  5. 系统复杂,开发要面对缓存一致性、缓存击穿、两种数据库类型的编程管理等问题
  6. 成本过高,开发、管理、硬件成本加多了

redis和memcached区别

(1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型
(2) redis的速度比memcached快很多
(3) redis可以持久化其数据
redis 最基本的一个内部原理和特点,就是 redis 实际上是个单线程工作模型,但是 memcached 是早些年各大互联网公司常用的缓存方案,但是现在近几年基本都是 redis,没什么公司用 memcached 了。
redis 支持复杂的数据结构
redis 相比 memcached 来说,拥有更多的数据结构,能支持更丰富的数据操作。如果需要缓存能够支持更复杂的结构和操作, redis 会是不错的选择。
redis 原生支持集群模式
在 redis3.x 版本中,便能支持 cluster 模式,而 memcached 没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据。
性能对比
由于 redis 只使用单核,而 memcached 可以使用多核,所以平均每一个核上 redis 在存储小数据时比 memcached 性能更高。而在 100k 以上的数据中,memcached 性能要高于 redis。虽然 redis 最近也在存储大数据的性能上进行优化,但是比起 memcached,还是稍有逊色。

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

EXPIRE 和 PERSIST 命令。

Redis 回收进程如何工作的

一个客户端运行了新的命令,添加了新的数据。Redis检查内存使用情况,如果大于 maxmemory 的限制, 则根据设定好的策略进行回收。一个新的命令被执行,等等
所以我们不断地穿越内存限制的边界,通过不断达到边界然后不断地回收回到边界以下。如果一个命令的结果导致大量内存被使用(例如很大的集合的交集保存到一个新的键),不用多久内存限制就会被这个内存使用量超越
Redis 回收使用的是什么算法
LRU 算法
Redis 如何做大量数据插入
Redis2.6 开始 Redis-cli 支持一种新的被称之为 pipe mode 的新模式用于执行大量数据插入工作

为什么要做 Redis 分区

分区可以让 Redis 管理更大的内存,Redis 将可以使用所有机器的内存。如果没有分区,你最多只能使用一台机器的内存。分区使 Redis 的计算能力通过简单地增加计算机得到成倍提升,Redis 的网络带宽也会随着计算机和网卡的增加而成倍增长
你知道有哪些 Redis 分区实现方案
客户端分区就是在客户端就已经决定数据会被存储到哪个 Redis 节点或者从哪个 Redis 节点读取。大多数客户端已经实现了客户端分区。代理分区 意味着客户端将请求发送给代理,然后代理决定去哪个节点写数据或者读数据。代理根据分区规则决定请求哪些 Redis 实例,然后根据 Redis 的响应结果返回给客户端。
Redis 和 memcached 的一种代理实现就是 Twemproxy查询路由(Query routing) 的意思是客户端随机地请求任意一个 Redis 实例,然后由 Redis将请求转发给正确的 Redis 节点。Redis Cluster 实现了一种混合形式的查询路由,但并不是直接将请求从一个 Redis 节点转发到另一个 Redis 节点,而是在客户端的帮助下直接redirected 到正确的 Redis 节点
Redis 分区有什么缺点
涉及多个 key 的操作通常不会被支持。例如你不能对两个集合求交集,因为他们可能被存储到不同的 Redis 实例(实际上这种情况也有办法,但是不能直接使用交集指令)
同时操作多个 key,则不能使用 Redis 事务.分区使用的粒度是key,不能使用一个非常长的排序key存储一个数据集(The partitioninggranularity is the key, so it is not possible to shard a dataset with a single huge
key like a very big sorted set).
当使用分区的时候,数据处理会非常复杂,例如为了备份你必须从不同的 Redis 实例和主机同时收集 RDB / AOF 文件。分区时动态扩容或缩容可能非常复杂。Redis 集群在运行时增加或者删除 Redis 节点,能做到最大程度对用户透明地数据再平衡,但其他一些客户端分区或者代理分区方法则不支持这种特性。然而,有一种预分片的技术也可以较好的解决这个问题
Redis 持久化数据和缓存怎么做扩容
如果 Redis 被当做缓存使用,使用一致性哈希实现动态扩容缩容。
如果 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-rb、PRedis 等
Redis 与其他 key-value 存储有什么不同
Redis 有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis 的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象
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 使用情况及状态信息用什么命令
info
Redis 的内存用完了会发生什么
如果达到设置的上限,Redis 的写命令会返回错误信息(但是读命令还可以正常返回。)或者你可以将 Redis 当缓存来使用配置淘汰机制,当 Redis 达到内存上限时会冲刷掉旧的内容
Redis 是单线程的,如何提高多核 CPU 的利用率
可以在同一个服务器部署多个 Redis 的实例,并把他们当作不同的服务器来使用,在某些时候,无论如何一个服务器是不够的,所以,如果你想使用多个 CPU,你可以考虑一下分片(shard)
一个 Redis 实例最多能存放多少的 keys?List、Set
Sorted Set 他们最多能存放多少元素
理论上 Redis 可以处理多达 232 的 keys,并且在实际中进行了测试,每个实例至少存放了 2亿 5 千万的 keys。我们正在测试一些较大的值。任何 list、set、和 sorted set 都可以放 232 个元素。
换句话说,Redis 的存储极限是系统中的可用内存值。

修改配置不重启 Redis 会实时生效吗
针对运行实例,有许多配置选项可以通过 CONFIG SET 命令进行修改,而无需执行任何形式的重启。 从 Redis 2.2 开始,可以从 AOF 切换到 RDB 的快照持久性或其他方式而不需要重启 Redis。检索 ‘CONFIG GET *’ 命令获取更多信息。但偶尔重新启动是必须的,如为升级 Redis 程序到新的版本,或者当你需要修改某些目前
CONFIG 命令还不支持的配置参数的时候

Redis 中的管道有什么用

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

redis有时候会请求超时,已知都是固定的一个时间,比如200ms或者500ms,问这是为什么
请求redis超时,如果时间较长,比如60s或者75s这样的,可能是redis的timeout配置。目前是时间较短,200ms就超时,一般来说redis没道理在能处理请求的时候报超时错误,会否是现在超过了redis设置的最大连接数maxclients,导致拒绝服务;会否是client自身的连接超时设置。无论如何,CS模式的两端都有可能是原因

mySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据
相关知识:redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。redis 提供 6种数据淘汰策略:
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)中任意选择数据淘汰
no-enviction(驱逐):禁止驱逐数据

Pipeline 有什么好处,为什么要用pipeline?
答:可以将多次 IO 往返的时间缩减为一次,前提是 pipeline 执行的指令之间没有因果相关性。使用
redis-benchmark 进行压测的时候可以发现影响 redis 的 QPS 峰值的一个重要因素是 pipeline 批次指
令的数目。

代码要执多个redis命令,不加锁的情况下如何保证原子性
lua脚本:https://segmentfault.com/a/1190000009811453
Redis 中执行 Lua 脚本
Lua脚本功能为Redis开发和运维人员带来如下三个好处:
● Lua脚本在Redis中是原子执行的,执行过程中间不会插入其他命令。
● Lua脚本可以帮助开发和运维人员创造出自己定制的命令,并可以将这些命令常驻在Redis内存中,实现复用的效果。
● Lua脚本可以将多条命令一次性打包,有效地减少网络开销。

一个 Redis 实例最多能存放多少的 keys?List、Set、Sorted Set 他们最 多能存放多少元素?
理论上 Redis 可以处理多达 232 的 keys,并且在实际中进行了测试,每个实例至少存放了 2 亿 5 千万的 keys。我们正在测试一些较大的值。任何 list、set、和 sorted set 都可以放 232 个元素。换句话说,Redis 的存储极限是系统中的可用内存值