美文网首页
阿里云企业级互联网架构实践系列(3)

阿里云企业级互联网架构实践系列(3)

作者: 技术与健康 | 来源:发表于2020-08-06 09:26 被阅读0次

    一、产品概述

    二、使用需知

    § DRDS的异构索引的原理是什么? 通过将同一份数据按照业务的使用场景进行冗余 ,然后根据不同的使用场景,进行不同纬度的切分,保持使用纬度和切分纬度的统一 ,大大提升分布式数据库在复杂业务场景下的仍旧可以保持高性能的服务能力。

    § DRDS的内部各工作模块(解析器、优化器、执行器及配置变更等)的运行原理? 前端网络通讯框架:对外提供了虚拟MySQL通信接口。 MySQL协议处理层:解析MySQL调用请求,转换为内部识别的SQL指令;同时对SQL返回值进行处理组装并向上返回。 SQL处理引擎:DRDS核心模块,用来分析SQL语义结合分库分表等规则,合理拆分和优化SQL语句,下发到各库执行,并将返回数据进行整理和合并。 管理命令:为方便用户使用和维护DRDS ,DRDS 提供自己特有的辅助语句。

    § DRDS扩容时,应用是否需要停服?过程细节? DRDS 扩容流程分为 配置>迁移>切换>清理 四个步骤。具体请参考扩容操作文档。 在扩容前请注意以下事项: 源 RDS 实例扩容过程中会有读压力,请尽量在源 RDS 低负载时操作。 扩容期间请勿在控制台提交 DDL 任务或连接 DRDS 直接执行 DDL SQL,否则会导致扩容任务失败。 扩容需要源库表中有主键,如果没有需要事先加好主键。 扩容的切换动作会将读写流量切换到新增的 RDS 上,切换过程大约持续3~5分钟,建议在停业务的情况下进行切换。 在执行切换前,扩容动作不会对 DRDS 产生任何影响。因此在切换前都可以通过回滚来放弃本次扩容。 扩容操作对数据库有一定压力,建议在业务低谷期操作。

    § DRDS多个的逻辑库若都使用同一个RDS实例, 若给该RDS添加只读实例时,是否所有的逻辑库的读扩展能力都能生效? 读写比例在容量管理页面是以 RDS 实例为单位设置的。如果一个 DRDS 数据库含有多个 RDS 实例,则需要针对每个 RDS 实例设置读写比例。

    § 在DRDS上怎样才能将线上的单表变为分库分表,而又不影响在线服务?过程能否自动化? 不支持 选择新的分库键并重新建表; 然后将原表的数据进行导入。 § 在DRDS上怎样才能将线上分库分表的分库分表键进行更换,而又不影响在线服务?过程能否自动化? 对于已经被建好的分库分表,DRDS 不支持变更它们的拆分键。如果确实有需要变更表的拆分键,可以采用以下的临时办法: 选择新的分库键并重新建表; 然后将原表的数据进行导入。

    § 业务场景要求,DRDS中两张分库分表的大表要做Join,应该如何做? 在 DRDS 层的 JOIN 计算中,大多数情况下采用的 JOIN 算法都是 Nested Loop 及其派生算法 (若 JOIN 有排序要求,则使用 Sort Merge 算法)。 采用 Nested Loop 算法时,如果 JOIN 中左表的数据量越少, 那么 DRDS 对右表做查询的次数就越少,如果右表上建有索引或者表中的数据量也很少, 则 JOIN 的速度会更快。 因此,在 DRDS 中,分布式 JOIN 的左表被称为驱动表, 对分布式 JOIN 的优化应将小表作为驱动表,且让驱动表带有尽可能多的过滤条件 SQL最佳实践 做小表,如果不能从应用端优化

    § DRDS是否支持用户自定义拆分函数? 不支持

    § 用户应该怎么选择决定应用是否该要分库以及如何选择分多少表? DRDS 中的水平拆分有两个层次:分库和分表。每个 RDS 实例上默认会创建8个物理分库,每个物理分库上可以创建一个或多个物理分表。分表数通常也被称为分片数。

    一般情况下,建议单个物理分表的容量不超过500万行数据。通常可以预估1到2年的数据增长量,用估算出的总数据量除以总的物理分库数,再除以建议的最大数据量500万,即可得出每个物理分库上需要创建的物理分表数: 物理分库上的物理分表数 = 向上取整(估算的总数据量 / (RDS 实例数 * 8) / 5,000,000)

    § DRDS能否支持同时使用多个拆分字段进行表的拆分? 目前可同时支持使用两个拆分字段

    **§ Rtools组件的作用是什么,Diamond组件的作用?********* Rtools 提供drds与物理库的配置管理,主备切换,数据备份、复制等功能。 Diamond:主要元数据的存储服务,是一种可靠的配置中心,配置发生变更后能够动态推动到所有 DRDS 服务节点。用于存储 DRDS 元数据信息,元信息包括 DRDS 下挂载的 MySQL 信息和分库分表路由信息。

    § DRDS的执行计划怎么查看?怎么解读? explain:返回三个字段 GROUP_NAME:DRDS 分库的名字,可以根据后缀识别出是哪个分库,其值与 SHOW NODE 指令的结果一致。 SQL:在该分库上执行的 SQL 语句。 PARAMS:当 DRDS 使用 Prepare 协议与 MySQL 通信时,SQL 语句的参数列表。 explain detail: SQL 字段内容中的 executeOn 表示下推的 SQL 语句在哪个分库上执行 explain execute: 通MySQL的explain。

    § Show Slow与控制台的慢SQL信息是否完全一致? 一致

    § Manager与Prectrl的功能如何区分? DRDS的后台控制系统,提供后台级的实例管理、库管理、监控、库存、VIP、域名、升降配等功能。DRDS Manager为Prectrl等系统提供API,并为DRDS Server提供部分元数据信息。 prectrl用户控制台,提供用户层面的实例管理、库管理、监控、扩容缩容等功能。功能主要以调用DRDS Manager API实现。提供给普通用户使用。 简单理解Manager为整个DRDS系统的管理控制台,只有系统管理员才有权操作;而Prectrl是面向普通租户、用户操作DRDS的控制台。

    § DRDS是否支持指定用户权限?权限是什么级别? 支持,提供库基表和表级别的用户权限,支持和表相关联的8个基本权限项:CREATE、DROP、ALTER、INDEX、INSERT、DELETE、UPDATE、SELECT https://help.aliyun.com/document_detail/50890.html?spm=5176.doc50067.6.569.Q9cBgb

    § 怎样区分一条DRDS中SQL来源于哪个客户机器IP?来源于哪个登录帐户? 首先确认查询SQL的目的是什么? 如果是为了查询慢sql,可以使用show sql,在返回结果中记录了每一条慢SQL的来源的地址,用户执行信息,同时也可以登录到drds-server上查看慢sql日志,slow.log。 另外drds也会为记录逻辑库的SQL语句到sql.log中,可以中日志中回去到hostip,port和schema等信息。

    § DRDS的Trace与Explain的异同及作用? 区别: DRDS 中的 TRACE 指令可以跟踪 SQL 的执行过程和各个阶段的执行开销。Time_Cost 字段。 TRACE SQL 和 EXPLAIN SQL 的区别在于 TRACE SQL 会实际执行该语句。 § DRDS是否有全SQL的审计功能?

    DRDS不支持。

    三、常见问题

    1.问题: DRDS页面中有个库一直删除失败

    结论:hidas接口没调通,不是删库删不掉,是管控平台的元数据没删,不会占用mysql的资源,不影响使用

    2. 问题:能否将表建在指定分库中,(现有业务组建表不指定分库键,默认数据在0号分库下,考虑到数据达到瓶颈,能否在2号分库上继续建表) 结论:不应这样使用,应该在建表之前就应该采用分库表或者分库分表的方法创建

    3. 问题:一个8分库的DRDS中,使用普通表语句创建的表为何依然在8个分库中创建了相同的表,且只有0000号库中的表才有数据,其他分库中的表没有数据 结论:单表在所有分库中创建表,只有0000号库中有数据,其他库中的表没有作用,不影响使用

    4. 问题:数据库扩容时不能选0号分库

      结论: 0号分库里面都是元数据,不能选
    

    5. 问题:修改表属性的语句时间显示很差,实际上只用了0.18秒,慢sql查出来的sql执行时间比实际大很多 结论:1. 用show trace查询看下,结果是空的 2. show slow只会记录执行的sql超过1秒的,如果show slow 显示有这条sql很慢,就可以查下执行计划,看看原因

    6. 问题:创建一张分库表,在DRDS中指定分库读表数据,结果是全数据,如select * from kd_tsd_zaxt_0000.role 结论:DRDS不支持MySQL的分库查询语法,官网文档上没有说明,但可以使用扩展语法指定节点Hint

    7. 问题:drds是否支持多个外键 结论:不支持

    8. 问题:DRDS的一张表中插入5000万数据后打不开了,dc_charging_monitoring_data_up

      定位:1\. 指定where条件少查一些数据 ==>还是报ERROR1146....Table'mysql1_bbnl_0000.dc_charging_monitoring_data_up_1' doesn't exsit, More[...TDDL_4614] 
    

    2. 看下Mysql是否正常 ==> 正常 3. 指定条件查查,比如where语句加上分库分表键 ==>找dc_charging_monitoring_data_up_1这张表进行查询了? 4. 表已做分库分表但控制台显示不对,是桩id分库,时间分表 5. 那原因可能是当时建表没有建完整,后续导数据部分数据没有导进去 ==> 导入数据成功后重DRDS看到5000万数据, select count(*) 6. 什么是否插入的数据,插入数据时间为多长 ==>周六插的5000万条数据,周一插入数据时发现打不开了 7. dc_charging_monitoring_data_up每个分库有0-4,5张分表但分表1不存在了 8. 需要登陆到这个 192.168.100.18:3303 MySQL 实例上看 binglog 日志, 是否有单独针对 mysql 的 drop 操作,DRDS 这边不会主动去删表的。如果没有认为的去 mysql 上删表,那么怀疑是部署的 MySQL 自身的问题。 9. 本来库里有这样的一张分库分表dc_charging_monitoring_data_up, 后来创建一张测试表叫dc_charging_monitoring_data_up_1, 今天早上将dc_charging_monitoring_data_up_1删了,是否对dc_charging_monitoring_data_up有何影响 10. 因为DRDS要同时支持表拆分和表不拆分(即单库单表),当同一数据库里拆分的某个分表与没拆分的单表重名,DRDS目前是区分不不出来的,所以尽量避免不必要的重名即可。

    结论:操作Drop XXXX_1表的时候,把不带1的那个分库分表的0库上的子表给删除了。避免创建XXXX_1 这样的表              9. 问题:还有这个drds控制台分库管理信息加载,总是超时      结论:连接到分库上的时候报了连接不足,是到后端 mysql 的连接数达到了最大值,mysql 的系统参数,得调整 mysql 实例后重启                [https://dev.mysql.com/doc/refman/5.5/en/too-many-connections.html](https://dev.mysql.com/doc/refman/5.5/en/too-many-connections.html)      10\. 问题:创建了昨天问题表一模一样的表.改了个名字.第一次写入10W条数据,都正常写入,然后delete,清除表中数据后再往里写入.                   就报java.sql.SQLException: [b9499b3b7800001-b][172.169.101.107:3306][mysql1]ERR-CODE: [TDDL-4603][ERR_ACCROSS_DB_TRANSACTION] Transaction accross db is not supported in current transaction policy,
    
                 transaction node is: MYSQL1_1492148880444FVJAMYSQL1_BBNL_0002_RDS, but this sql execute on: MYSQL1_1492148880444FVJAMYSQL1_BBNL_0001_RDS. More: [[http://middleware.alibaba-inc.com/faq/faqByFaqCode.html?faqCode=TDDL-4603](http://middleware.alibaba-inc.com/faq/faqByFaqCode.html?faqCode=TDDL-4603)]                   再写入20W条数据,其中199725条写入成功,请他的数据都报这个错误,然我我把表drop掉,重新创建,再写入10W条.又是正常的了.重复上述操作,部分数据还会报上述错误        定位:1\. 创建了wjd_test表;现在又无法drop了,ERR-CODE:[TDDL-4614][ERR_EXECUTE_ON_MYSQL] Error occurs when execute on GROUP ""                   2\. 创建这张表是用来性能测试的.清空了几次表,然后删除就报这个错。其中百分之90+的数据都插入成功.其他数据都报这个错                   3\. 可能是因为磁盘空间不足原因,导致DRDS做这个DDL失败了。检查一下 109 的机器 的磁盘空间是不是已经满了? 看看 /home/admin/logs 目录的占用空间                   4\. 可以先将109机器的DRDS重启,这样可以先恢复,原因慢慢查                   5\. DRDS异常堆栈  /home/admin/drds-server/3306/llogs/ xxx_dbname/tddl.log                   6\. 101.107磁盘确实超过了12G。图, /root/logs/txc日志占了6.6G磁盘,是否可以清除        结论:DRDS_server 的磁盘空间满了,导致DRDS的DDL失败。
    

    11. 问题:创建的分库分表,在DRDS里显示却是单表 结论:drds-console 显示问题

    12. 问题:DRDS数据库支持改表名,修改表名事报这个错误Can't RENAME shard table name to: ID:sunweiwei 结论:不支持

    13. 问题:DRDS是否支持对分库分表修改表结构 结论:支持

    14. 问题:select * from dc_charging_monitoring_data_up_1 limit 3; ERR-CODE:[TDDL-4007] ....Table'mysql1_bbnl_0000.dc_charging_monitoring_data_up_1' doesn't exsit, More[...TDDL_4007] 结论:结论同问题8,原因相同 15. 问题:Too many connection. More [...TDDL-4102] 结论:1. 这个RDS上连接不足报的错,可以改DRDS与RDS的连接池配置 2. 这边做过一次调优,MySql的max_connections 是20000 3. 登录drds-manager → 控制模块 -> DB配置管理 通过DRDS的实例ID与dbName查询该db 对应的appName(配置的唯一ID) -> 修改 appConfig DRDS 实例后端连接池的最大连接数 = 向下取整( RDS 实例最大连接数(现在是20000)/ RDS 实例物理分库数(目前是8) / DRDS 实例节点数(机器数目) ) 只允许DRDS用 6成的RDSl链接: (20000/8/2) * 0.6

    1. 问题:ERR-CODE:[TDDL-2601][ERR_EXECUTOR] ERR-CODE:[TDDL-4201][ERR_GROUP_NO_ATOM_AVALABLE]


      定位:1. 查看下数据库下的读写比例设置是否正常? 2. 单独执行show table status like 'sign' 3. check table sign有时报错,有时成功 , 结论: 备库挂了,重启MySQL

    17. 问题:使用mysqldump导入xxx.sql文件的时候报ERR-CODE:[TDDL-4108]

    结论:xxx.sql中的/*!401xx SET ...... /注释导致xxx.sql文件导入失败,使用sed -i‘/^/*!401 /d’ xxx.sql 处理下

    18. 问题:ERR-CODE:[TDDL-4102][ERR_ATOM_GET_CONNECTION_FAILED_KOWN_REASON]get connection for db 'XXXXX' failed because com.mysql.jdbc.excetions.jdbc4.MySQLNonTransientConnectionException: Too many connections....

      定位:1.show DataSources;看下各个分库的最大连接数;
    
               2\. 在manger上看到qps不高,最多才45,而后端到MySQL的连接已使用完。
    
     结论:不通于问题15\. 无论连接数调maxpoolsize整到多大,都是会爆满,请检查测试用例case和应用端,在sql语句提交完后及时释放connection。在使用事务时,设置了setAutoCommit(false),如果后面任意一掉sql语句出现异常,需要在处理异常中调用conn.rollback(),
    
              conn.close()是不会断开连接的。
    

    19. 问题:DRDS实例连接不上:ERROR 2013 (HY000): Lost connection to sgrdb server at 'reading authorization packet', system error: 2

     定位:1\. 登录到出问题的drds-server容器,查看3306端口的监听进程(drds-server是否还活着) netstat nap | grep 3306,/home/admin/drdsserver/bin下是否有tddl-3306.pid
    
              2\. 查看3306/logs/tddl.log日志,日志中显示[ERROR] com.alibaba.cobar.server.statistics.StatsRpcClient - [] Java heap space java.lang.OurOfMemoryError: Java heap space;
    
              3\. cat drds/bin/tddl_3306.pid 可以看到内存情况;
    
     结论: 使用的是2c4g的server,配置太低,是生产环境同时又在进行事务压测,内存不够用了,建议升级规格。
    

    20. 问题: 在事务内 insert into wp values(2,1); 报ERROR 3009(HY000),错误但可以插入成功;

     结论:GTS对SQL的兼容性有一定的限制,要求insert必须带有列名,不加列名GTS会损失一些性能,不指定列名是不太好的实践,但后续版本会兼容这种方式。
    

    21. drds暂不支持用户自定义数据类型、自定义函数。暂不支持视图、存储过程、触发器、游标、暂不支持类似if、while等控制类语句。暂不支持begin...end, loop...end loop, repeat...until..end repeat, while...do...end while等复合语句。

    22. 扩容后执行show full stats,报[Err]2009错误。

      结论:此版本的bug,只会影响此指令,如何修复:登录到drds-server,修改脚本/home/admin/drds-server/bin/startup.sh →export LD_LIBRARY_PATH=../lib/native,重启docker容器。
    

    23. select * from update {table} set {column} = ? limit 10; drds不支持这种语法。

    24. drds 出现大量[TDDL-4614][ERR_EXECUTE_ON_MYSQL]Error occurs when execute on GROUP '.....'Failed to initialize atom datasource in lazyInit mode!.....

      结论:DRDS的初始化与RDS连结束是40,8*8*40=2560,RDS的连接数爆满了。初始连接数是40(之前调查问题调整了的),prefill参数又设置了true;
    

    四、事务相关:

    1. 问题:上海环境0号库,500并发,4个活跃连接数;没有压力是单条sql语句是5ms,压力上来后,有些sql执行时间是,0.5s 结论:?

    2. 问题:更新A,B,C三个表,其中A表不是分库表,B,C是分库表,更新完A表后select last_txc_xid(), 然后再更新B,C。这样的话会在select last_txc_xid()的时候把A的更新先提交,可以不可以不让A提交? 讨论:1. 不可以,drds在执行select last_txc_xid()的时候会先执行set autocommit=true,setautocommit=false。 ** 2. 为什么不发A放在事务中呢,因为A是是必须执行的,BC不是必然执行的** 结论:既然A与B,C不是必然关系,在应用上去做逻辑判断。

    3. select count() from acct_account_base where 1=1 and EXISTS(SELECT 1 from cus_user c where c.id=acct_account_base.user_id and c.user_type= '1') 报err-code 4501* 讨论:1. 改正inner join的方式,但性能比较低,acct_account_base是分库表,cus_user为分库。select count() from acct_account_base inner join cus_user c on c.id = acct_account_base .userid where c.user_type='1';* ** 2. cus_user 返回的数据也比较多** 结论:在acct_account_base表加上冗余字段 user_type,变成单表查询。

    4. 100个线程TPS只能泡到400左右,不跑GTS时TPS时4500。 讨论:基本上TPS时在不跑GTS时的40%~85%之间,是不是有严重的数据冲突?一套GTS的的tps应该是3000,可以线性扩展。 ** 改了下测试程序,10个连接,1400TPS(DRDS是4000QPS),加到1200连接后只有3000的QPS了。** ** 建议对比下使用GTS前后的QPS,如果发现前后数据差别不到,使用Wireshark抓下包。** ** 测出来结果:不带GTS的QPS还不如使用GTS的结果。** ** 测试改了下测试代码,不使用GTS的时候DRDS的qps能打50000,加上GTS之后DRDS的QPS在10000左右。怀疑是block在txc打日志的地方,可以降级日志。** ** 日志降级后,QPS到12000,tps从3200到4000了。drds-server的CPU达到80%-90%了,性能达到瓶颈,是否还有可以优化的空间?** 结论:drds性能瓶颈,需要扩容。

    5. table drop不掉,报ERR-CODE:[TDDL-4990][ERR_OTHER]lock conflict, maybe LAST DDL is still running More:..... 讨论:使用show processlist/kill 杀掉 线程有没有用。 ** 使用release dblock;释放锁。命令不管用。** ** 使用替代方案,show **DRDSSYSTEM_LOCK ** 使用hint一个个删除/tddl:node=?/drop table xxxxx;但建表的时候还是报错,可以再次执行drop table xxxx。**

    6. 用scan删20万数据大概需要11分钟,是否有并行的方法。 结论:/!tddl:scan and merge_concurrent=true/,生产环境慎用,容易导致CPU过高。*

    7. rds中可以通过show engin innodb status 查看死锁。

    相关文章

      网友评论

          本文标题:阿里云企业级互联网架构实践系列(3)

          本文链接:https://www.haomeiwen.com/subject/cgcarktx.html