Java-Redis浅谈

一、Redis 基础知识

1、什么是 Redis,有哪些优缺点?

Redis 是一个使用 C 语言编写的,开源的高性能非关系型(NoSQL)的键值对数据库。
Redis 可以存储键和五种不同类型的值之间的映射。键的类型只能为字符串,值支持五种数据类型:字符串、列表、集合、散列表、有序集合。
Redis 的数据是存在内存中的,所以读写速度非常快,因此 redis 被广泛应用于缓存方向,每秒可以处理超过 10 万次读写操作
Redis 支持事务 、持久化、LUA 脚本、LRU 驱动事件、多种集群方案。
整体的回答流程就是概念 + 基本数据类型 + 特点 + 可以做什么
(1)优点
读写速度快、支持持久化、数据结构丰富、支持主从复制。
(2)缺点
受物理内存的限制、不具备自动容错和恢复功能、较难支持在线扩容

2、Redis 为什么这么快

(1)完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。
(2)数据结构简单,操作也简单,Redis 中的数据结构是专门进行设计的;
(3)采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题
(4)使用多路 I/O 复用模型,非阻塞 IO;
(5)使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis 直接自己构建了 VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;

3、为什么要用 Redis 而不用 map/guava 做缓存?

缓存分为本地缓存和分布式缓存。以 Java 为例,使用自带的 map 或者 guava 实现的是本地缓存,最主要的特点是轻量以及快速,生命周期随着 jvm 的销毁而结束,并且在多实例的情况下,每个实例都需要各自保存一份缓存,缓存不具有一致性。
使用 redis 或 memcached 之类的称为分布式缓存,在多实例的情况下,各实例共用一份缓存数据,缓存具有一致性。

4、Redis 与 Memcached 的区别

区别很多,有一张表,我觉得记不住,大概下面三种就可以:
(1) memcached 所有的值均是简单的字符串,redis 作为其替代者,支持更为丰富的数据类型
(2) redis 的速度比 memcached 快很多
(3) redis 可以持久化其数据

5、Redis 常见性能问题和解决方案?

(1)Master 最好不要做任何持久化工作,包括内存快照和 AOF 日志文件,特别是不要启用内存快照做持久化。
(2)如果数据比较关键,某个 Slave 开启 AOF 备份数据,策略为每秒同步一次。
(3)为了主从复制的速度和连接的稳定性,Slave 和 Master 最好在同一个局域网内。
(4)尽量避免在压力较大的主库上增加从库
(5)Master 调用 BGREWRITEAOF 重写 AOF 文件,AOF 在重写的时候会占大量的 CPU 和内存资源,导致服务 load 过高,出现短暂服务暂停现象。
(6)为了 Master 的稳定性,主从复制不要用图状结构,用单向链表结构更稳定,即主从关系为:Master<–Slave1<–Slave2<–Slave3…,这样的结构也方便解决单点故障问题,实现 Slave 对 Master 的替换,也即,如果 Master 挂了,可以立马启用 Slave1 做 Master,其他不变。

二、数据类型

1、Redis 有哪些数据类型,都在哪些场景中使用过?
Redis 主要有 5 种数据类型,包括 String,List,Set,Zset,Hash,满足大部分的使用要求。
(1)string:适合最简单的 k-v 存储,类似于 memcached 的存储结构,短信验证码,配置信息等,就用这种类型来存储。
(2)hash:一般 key 为 ID 或者唯一标示,value 对应的就是详情了。如商品详情,个人信息详情,新闻详情等。
(3)list:因为 list 是有序的,比较适合存储一些有序且数据相对固定的数据。如省市区表、字典表等。因为 list 是有序的,适合根据写入的时间来排序,如:最新的排名。
(4)set:可以简单的理解为 ID-List 的模式,如微博中一个人有哪些好友,set 最牛的地方在于,可以对两个 set 提供交集、并集、差集操作。例如:查找两个人共同的好友等。
(5)Sorted Set:是 set 的增强版本,增加了一个 score 参数,自动会根据 score 的值进行排序。比较适合类似于 top 10 等不根据插入的时间来排序的数据。

三、持久化技术(重点)

1、Redis 的持久化机制是什么?各自的优缺点?
Redis 提供两种持久化机制 RDB(默认) 和 AOF 机制:
(1)RDB 是 Redis 默认的持久化方式。按照一定的时间将内存的数据以快照的形式保存到硬盘中,对应产生的数据文件为 dump.rdb。通过配置文件中的 save 参数来定义快照的周期。
优点:
1、只有一个文件 dump.rdb,方便持久化。
2、容灾性好,一个文件可以保存到安全的磁盘。
3、性能最大化,fork 子进程来完成写操作,让主进程继续处理命令,所以是 IO 最大化。使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 redis 的高性能
4. 相对于数据集大时,比 AOF 的启动效率更高。
缺点:数据安全性低。RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候 )
(2)AOF 持久化 (即 Append Only File 持久化),则是将 Redis 执行的每次写命令记录到单独的日志文件中,当重启 Redis 会重新将持久化的日志中文件恢复数据。
优点:数据安全、可以解决数据一致性问题。
缺点:AOF 文件比 RDB 文件大,且恢复速度慢、比 rdb 启动效率低。
2、如何选择合适的持久化方式
(1)应该同时使用两种持久化功能。在这种情况下,当 Redis 重启的时候会优先载入 AOF 文件来恢复原始的数据,因为在通常情况下 AOF 文件保存的数据集要比 RDB 文件保存的数据集要完整。
(2)如果允许部分数据丢失,可以使用 RDB 方式,并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快,除此之外,使用 RDB 还可以避免 AOF 程序的 bug。
(3)如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式。
3、Redis 怎么扩容?
(1)如果 Redis 被当做缓存使用时,使用一致性哈希实现动态扩容缩容。
(2)如果 Redis 被当做一个持久化存储使用,使用 Redis 集群进行扩容。
4、Redis 如何做大量数据插入?
Redis2.6 开始 redis-cli 支持一种新的被称之为 pipe mode 的新模式用于执行大量数据插入工作。
5、假如 Redis 里面有 1 亿个 key,其中有 10w 个 key 是以某个固定的已知的前缀开头的,如果将它们全部找出来?
使用 keys 指令可以扫出指定模式的 key 列表。 对方接着追问:如果这个 redis 正在给线上的业务提供服务,那使用 keys 指令会有什么问题? 这个时候你要回答 redis 关键的一个特性:redis 的单线程的。keys 指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。这个时候可以使用 scan 指令,scan 指令可以无阻塞的提取出指定模式的 key 列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用 keys 指令长。
6、使用 Redis 做过异步队列吗,是如何实现的
使用 list 类型保存数据信息,rpush 生产消息,lpop 消费消息,当 lpop 没有消息时,可以 sleep 一段时间,然后再检查有没有信息,如果不想 sleep 的话,可以使用 blpop, 在没有信息的时候,会一直阻塞,直到信息的到来。redis 可以通过 pub/sub 主题订阅模式实现一个生产者,多个消费者,当然也存在一定的缺点,当消费者下线时,生产的消息会丢失。
7、Redis 如何实现延时队列
使用 sortedset,使用时间戳做 score, 消息内容作为 key, 调用 zadd 来生产消息,消费者使用 zrangbyscore 获取 n 秒之前的数据做轮询处理。

四、过期删除策略(重点)

1、Redis 的过期键的删除策略
过期策略通常有以下三种:
(1)定时过期:每个设置过期时间的 key 都需要创建一个定时器,到过期时间就会立即清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的 CPU 资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。
(2)惰性过期:只有当访问一个 key 时,才会判断该 key 是否已过期,过期则清除。该策略可以最大化地节省 CPU 资源,却对内存非常不友好。极端情况可能出现大量的过期 key 没有再次被访问,从而不会被清除,占用大量内存。
(3)定期过期:每隔一定的时间,会扫描一定数量的数据库的 expires 字典中一定数量的 key,并清除其中已过期的 key。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得 CPU 和内存资源达到最优的平衡效果。
Redis 中同时使用了惰性过期和定期过期两种过期策略。
2、设置过期时间和永久有效的命令是什么?
EXPIRE 和 PERSIST 命令
3、Redis 的内存淘汰策略有哪些?
全局的键空间选择性移除
(1)noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。
(2)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key。(这个是最常用的)
(3)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 key。
设置过期时间的键空间选择性移除
(1)volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的 key。
(2)volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 key。
(3)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 key 优先移除。
在 2.8.13 的版本里,默认是 noeviction,在 3.2.3 版本里默认是 volatile-lru。
4、Redis 如何做内存优化?
尽可能使用散列表(hashes),散列表(是说散列表里面存储的数少)使用的内存非常小,所以你应该尽可能的将你的数据模型抽象到一个散列表里面。比如你的 web 系统中有一个用户对象,不要为这个用户的名称,姓氏,邮箱,密码设置单独的 key,而是应该把这个用户的所有信息存储到一张散列表里面。

五、Redis 事务

1、Redis 事务的概念?
Redis 事务的本质是通过 MULTI、EXEC、WATCH 等一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。
总结说:redis 事务就是一次性、顺序性、排他性的执行一个队列中的一系列命令。
2、Redis 事务的三个阶段
事务开始 MULTI、命令入队、事务执行 EXEC
3、Redis 事务支持隔离性吗?
Redis 是单进程程序,并且它保证在执行事务时,不会对事务进行中断,事务可以运行直到执行完所有事务队列中的命令为止。因此,Redis 的事务是总是带有隔离性的。
4、Redis 事务保证原子性吗,支持回滚吗?
Redis 中,单条命令是原子性执行的,但事务不保证原子性,且没有回滚。事务中任意命令执行失败,其余的命令仍会被执行。
1.          如果在一个事务中的命令出现错误,那么所有的命令都不会执行;
2.          如果在一个事务中出现运行错误,那么正确的命令会被执行。

六、Redis 集群

1、什么是哨兵
哨兵的介绍
sentinel,中文名是哨兵。哨兵是 redis 集群机构中非常重要的一个组件,主要有以下功能:
(1)集群监控:负责监控 redis master 和 slave 进程是否正常工作。
(2)消息通知:如果某个 redis 实例有故障,那么哨兵负责发送消息作为报警通知给管理员。
(3)故障转移:如果 master node 挂掉了,会自动转移到 slave node 上。
(4)配置中心:如果故障转移发生了,通知 client 客户端新的 master 地址。 哨兵用于实现 redis 集群的高可用,本身也是分布式的,作为一个哨兵集群去运行,互相协同工作。
哨兵的核心知识
(1)哨兵至少需要 3 个实例,来保证自己的健壮性。
(2)哨兵 + redis 主从的部署架构,是不保证数据零丢失的,只能保证 redis 集群的高可用性。
(3)对于哨兵 + redis 主从这种复杂的部署架构,尽量在测试环境和生产环境,都进行充足的测试和演练。
2、redis 集群模式的工作原理能说一下么?
Redis Cluster 是一种服务端 Sharding 技术,3.0 版本开始正式提供。Redis Cluster 并没有使用一致性 hash,而是采用 slot(槽) 的概念,一共分成 16384 个槽。将请求发送到任意节点,接收到请求的节点会将查询请求发送到正确的节点上执行。
3、分布式寻址都有哪些算法?
(1)hash 算法(大量缓存重建)
(2)一致性 hash 算法(自动缓存迁移)+ 虚拟节点(自动负载均衡)
(3)redis cluster 的 hash slot 算法
4、节点间如何通信?
集群元数据的维护有两种方式:集中式、Gossip 协议。redis cluster 节点间采用 gossip 协议进行通信。
5、Redis Sharding 如何实现的?
Redis Sharding 是 Redis Cluster 出来之前,业界普遍使用的多 Redis 实例集群方法。其主要思想是采用哈希算法将 Redis 数据的 key 进行散列,通过 hash 函数,特定的 key 会映射到特定的 Redis 节点上。Java redis 客户端驱动 jedis,支持 Redis Sharding 功能,即 ShardedJedis 以及结合缓存池的 ShardedJedisPool
6、Redis 主从架构原理
单机的 redis,能够承载的 QPS 大概就在上万到几万不等。对于缓存来说,一般都是用来支撑读高并发的。因此架构做成主从 (master-slave) 架构,一主多从,主负责写,并且将数据复制到其它的 slave 节点,从节点负责读。所有的读请求全部走从节点。这样也可以很轻松实现水平扩容,支撑读高并发。
过程原理
(1)当从库和主库建立 MS 关系后,会向主数据库发送 SYNC 命令
(2)主库接收到 SYNC 命令后会开始在后台保存快照 (RDB 持久化过程),并将期间接收到的写命令缓存起来
(3)当快照完成后,主 Redis 会将快照文件和所有缓存的写命令发送给从 Redis
(4)从 Redis 接收到后,会载入快照文件并且执行收到的缓存的命令
(5)之后,主 Redis 每当接收到写命令时就会将命令发送从 Redis,从而保证数据的一致
7、Redis 集群会有写操作丢失吗?为什么?
Redis 并不能保证数据的强一致性,这意味这在实际中集群在特定的条件下可能会丢失写操作。
8、Redis 集群之间是如何复制的?(异步复制)
9、Redis 集群最大节点个数是多少?(16384)
10、Redis 是单线程的,如何提高多核 CPU 的利用率?
可以在同一个服务器部署多个 Redis 的实例,并把他们当作不同的服务器来使用,在某些时候,无论如何一个服务器是不够的, 所以,如果你想使用多个 CPU,你可以考虑一下分片(shard)。
11、为什么要做 Redis 分区?
分区可以让 Redis 管理更大的内存,Redis 将可以使用所有机器的内存。如果没有分区,你最多只能使用一台机器的内存。分区使 Redis 的计算能力通过简单地增加计算机得到成倍提升,Redis 的网络带宽也会随着计算机和网卡的增加而成倍增长。
12、有哪些 Redis 分区实现方案?
(1)客户端分区就是在客户端就已经决定数据会被存储到哪个 redis 节点或者从哪个 redis 节点读取。大多数客户端已经实现了客户端分区。
(2)代理分区 意味着客户端将请求发送给代理,然后代理决定去哪个节点写数据或者读数据。代理根据分区规则决定请求哪些 Redis 实例,然后根据 Redis 的响应结果返回给客户端。redis 和 memcached 的一种代理实现就是 Twemproxy
(3)查询路由 (Query routing) 的意思是客户端随机地请求任意一个 redis 实例,然后由 Redis 将请求转发给正确的 Redis 节点。Redis Cluster 实现了一种混合形式的查询路由,但并不是直接将请求从一个 redis 节点转发到另一个 redis 节点,而是在客户端的帮助下直接 redirected 到正确的 redis 节点。
13、Redis 分区有什么缺点?
(1)涉及多个 key 的操作通常不会被支持。例如你不能对两个集合求交集,因为他们可能被存储到不同的 Redis 实例(实际上这种情况也有办法,但是不能直接使用交集指令)。
(2)同时操作多个 key, 则不能使用 Redis 事务.
(3)分区使用的粒度是 key,不能使用一个非常长的排序 key 存储一个数据集
(4)当使用分区的时候,数据处理会非常复杂,例如为了备份你必须从不同的 Redis 实例和主机同时收集 RDB / AOF 文件。
(5)分区时动态扩容或缩容可能非常复杂。Redis 集群在运行时增加或者删除 Redis 节点,能做到最大程度对用户透明地数据再平衡,但其他一些客户端分区或者代理分区方法则不支持这种特性。然而,有一种预分片的技术也可以较好的解决这个问题。
14、Redis 如何实现分布式锁?
使用 SETNX 完成同步锁的流程及事项如下:
使用 SETNX 命令获取锁,若返回 0(key 已存在,锁已存在)则获取失败,反之获取成功
为了防止获取锁后程序出现异常,导致其他线程 / 进程调用 SETNX 命令总是返回 0 而进入死锁状态,需要为该 key 设置一个“合理”的过期时间
释放锁,使用 DEL 命令将锁数据删除
15、如何解决 Redis 的并发竞争 Key 问题
所谓 Redis 的并发竞争 Key 的问题也就是多个系统同时对一个 key 进行操作,但是最后执行的顺序和我们期望的顺序不同,这样也就导致了结果的不同!
推荐一种方案:分布式锁(zookeeper 和 redis 都可以实现分布式锁)。(如果不存在 Redis 的并发竞争 Key 问题,不要使用分布式锁,这样会影响性能)
zookeeper 分布式锁准备在今后的面试文章中提到。
16、分布式 Redis 是前期做还是后期规模上来了再做好?为什么?
既然 Redis 是如此的轻量(单实例只使用 1M 内存),为防止以后的扩容,最好的办法就是一开始就启动较多实例。即便你只有一台服务器,你也可以一开始就让 Redis 以分布式的方式运行,使用分区,在同一台服务器上启动多个实例。
一开始就多设置几个 Redis 实例,例如 32 或者 64 个实例,对大多数用户来说这操作起来可能比较麻烦,但是从长久来看做这点牺牲是值得的。
这样的话,当你的数据不断增长,需要更多的 Redis 服务器时,你需要做的就是仅仅将 Redis 实例从一台服务迁移到另外一台服务器而已(而不用考虑重新分区的问题)。一旦你添加了另一台服务器,你需要将你一半的 Redis 实例从第一台机器迁移到第二台机器。
17、什么是 RedLock
Redis 官方站提出了一种权威的基于 Redis 实现分布式锁的方式名叫 Redlock,此种方式比原先的单节点的方法更安全。它可以保证以下特性:
(1)安全特性:互斥访问,即永远只有一个 client 能拿到锁
(2)避免死锁:最终 client 都可能拿到锁,不会出现死锁的情况,即使原本锁住某资源的 client crash 了或者出现了网络分区
(3)容错性:只要大部分 Redis 节点存活就可以正常提供服务
18、如何保证缓存与数据库双写时的数据一致性?
你只要用缓存,就可能会涉及到缓存与数据库双存储双写,你只要是双写,就一定会有数据一致性的问题,那么你如何解决一致性问题?
(1)一般来说,就是如果你的系统不是严格要求缓存 + 数据库必须一致性的话,缓存可以稍微的跟数据库偶尔有不一致的情况,最好不要做这个方案,读请求和写请求串行化,串到一个内存队列里去,这样就可以保证一定不会出现不一致的情况
串行化之后,就会导致系统的吞吐量会大幅度的降低,用比正常情况下多几倍的机器去支撑线上的一个请求。
(2)还有一种方式就是可能会暂时产生不一致的情况,但是发生的几率特别小,就是先更新数据库,然后再删除缓存。

七、缓存异常

1、缓存雪崩
缓存雪崩是指缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大量请求而崩掉。
解决方案
(1)缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
(2)一般并发量不是特别多的时候,使用最多的解决方案是加锁排队。
(3)给每一个缓存数据增加相应的缓存标记,记录缓存的是否失效,如果缓存标记失效,则更新数据缓存。
2、缓存穿透
缓存穿透是指缓存和数据库中都没有的数据,导致所有的请求都落到数据库上,造成数据库短时间内承受大量请求而崩掉。
解决方案
(1)接口层增加校验,如用户鉴权校验,id 做基础校验,id<=0 的直接拦截;
(2)从缓存取不到的数据,在数据库中也没有取到,这时也可以将 key-value 对写为 key-null,缓存有效时间可以设置短点,如 30 秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个 id 暴力攻击
(3)采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的 bitmap 中,一个一定不存在的数据会被这个 bitmap 拦截掉,从而避免了对底层存储系统的查询压力。
3、缓存击穿
缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。
和缓存雪崩不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。
解决方案
(1)设置热点数据永远不过期。
(2)加互斥锁,互斥锁
4、缓存预热
缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!
解决方案
(1)直接写个缓存刷新页面,上线时手工操作一下;
(2)数据量不大,可以在项目启动的时候自动进行加载;
(3)定时刷新缓存;
5、缓存降级
当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级。
缓存降级的最终目的是保证核心服务可用,即使是有损的。而且有些服务是无法降级的(如加入购物车、结算)。
在进行降级之前要对系统进行梳理,看看系统是不是可以丢卒保帅;从而梳理出哪些必须誓死保护,哪些可降级;比如可以参考日志级别设置预案:
(1)一般:比如有些服务偶尔因为网络抖动或者服务正在上线而超时,可以自动降级;
(2)警告:有些服务在一段时间内成功率有波动(如在 95~100% 之间),可以自动降级或人工降级,并发送告警;
(3)错误:比如可用率低于 90%,或者数据库连接池被打爆了,或者访问量突然猛增到系统能承受的最大阀值,此时可以根据情况自动降级或者人工降级;
(4)严重错误:比如因为特殊原因数据错误了,此时需要紧急人工降级。
服务降级的目的,是为了防止 Redis 服务故障,导致数据库跟着一起发生雪崩问题。因此,对于不重要的缓存数据,可以采取服务降级策略,例如一个比较常见的做法就是,Redis 出现问题,不去数据库查询,而是直接返回默认值给用户。
6、缓存热点 key
缓存中的一个 Key(比如一个促销商品),在某个时间点过期的时候,恰好在这个时间点对这个 Key 有大量的并发请求过来,这些请求发现缓存过期一般都会从后端 DB 加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端 DB 压垮。
解决方案
(1)对缓存查询加锁,如果 KEY 不存在,就加锁,然后查 DB 入缓存,然后解锁;
(2)其他进程如果发现有锁就等待,然后等解锁后返回数据或者进入 DB 查询

八、常用工具

1、Redis 支持的 Java 客户端都有哪些?官方推荐用哪个?
Redisson、Jedis、lettuce 等等,官方推荐使用 Redisson。
2、Redis 和 Redisson 有什么关系?
Redisson 是一个高级的分布式协调 Redis 客户端,能帮助用户在分布式环境中轻松实现一些 Java 的对象 。
3、Jedis 与 Redisson 对比有什么优缺点?
Jedis 是 Redis 的 Java 实现的客户端,其 API 提供了比较全面的 Redis 命令的支持;Redisson 实现了分布式和可扩展的 Java 数据结构,和 Jedis 相比,功能较为简单,不支持字符串操作,不支持排序、事务、管道、分区等 Redis 特性。Redisson 的宗旨是促进使用者对 Redis 的关注分离,从而让使用者能够将精力更集中地放在处理业务逻辑上
 

作者:三尺青锋
本文链接:https://www.cnblogs.com/zhangjiale/p/17394356.html