当前位置:澳门网上开户聊城网站建立,网站设计制作,聊城网站推广优化,聊城微营销,聊城网站托管» 网站建立 » 聊城网站建立分享MYSQL系统阐发实战
聊城网站建立分享MYSQL系统阐发实战
宣布日期:2017-01-13 作者:澳门网上开户聊城网站建立,网站设计制作,聊城网站推广优化,聊城微营销,聊城网站托管

上班了上班了,干活了干活了。

 

那个,其实,我许多年没碰过技能了,但照旧觉得有须要把之前一些处理惩罚过的技能问题拿出来,其实每个问题,都是很小的问题,如果单独说原因和答案都非常简单,但要害是,遇到问题的思考方法和阐发要领。

 

依然是,妙手请无视,针对一些初入技能职场的童鞋,希望能对列位遇到问题时候的思考方法有所资助。

 

案例1:诡异的链接过多

 

其时情况是这样,突然有一天,数据库出现链接过多错误,导致网站报错。 熟悉mysql并操纵过高并发系统的朋友知道,数据连接过多属于很常见的问题。但其时的情况是,访问量并不在岑岭,按理说不应该有这样的问题。

 

看了一下数据库办事器的负载,很低,并不存在cpu或内存跑满的问题。

慢查询日志没有异常的SQL,更没有锁表。

 

于是就进入数据库做一下 show processlist的查询。

有些朋友可能会问,链接过多你还能看show processlist么,那个,mysql里root比普通用户多一个链接许可,所以,记得步伐切忌用root链接,保存一个给系统阐发师用。

 

意外发明,险些所有的SQL停留在sleep状态,并且许多链接都连续了好几秒,甚至十几秒。

 

这里说明一下,如果是用数据中间件链接池来操纵,从中间件到数据库存在牢固命字的sleep链接是正常的,但从步伐端到中间件,除非你是长连接,并且需要保持数据库频繁操纵的应用,不然,通常不发起数据库保持连接,也就是不应该出现太多sleep操纵。

 

我们的场景就是普通的web应用,php步伐罢了,都是短链接,按理说,步伐执行完就应该释放的,所以这个问题就有点意外。

 

虽然,这个和代码的设计也有干系,因为系统用的开源软件改写的,涉及数据库操纵照旧蛮多的,一般情况下,数据库操纵完应该实时封闭,但由于一般认为php代码执行时间很短,所以在代码架构有点庞大的情况下,许多都是默认整个步伐执行完再封闭。那么现在问题来了,到底php产生了什么问题。

 

我们去web办事器,看日志,发明访问量并没有异常,也没有针对我们的打击行为,但确实许多php步伐执行时间较长,web连接数也明显多于异常,即便是数据库重启,问题依然会重现,那么这时候,我们工程师就在最常用的php代码里设置断点,去看代码到底卡在哪个环节上执行时间很长,结果,发明是我们的一个非常重要的知识盲点。原来执行时间最长的,是在最子女码数据都执行完,输出执行 echo 的环节。

 

在本地做性能测试,压力测试的时候,我们知道echo 这种语句是根本没有开销的,也不太可能成为一种负载的来源,但这下我们明白了,echo原来不但仅是php执行输出,也包罗了网络传输的时间开销。只有客户端接收到传输内容后,echo执行才结束。

 

而那天的问题,其实是因为同机房有其他公司办事器被Ddos,导致机房出口拥堵,按理说这只是websever的问题,但因为webserver自己有轮询机制,并且设置的连接数较大,虽然访问较慢,但没有瓦解,而因为php代码里mysql链接没有实时释放,在php执行echo的时间期待较长,导致mysql链接过多瓦解。

 

知道这个问题,解决就简单了,因为开源系统封装了输出template的东西,我们就在这个东西执行的时候,先执行mysql_close(); 这样只改了一行代码,问题就解决了。

 

但厥后发明出了bug,bug的理由很无厘头,居然部分template 的伪码里有数据库操纵,但这个问题解决也简单,因为究竟这样的场景很少, 并且mysql东西也被封装了,我们就在query要领里加了一行代码,如果没有数据库连接,就重建一个。 这样,这个重建历程只出现在少少数template里有mysql操纵的场景,对整体系统根本没有性能滋扰。

 

这个案例说来挺简单,就是数据库连接没有实时释放造成的,但因为触动了一个思维盲区,所以印象深刻。

 

线上的步伐做断点日志阐发是最常用的阐发诡异问题的要领。基于断点日志阐发,我们可以通过类似二分法,逐步递进直到精确定位具体到每一行代码的执行时间开销。

 

这里还要提醒一个常见问题,线上情况许多问题是在测试情况里很难重现的,所以遇到诡异问题,应该可以在线上做一些日志阐发和代码的调试,虽然这样可能会有一定的风险,但许多公司的流程和范例,开发工程师只能在线下测试性能和压力蒙受能力,针对线上许多现实的问题没有步伐完整实测。

 

大公司可能会把测试情况做的更好更范例,以及有更有经验的工程师和阐发师来解决问题,但创业公司,我发起要给步伐员和阐发人员一些线上应急处理惩罚的权限,不然真的会束手无策,经验值都是靠出错息争决问题来积聚的。

 

案例2:看似正常的负载过高

 

其时有个新业务数据增长很快,该业务的数据库办事器每天处理惩罚数百万次数据查询请求,uptime比力高,经常在5-6的样子,cpu负荷较重,运维卖力人就发邮件,申请调换更好的办事器,增加资源。

 

按理说,这是个公道请求,负载也确实很高,业务也确实增长,但我这小我私家天性财迷抠门,总觉得这个数字不应该是极限,就登录到数据库办事器看了一下,很简单,我的要领就是先刷show processlist,连续刷几遍,看数据库都在执行啥,开销都会合在什么状态,这一看还真就发明问题了,居然经常看到有些mysql进程停留在 storing result to query cache 上。

 

这事我就纳闷了,因为按通例,这个状态应该是根本没有时间开销的,也就是show processlist看到是小概率事件的。

 

所以就要验证一下,执行 set profiling=1,然后从show processlist复制一条执行一次,然后执行 show profiles for query 1; 结果意外发明,通例来说执行开销最大的sending data (这个开销可不是输出数据哦,其实是io寻址)只有0.002秒,而 storing result to query cache 却执行了 0.005秒的样子,千分之五秒,一般人可能就无视了吧,但整个SQL执行不到0.01秒,这个开销比例蛮大的了。

 

那个,其实这个问题的责任者呢,是我自己,我觉得query cache是个好东西啊,所以开始配置办事器的时候,照旧我自己做的配置,因为办事器内存够大,我就把query cache设置的比力大,结果SQL的反馈结果内容较多的情况下,就出现了query cache的碎片化比力严重,反而导致了query cache存储特别的开销,我在数据库里直接操纵将query cache内容重置的命令,再执行这个SQL,用profiling去阐发,发明这个开销就没有了,负载瞬间显著下降了60%左右。

 

然后我跟运维卖力人说,半夜没人的时候把数据库的启动参数,query cache那块设置回默认值,重启一下数据库,于是就没再追加预算和办事器投入。

 

这个案例自己是我自己的乌龙,因为没有明确理解query cache的读取和存储逻辑,自以为是的调高了参数,在SQL返回值较大的情况下,导致了严重碎片化,带来了特别的开销,虽然每次开销都极其微小,但由于系统的请求频次非常高,所以系统不须要的负载就比力大。

 

那么这个案例里,需要分享的要领是,showprocesslist+一定的敏感度,再配适用set profiling去阐发具体的开销,是非常重要的一种阐发查询性能的要领。

 

案例3:io性能的优化案例

 

这个案例又是我的错,唉,我发明我犯的错误照旧蛮多的,不外我们工程师解决方案非常经典,所以也列在这里以供参考。

 

照旧一个非常高并发的业务场景,最开始呢,为了到达查询的最优化,数据结构照旧我设计的,使用了复合索引,确保每次查询的索引命中率极高,但这个业务场景有一个问题,就是除了查询请求很高之外,数据的插入请求根本上是同频次的。(大部分场景都是数据插入后随之查询,个别会有单独查询场景),所以插入请求巨大,数据库的io压力特别大。

 

结果我们工程师也是受到我的影响吧,抠门的很,也是尽可能在有限资源下挖潜。结果怎么做的呢? 说来简单,索引降级,把两个字段的复合索引降到单键索引了。

 

单纯从查询而言,这一降级其实是牺牲了效率,但是牺牲的并不大,但从更新而言,从复合索引降级到单键索引,索引更新的io负载就有了明显的低落,由于查询的负载开销远低于更新的负载开销,所以这一降级,在查询与更新同频的场景下,就变得效果特别好。

 

这个案例需要分享的经验是,索引的创建,不但要考虑查询的语句,更新的语句,也要考虑业务场景中相关的频次,在更新频次远低于查询频次时,和更新频次与查询频次相其时,同样的数据结构,同样的SQL语句,可能索引的设计方案会有重大的调解和改变。

 

 

 

 

Mysql也有了许多的版本迭代,许多之前遇到的问题和瓶颈也许现在已经在系统中顺畅解决,但我觉得,一些思路和要领依然值得分享。

 

虽然,这些都不是什么高峻上的技能息争决方案,都是实战中,屌丝创业团队面临一些实际问题的响应和处理惩罚能力。许多草根创业团队,其实都是栽倒类似这样的问题上的。

?