1
lecher 2016-03-09 22:27:27 +08:00 via Android
这个故障挺有价值的, tornado 爆掉了 MySQL 的查询性能。
TorMySQL 的并发是不是开的也高了点,失去平缓峰值的作用。导致峰值直接击穿 MySQL 。 |
2
cevincheung 2016-03-09 22:37:08 +08:00
中间挂个中间件咧~~~atlas
|
3
sujin190 OP @lecher 是的,以前一直想高并发高并发的,没想过超过 mysql 查询数后的快速失败策略,学习到了,现在果断调低了连接池最大连接数, TorMySQL 应该有个队列等待超时策略才是
|
4
sujin190 OP @cevincheung 像 php 来说,每个进程同一时刻只能接受一个请求,所以一般来说 mysql 并发查询不会太高,同时过高的并发过来会直接访问拒绝,但 tornado 不会,所以像 php 之类的来说是不会出现循环等待的,挂个中间件估计不能解决问题啊
|
5
cevincheung 2016-03-09 22:53:55 +08:00
那就换 postgresql 试试~~~
|
6
pynix 2016-03-09 23:07:11 +08:00
需要缓存来降低 MySQL 查询密度
|
7
sujin190 OP @cevincheung 其实我瞬间并发超过了单机 mysql 的负载,加机器才是王道。。
|
9
cevincheung 2016-03-09 23:20:03 +08:00
@sujin190 试试单机 pgsql 抗
|
10
skydiver 2016-03-09 23:51:04 +08:00 via iPad
mysql 连接数设置低一点,多了自动拒绝连接。
另外客户端的重试策略也需要调整 |
11
calease 2016-03-09 23:53:23 +08:00 via iPhone
中间加一个 redis 应该就没问题了吧。
虽然高峰时第一次会 timeout , 但第二次就去缓存拿了, 不会导致反复 retry 。 还真没试过 tornado 直接连接 MySQL. |
12
lecher 2016-03-09 23:57:17 +08:00 via Android
好奇到底是多大的并发量击穿了 MySQL 。
有没有使用 Redis memcached 之类的缓存热数据? MySQL 如果不是没有建索引或特别复杂的联表查询,一秒跑几千个查询也是绰绰有余的。 |
13
glasslion 2016-03-10 00:22:50 +08:00
@cevincheung pg 连接数高了也一般是用 pgbouncer , pgpool 抗吧
|
14
alexapollo 2016-03-10 00:30:40 +08:00
前端尽量少重试,防止雪崩
|
15
scys 2016-03-10 00:35:08 +08:00
这种情况我倒是遇到过很多次,现在换用了 aiomysql 。
对池管理方便比较简单,最大限制就行,反正并发量用更加简单的 iptables rate limit -_- ... 解决 客户端等得起。 |
16
cevincheung 2016-03-10 01:06:59 +08:00
@glasslion
中间多个中间件应该不会有突发的连接而且应该不会让数据库负载达到峰值,起码不会再出现这种情况吧?又不实际的执行什么东西。(我这么觉得) |
17
GTim 2016-03-10 07:04:38 +08:00
好奇多大的并发量,不然讨论没意义啊
|
18
sujin190 OP @cevincheung 正常其实压力不大,高峰突然停机重启才会出现这种情况
|
22
sujin190 OP @scys aiomysql 遇到的问题还是一样的啊,并发高了之后, tornado 不会拒绝请求,当超过连接池最大链接数后,大量的请求都会阻塞在从连接池获取连接那,最后几乎所以得请求等待连接的时间就超过了请求超时时间, nginx 超时断开连接但 tornado 查询数据库请求却并未取消,客户端如果有重试的话,等待从连接池或取连接的请求会越来越多,最后几乎所有请求都会超时的,除非 tornado 内存爆了,否则是不会出现访问拒绝的
|
23
ethego 2016-03-10 09:51:51 +08:00
来几台主从,读写分离
|
24
AlexaZhou 2016-03-10 10:27:30 +08:00
支持,分析的很到位
有没有一种办法可以在 Nginx 返回 504 时,通知 Tornado 把正在进行的查询取消掉呢 |
25
zeayes 2016-03-10 10:58:55 +08:00
可以通过 ioloop 里面的_handlers 数量做下简单的过载保护。
|
26
tabris17 2016-03-10 11:16:05 +08:00
所以要用连接池中间件啊,另外这也属于配置不当吧
|
27
micyng 2016-03-10 12:23:31 +08:00 via iPhone
tornado 本来就不合适做这种同步 io 的事情
原理都不清楚就断言是坑 |
33
lecher 2016-03-10 12:54:15 +08:00 via Android
400 并发查询繁忙这个事情算是开发的时候数据管理的坑了,互联网项目为了性能,通常是在数据库存冗余数据,交给数据库的语句最好都是单表查询。
要完全填掉这个坑,估计要改一下数据库的字段和查询语句,尽可能让执行的 SQL 语句实现单表查询,简单的 join 宁愿分成两步先取 ID 再去另一个表作 where in 。把数据库的处理提高一个量级,能支持到 4000 每秒,就没有这些事了。 临时解决方案也得是加个内存缓存,先把复杂查询的结果都缓存一下。数据库做读写分离将数据库拆成主从结构也可以提高几倍查询性能。 应急就是加配置加机器了,但是 SQL 处理上不去是硬伤。 |
35
sujin190 OP @lecher 恩,但同时不管提高 mysql 查询性能到多少,总有可能瞬间并发超过的可能,所以应用层能提供一个当严重超负载时快速失败的策略还是必须的
|
36
zhicheng 2016-03-10 14:41:18 +08:00
跟 tornado 没什么关系。跟不阻塞更没有关系了,有关系的是你的客户端实现。
“网络异常后,客户端一直在重试,网络正常后,瞬间过来的并发高了十几倍” 阻塞模型雪崩得更快,如果不能保证客户端的实现,那至少在 nginx 上开一个 rate limit 的插件。 |