云服务器内容精选

  • D CS 实例配置建议 连接池化 因lettuce底层采用基于netty的NIO模式,和redis server进行通信,不同于jedis的BIO模式。底层采用长连接 + 队列的组合模式,借助TCP顺序发、顺序收的特性,来实现同时处理多请求发送和多响应接收,单条连接可支撑的QPS在3K~5K不等,线上系统建议不要超过3K。lettuce本身不支持池化,且在springboot中默认不开启池化,如需开启池化,需通过手动引入commons-pool2组件,并关闭LettuceConnectionFactory.shareNativeConnection(共享连接)来实现池化。 因每条lettuce连接默认需要配置两个线程池-I/O thread pools、computation thread pool,用于支撑IO事件读取和异步event处理,如配置成连接池形式使用,每个连接都将会创建两个线程池,对内存资源的占用偏高。鉴于lettuce的底层模型实现,及单连接突出的处理能力,不建议通过池化的方式使用lettuce。 拓扑刷新 在连接cluster类型实例中,lettuce会在初始化时,向配置的节点列表随机发送cluster nodes来获取集群slot的分布信息。如后续cluster扩/缩容、主备切换等,会导致集群拓扑结构发生变化,lettuce默认是不感知的,需手动开启主动感知拓扑结构变化,如下: 基于application.properties配置 # 开启自适应拓扑刷新 spring.redis.lettuce.cluster.refresh.adaptive=true # 开启每10s定时刷新拓扑结构 spring.redis.lettuce.cluster.refresh.period=10S 基于API配置 ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder() .enableAllAdaptiveRefreshTriggers() .enablePeriodicRefresh(Duration.ofMillis(redisClusterTopologyRefreshPeriodMillis)) .build(); ClusterClientOptions clientOptions = ClusterClientOptions.builder() ... ... .topologyRefreshOptions(topologyRefreshOptions) .build(); 爆炸半径 因lettuce底层采用的是单长连接 + 请求队列的组合模式,一旦遇到网络抖动/闪断,或连接失活,将影响所有请求,尤其是在连接失活场景中,将尝试tcp重传,直至重传超时关闭连接,待连接重建后才能恢复。在重传期间请求队列会不断堆积请求,上层业务非常容易出现批量超时,甚至在部分操作系统内核中的重传超时配置过长,致使业务系统长时间处于不可用状态。因此,不推荐使用lettuce组件,建议用jedis组件替换。
  • SSL连接配置(可选配置) 当实例开启了SSL,通过SSL连接实例时,请使用以下内容替换基于Bean方式配置中的LettuceClientConfiguration构造方法clientConfiguration()。Redis实例支持SSL的情况请参考配置Redis SSL 数据加密 传输。 单机、主备、读写分离、Proxy集群实例配置 @Bean public LettuceClientConfiguration clientConfiguration() { SocketOptions socketOptions = SocketOptions.builder().connectTimeout(Duration.ofMillis(redisConnectTimeout)).build(); SslOptions sslOptions = SslOptions.builder() .trustManager(new File(certificationPath)) .build(); ClientOptions clientOptions = ClientOptions.builder() .sslOptions(sslOptions) .autoReconnect(true) .pingBeforeActivateConnection(true) .cancelCommandsOnReconnectFailure(false) .disconnectedBehavior(ClientOptions.DisconnectedBehavior.ACCEPT_COMMANDS) .socketOptions(socketOptions) .build(); LettuceClientConfiguration clientConfiguration = LettuceClientConfiguration.builder() .commandTimeout(Duration.ofMillis(redisReadTimeout)) .readFrom(ReadFrom.MASTER) .clientOptions(clientOptions) .useSsl() .build(); return clientConfiguration; } Cluster集群实例配置 @Bean public LettuceClientConfiguration clientConfiguration() { SocketOptions socketOptions = SocketOptions.builder().connectTimeout(Duration.ofMillis(redisConnectTimeout)).build(); SslOptions sslOptions = SslOptions.builder() .trustManager(new File(certificationPath)) .build(); ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder() .enableAllAdaptiveRefreshTriggers() .enablePeriodicRefresh(Duration.ofMillis(redisClusterTopologyRefreshPeriodMillis)) .build(); ClusterClientOptions clientOptions = ClusterClientOptions.builder() .sslOptions(sslOptions) .autoReconnect(true) .pingBeforeActivateConnection(true) .cancelCommandsOnReconnectFailure(false) .disconnectedBehavior(ClientOptions.DisconnectedBehavior.ACCEPT_COMMANDS) .socketOptions(socketOptions) .topologyRefreshOptions(topologyRefreshOptions) .build(); LettuceClientConfiguration clientConfiguration = LettuceClientConfiguration.builder() .commandTimeout(Duration.ofMillis(redisReadTimeout)) .readFrom(ReadFrom.MASTER) .clientOptions(clientOptions) .useSsl() .build(); return clientConfiguration; }
  • StackExchange.Redis客户端连接Redis 查看并获取待连接Redis实例的IP地址/ 域名 和端口。 具体步骤请参见查看和修改DCS实例基本信息。 登录弹性云服务器。 弹性云服务器操作系统,这里以Window为例。 在弹性云服务器安装VS 2017社区版。 启动VS 2017,新建一个工程。 工程名自定义,这里设置为“redisdemo”。 使用VS的nuget管理工具安装C# Redis客户端StackExchange.Redis。 按照如图1操作,进入程序包管理器控制台,在nuget控制台输入:Install-Package StackExchange.Redis -Version 2.2.79。(版本号可以不指定) 图1 进入程序包管理器控制台 编写如下代码,并使用String的set和get测试连接。 using System; using StackExchange.Redis; namespace redisdemo { class Program { // redis config private static ConfigurationOptions connDCS = ConfigurationOptions.Parse("{instance_ip_address}:{port},password=********,connectTimeout=2000"); //the lock for singleton private static readonly object Locker = new object(); //singleton private static ConnectionMultiplexer redisConn; //singleton public static ConnectionMultiplexer getRedisConn() { if (redisConn == null) { lock (Locker) { if (redisConn == null || !redisConn.IsConnected) { redisConn = ConnectionMultiplexer.Connect(connDCS); } } } return redisConn; } static void Main(string[] args) { redisConn = getRedisConn(); var db = redisConn.GetDatabase(); //set get string strKey = "Hello"; string strValue = "DCS for Redis!"; Console.WriteLine( strKey + ", " + db.StringGet(strKey)); Console.ReadLine(); } } } 其中,{instance_ip_address}和{port}分别为Redis实例的IP地址/域名以及端口。IP地址/域名和端口获取见1,请按实际情况修改后执行。********为创建Redis实例时自定义的密码,请按实际情况修改后执行。 运行代码,控制台界面输出如下,表示连接成功。 Hello, DCS for Redis! 关于客户端的其他命令,可以参考StackExchange.Redis。