Redis异步客户端选型及落地实践
Netty的单个EventLoop仅与单一线程绑定,业务端的并发请求均会被放入EventLoop的任务队列中,最终被该线程顺序处理。同时,Lettuce自身也会维护一个队列,当其通过EventLoop向Redis发送指令时,成功发送的指令会被放入该队列;当收到服务端的响应时,Lettuce又会以FIFO的方式从队列的头部取出对应的指令,进行后续处理。 Redis服务端本身也是基于NIO模型,使用单一线程处理客户端请求。虽然Redis能同时维持成百上千个客户端连接,但是在某一时刻,某个客户端连接的请求均是被顺序处理及响应的。 Redis客户端与服务端通过TCP协议连接,而TCP协议本身会保证数据传输的顺序性。
meet:集群中节点通过向新加入节点发送meet消息,将新节点加入集群中。 ping:节点间通过ping命令交换元数据。 pong:响应ping。 fail:某个节点主观认为某个节点宕机,会向其他节点发送fail消息,进行客观宕机判定。
基于Redis连接信息创建RedisClient 基于RedisClient创建StatefulRedisConnection 从Connection中获取Command,基于Command执行Redis命令操作。
List<RedisURI> servers = new ArrayList<>();
servers.add(RedisURI.create("127.0.0.1", 7000));
servers.add(RedisURI.create("127.0.0.1", 7001));
servers.add(RedisURI.create("127.0.0.1", 7002));
servers.add(RedisURI.create("127.0.0.1", 7003));
servers.add(RedisURI.create("127.0.0.1", 7004));
servers.add(RedisURI.create("127.0.0.1", 7005));
//创建客户端
RedisClusterClient client = RedisClusterClient.create(servers);
//创建连接
StatefulRedisClusterConnection<String, String> connection = client.connect();
//获取异步命令
RedisAdvancedClusterAsyncCommands<String, String> commands = connection.async();
//执行GET命令
RedisFuture<String> future = commands.get("test-lettuce-key");
try {
String result = future.get();
log.info("Get命令返回:{}", result);
} catch (Exception e) {
log.error("Get命令执行异常", e);
}
// 设置基于事件的自适应刷新策略
ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
//开启自适应拓扑刷新
.enableAllAdaptiveRefreshTriggers()
//自适应拓扑刷新事件超时时间,超时后进行刷新
.adaptiveRefreshTriggersTimeout(Duration.ofSeconds(30))
.build();
redisClusterClient.setOptions(ClusterClientOptions.builder()
.topologyRefreshOptions(topologyRefreshOptions)
// redis命令超时时间
.timeoutOptions(TimeoutOptions.enabled(Duration.ofSeconds(30)))
.build());
评论