Skip to content

Latest commit

 

History

History
52 lines (26 loc) · 3.19 KB

File metadata and controls

52 lines (26 loc) · 3.19 KB

线程池和性能

后台开发有各种池子, 最广泛的莫过于线程池. 然而多数程序员对线程池的理解, 可能只在"使用线程池能提高性能"这个点上. 我想讲两个故事.

吞吐, 并发和延迟

有天我刚到公司, 包还没放下, 被急匆匆地拉去检查问题: redis性能低下, 才2k就上不去了.

我说不会啊, 然后问了下场景, 发现是跨机房访问. 就说让我看下线程池配置. 一看只有20, 就知道问题在这里了. 修改成200, 问题就没了.

其实很简单, 吞吐 = 并发 / 延迟 . 在同一个机房内, redis操作延迟在1ms以下, 线程池配到20, 可以支撑每秒20k的吞吐; 一旦变成跨机房, 延迟在10ms, 就只能支撑到2k吞吐了.

Zabbix对检查连接池是否正确配置的帮助

上面提到跨机房导致吞吐下降, 还有一种问题是连接回收导致超时. 一般使用连接池的时候, 不要担心没有回收的idle连接会造成浪费, 就让它们idle着. 否则在吞吐不足需要新建连接的时候, 会造成一些请求超时.

这个问题本来没什么好讲的, 重点在于: 原因是通过zabbix发现的. 正常情况下, 因为用了连接池, 后台数据库的连接数应该是稳定的. 如果发现数据库连接波动频繁, 说明连接池用的不好.

image

网上盗了张连接数的图, 如果数据库连接数上看到这种波动, 尤其是缓存, 就该提醒开发人员调整连接池配置了. 好的情况是一条直线.

如果心里有这个问题"具体该怎么配呢?", 我有个非常简单的答案: 把要配的地方都写42. 然后"相信"它.

集群的节点超时

现在我们考虑个复杂点的情况: 10个节点的redis集群, 其中一个节点出现严重超时(但是还没被踢出集群), 这个时候, 集群qps会发生变化? 假设正常访问延迟1ms, 超时为50ms, 正常情况下qps为10k.

qps变为多少, 选项:

  1. 1k
  2. 9k
  3. 5.3k
  4. 1.7k

有没有很想选9k的冲动? 但是考试的训练让我们知道这个答案简直正确得像是错误答案啊.

我就直说了, 其实这些都不是精准答案. 采用上面的公式, 吞吐 = 并发 / 延迟 . 我们先考虑延迟的变化.

Cluster的情况下, 延迟就是访问每个节点的延迟的均值. 之前的延迟是1ms, 现在的延迟是(1*9 + 50)/10 = 5.9ms. 所以, 如果并发不变, 现在的吞吐是原来吞吐的1/5.9, 大约1.7k.

只有这么点是不是让人很惊讶? 能不能多一点? 我们不是还没考虑并发嘛.

1.7k是假设了并发不变, 也就是之前的吞吐达到了系统上限. 现在就要看, 正常情况下, 系统有多少冗余. 在这个情况下, 只要有6倍的冗余, 就不受影响.

不过在现实场景下, 集群一旦出故障, 怎么也得有个两台, 否则都不好意思叫集群故障. 那么平均延迟就会变成10.8ms, 10倍冗余就更很难做到了.

到现在为止, 都是按线程模型说的. 除此之外, 如果用异步模型, 可以假设等于无限的并发冗余, 自然是很好的. 不过上异步模型, 可是得考虑清楚. Tomcat是支持了, 工程师的薪水也得支持才行.