遅い SQL ガバナンスの経験の概要




過去 2 年間、私たちのチームはタオバオ テクノロジーの遅い SQL ガバナンスを担当してきました。水平的なデータ セキュリティ ガバナンス プラットフォームとして、部門内のすべてのアプリケーションの遅い SQL を迅速かつ正確に発見し、効果的にガバナンスを促進する方法、同時に、複数の開発環境と実稼働環境をカバーすることは大きな課題です。以下は経験の共有であり、継続的な低速 SQL を通じてガバナンスを推進し、DB 関連のオンライン問題を効果的に軽減し、システムの安定性を大幅に向上させます。


遅いSQLについて

同グループの遅い SQL の定義は、1 秒を超えて実行される SQL が遅い SQL であるということです。

SQL が遅いと、実行時間が長いため、次のような問題が発生します。
  1. システムの応答時間が遅くなり、ユーザー エクスペリエンスに影響を与える
  2. リソース使用量の増加によりシステムの負荷が増加し、他のリクエストの応答時間にも影響が出る可能性があります。
  3. 遅い SQL はデータベース接続の占有に時間がかかり、同時に大量の遅い SQL クエリを実行すると、データベース接続プール内のすべての接続が占有され、データ接続が切断されるなどの問題が発生する可能性があります。プールがいっぱいになり、バッファ オーバーフローが発生し、データベースが他のリクエストに応答できなくなります。
  4. また、ロックの競合の増加やデータの不整合などの問題が発生する可能性もあります。

システムの安定性を確保するには、遅い SQL をタイムリーに検出して最適化することが非常に重要であることがわかります。


SQL の導入がいかに遅かったか

SQL が遅い原因は数多く考えられますが、一般的な理由をいくつか次に示します。
  1. インデックスが不足している、またはインデックスが有効になっていない場合、データベースの全テーブル スキャンが行われ、その結果、大量の IO 消費と SQL の速度低下が発生します。
  2. 1 つのテーブル内のデータ量が多すぎると、インデックス作成の効果が十分に明らかではなくなります。
  3. 結合やサブクエリが多すぎる、要素が多すぎるなど、不適切に作成された SQL ステートメント、ディープ ページングの問題の制限、ファイルの並べ替えによる順序付け、一時テーブルを使用したグループ化など。
  4. データベースは「ダーティ ページ」をフラッシュしており、REDO ログがいっぱいになっているため、すべてのシステム更新がブロックされ、書き込みできなくなります。
  5. SQL の実行時にテーブル ロックまたは行ロックが発生した場合、ロックが解放されるまで待つことしかできないため、SQL が遅くなります。


遅い SQL と高リスク SQL を検出する方法


  遅い SQL を


実行に 1 秒以上かかることが多い遅い SQL は、本当に遅い SQL です。Alibaba Group は、TDDL を介してデータベースに接続するなど、アプリケーションの遅い SQL を簡単に取得するためのさまざまな方法を提供しています。TDDL は、遅い SQL ログをマシンの tddl- に均一に記録します。遅い.log ファイル。中間。グループの内部データベース サービス センターは、関連する低速 SQL データ クエリのレコードとインターフェイスも提供します。

对于外部用户,可以在数据库配置中启用慢查询日志功能,数据库会将执行时间超过一定阈值的慢SQL语句记录到日志中,也可以方便地获取慢查询日志。或者使用其他的数据库性能监控工具、SQL性能分析工具等。


  发现全量SQL


除了执行时长超过1s的慢SQL之外,我们还额外关注了未来可能劣化的慢SQL,这样就需要获取全量SQL,再对其进行分析,筛选出其中风险较大的SQL。我们采取了如下方法:


  • 基于JVM Sandbox进行SQL流水记录的采集


关于JVM Sandbox:「JVM-Sandbox提供动态增强你所指定的类,获取你想要的参数和行信息;提供动态可插拔容器,管理基于JVM-Sandbox的模块。」


简单来说,JVM Sandbox可以动态地将你要实现的代码模板打包编织到目标代码中,实现事件的监听、切入与代码增强。将目标代码的Java方法的调用分解为BEFORE、RETURN和THROWS三个环节,由此在三个环节上引申出对应环节的事件探测和流程控制机制。不仅如此,还有Line事件,可以完成代码行的记录。


// BEFORE-EVENTtry {    /*    * do something...    */
//LINE-EVENT
a();
// RETURN-EVENT return;
} catch (Throwable cause) { // THROWS-EVENT}


jvm-sandbox-repeater是JVM-sandbox生态体系下的重要模块,具备了JVM-Sandbox所有特点, 封装请求录制/回放基础协议,也提供了通用可拓展的丰富API。


repeator模块可以无侵入式地录制HTTP/Java/Dubbo入参/返回值,业务系统无感知。基于这个能力,我们可以方便的采集和SQL执行相关的Java方法参数以及返回值。通过配置采集点,来采集执行sql的java代码的相关方法、参数和返回值,辅助实现sql采集功能。


jvm-sandbox-repeater 地址:https://github.com/alibaba/jvm-sandbox-repeater?spm=ata.21736010.0.0.3e5975362i3rJi

  • 确认采集点


根据对MyBatis源码分析,我们确认了如下采集点:


JVMSandbox完成数据采集后,通过发送metaq消息的方式,与系统进行对话。对于不同种类的采集消息,我们通过不同的字段加以匹配,最终可以获得每一条SQL流水对应的SQL文本、执行时长、sql参数、db名称、ip端口、sql_mapper资源文件等全部信息,具体如图所示:


以上可以采集到应用的全部SQL,量级是很大的。我们采用了Blink创建时间窗口,进行数据聚合,实时数据处理,减少回流的在线数据量,在此就不展开说明了。


  如何识别高危SQL


根据历史慢SQL治理经验,我们把高危SQL分为以下几类:

  1. 不符合集团SQL规约的SQL,可能会埋坑,造成线上问题,影响执行效率等。

  2. 通过对SQL语句分析,发现SQL索引使用不当、造成全表扫描,或者SQL扫描行数过多、出现文件排序等。这种SQL即使当前不是慢SQL,随着表数据量的膨胀,未来也可能发展为慢SQL。

  3. SQL执行时间过长,比较容易理解。对慢SQL来说,执行时间越长,风险越高。


  • SQL规约


集团重点强制SQL规约如下:

  1. 【强制】不要使用count(列名)或count(常量)来替代count(*),count(*)就是SQL92定义的标准统计行数的语法,跟数据库无关,跟NULL和非NULL无关。

  2. 【强制】count(distinct col) 计算该列除NULL之外的不重复数量。注意 count(distinct col1, col2) 如果其中一列全为NULL,那么即使另一列有不同的值,也返回为0。

  3. 【强制】当某一列的值全是NULL时,count(col)的返回结果为0,但sum(col)的返回结果为NULL,因此使用sum()时需注意NPE问题。

  4. 【强制】使用ISNULL()来判断是否为NULL值。

  5. 【强制】对于数据库中表记录的查询和变更,只要涉及多个表,都需要在列名前加表的别名(或表名)进行限定。

  6. 【强制】在代码中写分页查询逻辑时,若count为0应直接返回,避免执行后面的分页语句。

  7. 【强制】不得使用外键与级联,一切外键概念必须在应用层解决。

  8. 【强制】禁止使用存储过程,存储过程难以调试和扩展,更没有移植性。

  9. 【强制】IDB数据订正(特别是删除或修改记录操作)时,要先select,避免出现误删除,确认无误才能提交执行。


我们使用了Druid SQL Parser进行SQL解析,Druid SQL Parser是阿里巴巴的开源项目,可以将SQL语句解析为语法树,可以解析SQL的各个部分,如SELECT语句、FROM语、WHERE语句等,并且可以方便获取SQL语句的结构信息,如表名、列名、操作符等。通过分析SQL,可以轻松判断SQL是否符合规约。


  • SQL索引


SQL explain语句可以提供关于SQL查询执行的详细信息和执行计划,并且可以了解sql的索引使用情 况以及数据访问方式。通过使用Explain语句,可以了解SQL是如何执行的,并且可以看出其可能存在的性能问题。

一个常见的返回结果示例如下:

返回结果解析:


我们重点关注的点如下:

  1. 使用全表扫描,性能最差,即type="ALL"

  2. 扫描行数过多,即rows>阈值

  3. 查询时使用了排序操作,也比较耗时,即Extra包含"Using filesort"

  4. 索引类型为index,代表全盘扫描了索引的数据,Extra信息为Using where,代表要搜索的列没有被索引覆盖,需要回表,性能较差。


以上几点都可能造成SQL性能的劣化,是我们需要额外关注的高风险sql。


如何推动治理慢SQL


作为横向的数据安全治理团队,为了对大淘宝技术部门进行慢SQL治理,我们建立了统一的问题发现-追踪-治理机制。慢SQL治理中涵盖了生产环境、开发环境的慢SQL,区别在于:生产环境中为已经上线的存量慢SQL,开发环境中为新引入的慢SQL,对开发环境引入的慢SQL,修复代价要小于生产环境。接下来分别介绍。


  存量慢SQL治理


存量慢SQL治理的难点在于,历史遗留下的慢SQL可能量级很大,所以要区分慢SQL治理的优先级。我们制定了健康分机制,对SQL分批分级治理。


对慢SQL来说,健康分主要受SQL的执行次数、扫描行数、执行时长影响。另外根据应用中包含慢SQL的数量、平均SQL执行数据等,给应用打出健康分。再根据部门维度汇总,根据应用等级、应用健康分情况等,计算出部门维度的健康分。

整体流程大致如下:


在慢SQL推动治理方面,高危慢SQL,会建立Issue持续追踪,Issue存在超期时间,超期后会影响团队健康分。另外,提供应用维度、部门维度的整体慢SQL风险大盘以及排名,针对重点业务、慢SQL高发团队等,进行集中的推进治理。


  增量慢SQL治理


我们希望增量慢SQL能在上线前得到解决,即分支内不要引入慢SQL或者风险SQL,所以结合3.2和3.3,我们建立了开发环境下增量慢SQL发现机制,并建立发布前卡点能力。整体流程如下:


增量慢SQL的修复代价是小于存量慢SQL的,因此这里我们添加了分支定位的能力。同一应用存在多个同学共同开发的情况,有效的分支定位,可以准确指派慢SQL引入人,实现快速推动治理。这里以git上代码改动为切入点,完成了引入慢SQL的sql_map与修改人之间的关系映射,大致逻辑如下:

a. 监听应用部署消息

b. 获取应用信息,拿到git地址

c. 将本次部署分支与master分支做分支diff

d. 解析sql_map文件,获取本次修改的sql内容

e. 记录被修改sql_id与分支的对应关系

f. 根据sql_id查询对应分支

……


这样就可以精准匹配到增量SQL的引入分支,从而指派到开发者,实现了定向问题指派和追踪,并且可以方便完成分支发布前的管控能力。如果存在增量慢SQL,分支发布,合并到master之前,会触发卡点,需要问题解决才能发布。


  安全生产环境慢SQL治理


安全生产环境(SPE环境),是集团层面为保障线上稳定性的灰度流量生产环境,安全生产环境执行过的慢SQL,在线上流量放大后,可能会对DB造成过大的压力。我们额外新增了安全生产环境慢SQL的管控,作为开发环境下SQL被引入到线上的最后一道防线。


整体方案与上面慢SQL治理方案类似,在此就不赘述了。


总结

慢SQL可能引起很严重的系统性能问题,影响系统可用性和稳定性,因此,及时发现和治理慢SQL是十分重要的。我们建了一套完整的慢SQL发现-分析-推动治理的机制,极大减少了由慢SQL引发的系统问题。同时,在db稳定性上,我们还额外关注数据库CPU使用情况、活跃会话数情况等,建立及时的风险预警和快恢机制,第一时间解决数据库风险。


团队介绍


营销与平台策略技术团队是淘天集团的核心部门之一,负责淘天集团核心用户产品——搜索、拍立淘,并支撑双11、618、年货节等大型活动,百亿补贴、淘宝好价、聚划算等营销产品。通过优惠券、跨店满减、直降、会员卡等多种营销工具的创新和沉淀,基于商品的搜索引擎建设对搜索产品的探索,招商、选品、搭建、投放的活动支撑链路的建设,以平台化、数据化、智能算法等方式支撑了以大淘宝为主的集团核心平台营销场景,全力为淘宝天猫打造有乐趣的购物体验。在这里可以接触到最前沿的人工智能产品和大数据开发体系,在数据和创新驱动下,为数亿用户提供优质服务。
若你对我们的工作内容感兴趣,欢迎加入挑战,简历(研发、前端、测开)投递邮箱:[email protected]




本文分享自微信公众号 - 大淘宝技术(AlibabaMTT)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

JetBrains 发布 Rust IDE:RustRover Java 21 / JDK 21 (LTS) GA 中国这么多 Java 开发者,应该诞生出生态级应用开发框架 .NET 8 性能大幅提升,比 .NET 7 遥遥领先 PostgreSQL 16 发布 Rust 团队前成员深感后悔,要求取消挂名,昨日完成移除 前端新轮子 Nue JS,作者称要打造全新的 Web 生态 网易伏羲回应员工“因 BUG 被 HR 威胁”离世 任正非:我们即将进入第四次工业革命、苹果是华为的老师 Vercel 新产品 "v0":根据文本生成 UI 界面代码
{{o.name}}
{{m.name}}

おすすめ

転載: my.oschina.net/u/4662964/blog/10112099