Redis根据定价层说明,不同级别支持的连接数最多可达4万(同时),但是当短时间又大量连接请求建立的时候,Redis服务的服务压力非常大,到达100%。严重影响了高响应的要求。最严重时,经常出现Redis Client Operation timeout错误。
问题分析根据设计,Redis 只使用一个线程进行命令处理。 Azure Cache for Redis 还利用其它核心进行 I/O 处理。 拥有更多的内核可能不会产生线性缩放,但可提高吞吐量性能。 而且,较大 VM 的带宽限制通常比较小 VM 的更高。 这有助于避免网络饱和,从而避免应用程序超时。
基本缓存和标准缓存
C0 (250 MB) 缓存 - 最多支持 256 个连接
C1 (1 GB) 缓存 - 最多支持 1,000 个连接
C2 (2.5 GB) 缓存 - 最多支持 2,000 个连接
C3 (6 GB) 缓存 - 最多支持 5,000 个连接
C4 (13 GB) 缓存 - 最多支持 10,000 个连接
C5 (26 GB) 缓存 - 最多支持 15,000 个连接
C6 (53 GB) 缓存 - 最多支持 20,000 个连接
高级缓存
P1 (6 GB - 60 GB) - 最多支持 7,500 个连接
P2 (13 GB - 130 GB) - 最多支持 15,000 个连接
P3 (26 GB - 260 GB) - 最多支持 30,000 个连接
P4 (53 GB - 530 GB) - 最多支持 40,000 个连接
虽然每个缓存大小 最多 允许一定数量的连接,但与 Redis 的每个连接都具有其关联的开销。 此类开销的一个示例是,由于 TLS/SSL 加密而导致的 CPU 和内存使用。 给定缓存大小的最大连接限制假定轻负载缓存。 如果连接开销的负载 和 客户端操作的负载超出了系统容量,那么即使未超出当前缓存大小的连接限制,缓存也可能会遇到容量问题。 解决方案启用连接池,重复使用连接。创建新连接是高开销的操作,会增大延迟,因此请尽量重复使用连接。 如果你选择创建新连接,请确保在释放旧连接之前先将其关闭(即使是在 .NET 或 Java 等托管内存语言中)。
避免高开销操作 - 某些 Redis 操作(例如 KEYS 命令)的开销很大,应该避免。 有关详细信息,请参阅有关的一些注意事项
如果请求连接及性能要求已经超过了单个服务器的极限,则考虑使用Redis Cluster (集群,增加分片数)。
连接池实例
一: Jedis的连接池设置
................. // boolean useSsl = true; String cacheHostname = "xxxx.redis.cache.chinacloudapi.cn"; String cachekey = " Key"; JedisPool jdspool = getPool(cacheHostname, 6379, cachekey); Jedis jedis1 = jdspool.getResource(); System.out.println("Cache Response : " + jedis1.set("Message-1","hello pool")); String msg = "Hello! The cache is working from Java!"; for (int i = 0; i < 10000; i++) { try { Jedis jedis = jdspool.getResource(); System.out.println("Cache Response : " + jedis.set("Message-Java-" + i, msg + i)); jedis.close(); } catch (Exception ex) { ex.printStackTrace(); } } .................... /** * 获取连接池. * * @return 连接池实例 */ public static JedisPool getPool(String ip, int port, String cachekey) { JedisPoolConfig config = new JedisPoolConfig(); config.setMaxIdle(20); config.setMaxTotal(20); config.setMinIdle(10); config.setMaxWaitMillis(2000); config.setTestOnBorrow(true); config.setTestOnReturn(true); JedisPool pool = null; try { /** * 如果你遇到 java.net.SocketTimeoutException: Read timed out exception的异常信息 * 请尝试在构造JedisPool的时候设置自己的超时值. JedisPool默认的超时时间是2秒(单位毫秒) */ pool = new JedisPool(config, ip, port, 2000, cachekey); } catch (Exception e) { e.printStackTrace(); } return pool; }