前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >你的Redis集群撑得住吗?

你的Redis集群撑得住吗?

原创
作者头像
雨夜v1
修改2021-03-21 18:40:36
1.2K1
修改2021-03-21 18:40:36
举报

1 前言

一大早有个同事过来问我,今天xxx系统需要增加6个pod。我们当前的Redis是否能够撑得住呢?

2 场景介绍

2.1 Redis和Jedis版本以及重要参数介绍

类型

版本

其他

Redis

4.0.12

三主三从(分布6台虚拟机4c32gb/台)

Jedis

2.9

2.2 Jedis 关键参数详解

首先我们先介绍几个关键的Jedis参数,方便我们后续的资源评估。

参数

说明

默认值

建议值

maxTotal

资源池中的最大连接数

8

详见《2.2.1 关键参数建议》

maxIdle

资源池允许的最大空闲连接数

8

详见《2.2.1 关键参数建议》

minIdle

资源池确保的最少空闲连接数

0

详见《2.2.1 关键参数建议》

blockWhenExhausted

当资源耗尽的时候,调用者是否等待。只有当值为true时,下面的maxWaitMillis才会生效。

true

建议使用默认值。

maxWaitMillis

当资源池连接用尽后,调用者的最大等待时间(单位为毫秒)。

-1(表示永不超时)

不建议使用默认值。

testOnBorrow

向资源池借用连接时是否做连接有效性检测(ping)。检测到的无效连接将会被移除。

false

业务量很大时候建议设置为false,减少一次ping的开销。

testOnReturn

向资源池归还连接时是否做连接有效性检测(ping)。检测到无效连接将会被移除。

false

业务量很大时候建议设置为false,减少一次ping的开销。

jmxEnabled

是否开启JMX监控

true

建议开启,请注意应用本身也需要开启。

2.2.1 关键参数建议

maxTotal(资源池中的最大连接数),该参数主要从如下四点进行考虑:

  1. 业务希望Redis能达到的并发数;
  2. 客户端执行的时间;
  3. Redis资源,例如Redis cluster(三主三从)pod数 *maxTotal < 3 * 单个Redis 分片的最大连接数(默认是10000),也就是要小于30000,正常情况我们还会为改参数乘于一个预留系数 0.8 ,所以公式为: pod数 *maxTotal < 3 * 10000 * 0.8 < 24000;
  4. 资源开销,例如虽然希望控制空闲连接,但又不希望因为连接池中频繁地释放和创建连接造成不必要的开销。

举个简单的例子来计算,比如一个命令的时间(borrow|return resource+Jedis执行命令+网络开销的时间)为1ms,那么一个连接的QPS计算公式为:1s/1ms=1000。如果业务希望我们集群的QPS能达到100w,有10个应用pod, 那计算公式为1000000/1000/10=100。那么maxTotal配置为100。

当然这个值只是一个理论值,我们在预设这个值的时候,需要预留一些资源,所以这个实际值就要比理论值设置大一点,但是这个值不是越大越好,一方面连接太多会占用客户端和服务端资源,另一方面对于Redis这种高QPS的服务器,如果出现大命令的阻塞,即使设置再大的资源池也无济于事。

maxIdle与minIdle

maxIdle实际上才是业务需要的最大连接数,maxTotal 是为了给出余量,所以 maxIdle 不要设置得过小,否则会有new Jedis(新连接)开销,而minIdle是为了控制空闲资源检测。

连接池的最佳性能是maxTotal=maxIdle,这样就避免了连接池伸缩带来的性能干扰。如果您的业务存在突峰访问,建议设置这两个参数的值相等;如果并发量不大或者maxIdle设置过高,则会导致不必要的连接资源浪费。

minIdle为资源池确保的最少空闲连接数,这个参数很重要。我们经常会在Jedis pool预热这一块用到这个参数。由于一些原因(如超时时间设置较小等),项目在启动成功后可能会出现超时。JedisPool定义最大资源数、最小空闲资源数时,不会在连接池中创建Jedis连接。初次使用时,池中没有资源使用则会先new Jedis,使用后再放入资源池,该过程会有一定的时间开销,所以建议在定义JedisPool后,以最小空闲数量为基准对JedisPool进行预热。

综上,您可以根据实际总QPS和调用Redis的客户端规模整体评估每个节点所使用的连接池大小。

使用监控获取合理值

在实际环境中,比较可靠的方法是通过监控来尝试获取参数的最佳值。可以考虑通过JMX等方式实现监控,从而找到合理值。

2.3 最佳实践评估

参数

参数值

maxTotal

500

maxIdle

500

minIdle

100

pod

20

如上列表为当前pod数量和关键参数配置,从普罗米修斯监控看,该集群内存使用率均整体资源达到30%左右,资源很空闲,所以我们只需要评估连接数是否足够,那就是500 * 26 是否小于 10000 * 3 * 80%,答案很明显,最大连接数符合要求。

3.其他

以上是一个最大连接数评估的一个过程,那资源不足的时候,程序会有哪些问题呢?下面将介绍两种资源不足的情况

A. blockWhenExhausted 为false,Jedis不会等待资源释放:

代码语言:txt
复制
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
…
Caused by: java.util.NoSuchElementException: Pool exhausted
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:464)

B.超时:

代码语言:txt
复制
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
…
Caused by: java.util.NoSuchElementException: Timeout waiting for idle object
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:449)

4 总结

当遇到资源评估的时候,稳住。查看下相关的理论,再结合实际一对比,其实很多问题就解决了。本文其实有一些定理总结,具体如下:

  1. 应用端最大连接数估算公式: maxTotal * pod数 < max_clients(redis cluster 单个分片的max_clients)* 分片数 * 80% (预留百分比);
  2. 应用端最大空闲连接数设置: 0 < maxIdle <= maxTotal;
  3. 比较常见的配置推荐: maxIdle == maxTotal == Tomcat 线程数,此配置均满足以上公式。

5 参考文献

1. https://github.com/redis/jedis/blob/master/src/main/java/redis/clients/jedis/JedisPoolConfig.java

2. https://www.alibabacloud.com/help/doc-detail/145231.htm?spm=a2c63.p38356.b99.30.70386695h1A3OP

3. https://www.alibabacloud.com/help/doc-detail/98726.html?spm=a2c5t.11065259.1996646101.searchclickresult.3b337b7aaLFVkZ

感谢您的支持!有空帮忙点个赞!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 前言
  • 2 场景介绍
    • 2.1 Redis和Jedis版本以及重要参数介绍
      • 2.2 Jedis 关键参数详解
        • 2.2.1 关键参数建议
      • 2.3 最佳实践评估
      • 3.其他
      • 4 总结
      • 5 参考文献
      相关产品与服务
      云数据库 Redis
      腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档