Redis【有与无】【Lettuce】L5.Redis Cluster
本文章基于Redis 6.0.9版本,Lettuce 6.0.1.RELEASE版本
目录
1.Redis Cluster
1.1.命令路由
1.2.跨槽命令执行和所选命令的全集群执行
例子1.使用NodeSelection API从所有复制节点中读取所有键
1.3.刷新集群拓扑视图
1.4.Redis群集连接对象的连接计数
1.5.客户端选项
1.6.例子
例子2.连接到Redis集群
示例3.连接到具有多个种子节点的Redis群集
例子4.启用定期集群拓扑视图更新
例子5.启用自适应集群拓扑视图更新
例子6.获得一个节点连接
1.Redis Cluster
Lettuce通过以下方式支持Redis Cluster:
- 支持所有CLUSTER命令
- 基于命令键的哈希槽(hash slot)的命令路由
- 所选集群命令的高级抽象
- 在多个群集节点上执行命令
- MOVED和ASK重定向处理
- 通过插槽(slot)和host/port获得与群集节点的直接连接(自3.3起)
- SSL和身份验证(从4.2开始)
- 定期和自适应群集拓扑更新
- 发布/订阅
连接到Redis集群需要一个或多个初始种子节点。 完整的集群拓扑视图(topology)(分区)是在第一个连接上获得的,因此你无需指定所有集群节点。 指定多个种子节点有助于提高弹性,因为即使种子节点不可用,Lettuce仍可以连接群集。 Lettuce拥有多个连接,可根据需要打开。 你可以自由操作这些连接。
可以将连接绑定到特定的host或nodeId。 即使nodeId由其他host处理,绑定到nodeId的连接也将始终坚持该nodeId。 对不属于群集的未知nodeId或host/ports的请求将被拒绝。 不要关闭连接。 否则,将发生不可预测的行为。 还请记住,群集连接本身会使用节点连接来执行群集操作:如果阻止一个连接,则群集连接的所有其他用户可能会受到影响。
1.1.命令路由
Redis Cluster的概念基于分片。 群集中的每个上游(upstream)节点都处理一个或多个插槽(slots)。 插槽是分片的单位,使用CRC16 MOD 16384
根据命令的键计算得出。还可以使用哈希标签(例如{user:1000}.foo
)指定哈希插槽。
包含至少一个键的每个请求都基于其哈希槽路由到相应的节点。没有键的命令在默认连接上执行,该默认连接最有可能指向第一个提供的RedisURI
。 相同的规则适用于对多个键进行操作的命令,但限制是所有键必须位于同一插槽中。在多个插槽上运行的命令将以CROSSSLOT
错误终止。
1.2.跨槽命令执行和所选命令的全集群执行
常规Redis Cluster命令仅限于单槽键操作(共享同一哈希槽的单键命令或多键命令)。
可以通过对一组选定的多键命令使用高级群集API来缓解跨槽限制。 对具有不同插槽的键进行操作的命令将分解为多个命令。 单个命令以fork/join方式触发。 同时发出命令以避免同步链接。 结果在命令完成之前已同步。
跨槽命令执行支持以下命令:
DEL
: 删除键。 返回已删除的键的数量。EXISTS
: 计算负责特定键的上游(upstream)节点中存在的键数量。MGET
: 获取所有给定键的值。 按键顺序返回值。MSET
: 为所有给定的键设置多个key/value对。 始终返回OK。TOUCH
: 更改所有给定键的最后访问时间。 返回被触摸的键数。UNLINK
: 删除键并在其他线程中回收内存。 返回已删除的键的数量。
在多个群集节点操作上执行以下命令:
CLIENT SETNAME
: 在所有已知的群集节点连接上设置客户端名称。 始终返回OK。KEYS
: Return/Stream存储在所有上游节点(upstreams)的所有键。DBSIZE
: 返回所有上游节点(upstreams)存储的键数。FLUSHALL
: 刷新集群上游节点(upstreams)的所有数据。 始终返回OK。FLUSHDB
: 刷新集群上节点(upstreams)的所有数据。 始终返回OK。RANDOMKEY
: Return a random key from a random upstream.从随机上游节点(upstream)返回一个随机键。SCAN
: 根据ReadFrom
设置在整个集群中扫描键空间。SCRIPT FLUSH
: 从所有群集节点上的脚本缓存中删除所有脚本。SCRIPT LOAD
: 将脚本加载到所有节点上的Lua脚本缓存中。SCRIPT KILL
: 杀死所有集群节点上当前正在执行的脚本。 即使没有脚本在运行,此调用也不会失败。SHUTDOWN
: 同步将数据集保存到磁盘,然后关闭群集的所有节点。
以下API可以执行跨槽命令:
RedisAdvancedClusterCommands
RedisAdvancedClusterAsyncCommands
RedisAdvancedClusterReactiveCommands
一个或多个群集节点上执行命令
有时必须在多个群集节点上执行命令。 先进的群集API允许选择一组节点(例如,所有上游节点(upstreams),所有复制节点(replicas))并在该节点上触发命令。
例子1.使用NodeSelection API从所有复制节点中读取所有键
RedisAdvancedClusterAsyncCommands<String, String> async = clusterClient.connect().async();
AsyncNodeSelection<String, String> replicas = connection.slaves();AsyncExecutions<List<String>> executions = replicas.commands().keys("*");
executions.forEach(result -> result.thenAccept(keys -> System.out.println(keys)));
这些命令是同时触发的。 该API当前仅适用于异步命令。 命令被分派到选择中的节点,结果(CompletionStage)可通过AsyncExecutions
获得。
节点选择可以是动态的也可以是静态的。 动态节点选择会在集群拓扑视图刷新时更新其节点集。 可以通过以下预设来构造节点选择:
- 上游节点(upstreams)
- 复制节点(replicas )(在激活的READONLY模式下进行连接)
- 所有节点(all nodes)
通过实现自定义谓词或lambda,可以自定义选择节点。
特定结果映射到节点选择中涉及的群集节点(RedisClusterNode
)。 你可以从AsyncExecutions
获取涉及的RedisClusterNode
s 集合和所有结果作为CompletableFuture
。
节点选择API是技术预览,可以随时更改。 该方法允许强大的操作,但需要用户的进一步反馈。 因此,随时贡献自己的力量。
1.3.刷新集群拓扑视图
Redis群集配置可能会在运行时更改。 可以添加新节点,可以更改特定插槽的上游节点(upstream)。 Lettuce透明地处理MOVED和ASK重定向,但是如果有太多命令运行到重定向中,则应刷新集群拓扑(topology)视图。 拓扑绑定到RedisClusterClient实例。 一个RedisClusterClient实例创建的所有集群连接共享同一集群拓扑视图。 该视图可以通过三种方式更新:
- 通过调用 RedisClusterClient.reloadPartitions
- 根据时间间隔在后台进行定期更新
- 基于持久断开连接和
MOVED
/ASK
重定向的后台自适应更新
缺省情况下,命令遵循-ASK
和-MOVED
最多重定向5次,直到命令执行失败为止。 后台拓扑更新从通过RedisClusterClient
获得的第一个连接开始。
1.4.Redis群集连接对象的连接计数
使用独立Redis,单个连接对象与单个传输连接相关。 Redis Cluster的工作原理有所不同:Redis Cluster的连接对象由多个传输连接组成。 这些是:
- 默认连接对象(用于key-less命令和发布/订阅消息发布)
- 每个节点的连接(用于与单个群集节点通信的读/写连接)
- 使用
ReadFrom
时:每个只读复制节点的只读连接(只读连接,用于从只读复制节点读取数据)
连接是按需分配的,而不是从最少量的连接开始就预先分配的。 计算单个连接对象的最大传输连接数的公式:
1 + (N * 2)
其中N是群集节点的数量。
除连接对象外,RedisClusterClient
使用其他连接进行拓扑刷新。 这些在拓扑刷新时创建,并在获取拓扑后关闭:
- 集群拓扑刷新的连接集(每个集群节点的连接)
1.5.客户端选项
参见L6.客户端选项
1.6.例子
例子2.连接到Redis集群
RedisURI redisUri = RedisURI.Builder.redis("localhost").withPassword("authentication").build();RedisClusterClient clusterClient = RedisClusterClient.create(redisUri);
StatefulRedisClusterConnection<String, String> connection = clusterClient.connect();
RedisAdvancedClusterCommands<String, String> syncCommands = connection.sync();...connection.close();
clusterClient.shutdown();
示例3.连接到具有多个种子节点的Redis群集
RedisURI node1 = RedisURI.create("node1", 6379);
RedisURI node2 = RedisURI.create("node2", 6379);RedisClusterClient clusterClient = RedisClusterClient.create(Arrays.asList(node1, node2));
StatefulRedisClusterConnection<String, String> connection = clusterClient.connect();
RedisAdvancedClusterCommands<String, String> syncCommands = connection.sync();...connection.close();
clusterClient.shutdown();
例子4.启用定期集群拓扑视图更新
RedisClusterClient clusterClient = RedisClusterClient.create(RedisURI.create("localhost", 6379));ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder().enablePeriodicRefresh(10, TimeUnit.MINUTES).build();clusterClient.setOptions(ClusterClientOptions.builder().topologyRefreshOptions(topologyRefreshOptions).build());
...clusterClient.shutdown();
例子5.启用自适应集群拓扑视图更新
RedisURI node1 = RedisURI.create("node1", 6379);
RedisURI node2 = RedisURI.create("node2", 6379);RedisClusterClient clusterClient = RedisClusterClient.create(Arrays.asList(node1, node2));ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder().enableAdaptiveRefreshTrigger(RefreshTrigger.MOVED_REDIRECT, RefreshTrigger.PERSISTENT_RECONNECTS).adaptiveRefreshTriggersTimeout(30, TimeUnit.SECONDS).build();clusterClient.setOptions(ClusterClientOptions.builder().topologyRefreshOptions(topologyRefreshOptions).build());
...clusterClient.shutdown();
例子6.获得一个节点连接
RedisURI node1 = RedisURI.create("node1", 6379);
RedisURI node2 = RedisURI.create("node2", 6379);RedisClusterClient clusterClient = RedisClusterClient.create(Arrays.asList(node1, node2));
StatefulRedisClusterConnection<String, String> connection = clusterClient.connect();RedisClusterCommands<String, String> node1 = connection.getConnection("host", 7379).sync();...
// do not close node1connection.close();
clusterClient.shutdown();
Redis【有与无】【Lettuce】L5.Redis Cluster相关推荐
- java整合redis集群_SpringBoot2.X整合Redis(单机+集群+多数据源)-Lettuce版
最近项目尝试从SpringBoot1.X升级到SpringBoot2.X, 但是 Spring Boot 2.0中 Redis 客户端驱动现在由 Jedis变为了 Lettuce, 所以尝试测试一下L ...
- [工具类] 系列二 Lettuce 访问Redis 工具类 RedisUtil
最近公司Redis集群启用了ssl和密码校验,使用Jedis访问Redis Cluster的时候,支持不太好.看到spring-data-redis 2.x开始使用Lettuce访问Redis,于是开 ...
- Lettuce操作redis使用指南
-1- 说明 redis版本:redis-3.2.6 环境: 集群, 三主三备 lettuce 版本4.3.0-fi ...
- Redis——Lettuce连接redis集群
Lettuce连接redis集群使用的都是集群专用类,像RedisClusterClient.StatefulRedisClusterConnection.RedisAdvancedClusterCo ...
- 慢连接 java_记一次redis的java客户端lettuce操作慢的解决方案
因为项目业务需要,我们要把数据库中的大量数据缓存到redis中,并且会随时更新缓存,刚开始更新频率是1Hz,没有什么问题,后来更新频率达到了5Hz,lettuce开始疯狂报错:redis comman ...
- redis伪集群安装linux,redis伪集群搭建(亲测无坑)
一.单机版安装部署,伪集群只需要操作前1-8步即可,再往下浏览找到:二.单机版-伪集群 安装部署继续搭建,如需设置密码参照第10步 1.安装基本工具 yum install -y gcc-c++ v ...
- Redis - Spring Data Redis 操作 Jedis 、Lettuce 、 Redisson
文章目录 官网 Jedis VS Lettuce Jedis Code POM依赖 配置文件 配置类 单元测试 Lettuce Code Redisson Code POM依赖 配置文件 配置类 单元 ...
- CentOS7下安装Redis伪集群(基于Redis官方Cluster集群模式版本redis-5.0.10)
文章目录 Redis简介 什么是redis redis的优点 Redis集群都有哪些模式 主从复制(Master-Slave Replication) 哨兵模式(Sentinel) Redis官方 C ...
- redis java客户端配置,Java的Redis客户端选择-jedis与Lettuce
Lettuce 和 Jedis 的定位都是Redis的client,所以他们当然可以直接连接redis server. Jedis在实现上是直接连接的redis server,如果在多线程环境下是非线 ...
- Redis 高级 Java 客户端 Lettuce 的用法及踩坑经验
如果你在网上搜索 Redis 的 Java 客户端,你会发现,大多数文献介绍的都是 Jedis,不可否认,Jedis 是一个优秀的基于 Java 语言的 Redis 客户端,但是,其不足也很明显:Je ...
最新文章
- antd+dva笔记
- 《如何高效学习》作者推荐!
- 响应用户呼声 币安更正BCH简称
- nginx 配置简介
- nginx假死导致的问题回顾
- webpack从入门到精通(四)优化打包配置总结①
- 标准 I/O (带缓冲)
- 企业管理软件开发不能割裂各系统的功能
- Linux下进程的建立 并附Linux exec函数族
- 在双屏软件中,PPT自定义动画注意事项
- dwg格式的计算机图,电脑上怎么打开dwg文件?
- 电脑出现我们在加载您的信息流时遇到了问题
- Quadratic Video Interpolation 视频插帧
- DOS基础使用专题(强烈推荐)2
- 阿里云盘小白羊版!你值得拥有的一款第三方阿里云盘客户端
- Transformers预训练模型使用:文本摘要 Summarization
- 第五课:状语和状语从句
- 金融时间序列分析:7. MA滑动平均模型
- Maven私服Nexus的搭建及使用
- 论文阅读VideoMAE: Masked Autoencoders are Data-Efficient Learners for Self-Supervised Video Pre-Training