资源描述
阿里巴巴分布式数据库原理、实现和应用2012.11集团共享技术平台分布式数据库邱硕2012华东架构师大会 分布式数据库中间件App App App AppCobarOracle MySQL MySQL MySQLErosa Oracle ErosaMySQL ErosaMySQL ErosaMySQLEromanga Otter Oracle MySQL MySQLOtterErosaOracle ErosaMySQL ErosaMySQLEromanga 性 能 容 量 高 可 用 数 据 消 费 时 效 性 跨 机 房 数 据 同 步ASCDW. 分布式数据库中间件App App App AppCobarOracle MySQL MySQL MySQLErosa Oracle ErosaMySQL ErosaMySQL ErosaMySQLEromanga Oracle MySQL MySQLOtter 性能 容量 高可用 数 据 消 费 时 效 性 跨 机 房 数 据 同 步ErosaOracle ErosaMySQL ErosaMySQLEromangaOtterASCDW. 分布式数据库中间件App App App AppCobarOracle MySQL MySQL MySQL Oracle MySQL MySQL OtterErosaOracle ErosaMySQL ErosaMySQLEromanga 性 能 容 量 高 可 用 数据消费时效性 跨 机 房 数 据 同 步ErosaOracle ErosaMySQL ErosaMySQL ErosaMySQLEromanga OtterASCDW. 分布式数据库中间件App App App AppCobarOracle MySQL MySQL MySQLErosa Oracle ErosaMySQL ErosaMySQL ErosaMySQLEromanga Oracle MySQL MySQLErosaOracle ErosaMySQL ErosaMySQLEromanga 性 能 容 量 高 可 用 数 据 消 费 时 效 性 跨机房数据同步OtterASCDW. Otter 分布式数据库中间件App App App AppCobarOracle MySQL MySQL MySQLErosa Oracle ErosaMySQL ErosaMySQL ErosaMySQLEromanga Oracle MySQL MySQLOtter 性能 容量 高可用 数 据 消 费 时 效 性 跨 机 房 数 据 同 步ErosaOracle ErosaMySQL ErosaMySQLEromangaOtterASCDW. 大纲n 中间件引入n Cobar策略n 系统实现n 实施应用 Cobar之前 Oracle单点数据库 性能问题 中 文 站 offer总 数 : 2008年 1亿 - 2011年 3亿 高 峰 时 : load 30、 cpu使 用 率 90% 数据库连接过多 可用性问题 Standby切 换 故 障 成本和伸缩性问题 依 赖 高 成 本 的 硬 件 设 备 Oracle MySQL MySQL MySQLMySQL MySQL MySQLMySQL MySQL MySQL单点:MySQL集群替换OracleMySQL MySQL MySQL Oracle单点数据库 性能问题 中 文 站 offer总 数 : 08年 1亿 - 今 天 3亿 高 峰 时 : load 30、 cpu使 用 率 90% 数据库连接过多 可用性问题 Standby切 换 故 障 成本和伸缩性问题 依 赖 高 成 本 的 硬 件 设 备Cobar引入 水平拆分 ID MEMBE_ID INFO1 pavarotti17 11 pavarotti17 MySQL ID MEMBE_ID INFO4 test1234 5 test1234 ID MEMBE_ID INFO3 abcd 9 abcd 20 abcd MySQLMySQLCobarApp Oracle单点数据库 性能问题 中 文 站 offer总 数 : 08年 1亿 - 今 天 3亿 高 峰 时 : load 30、 cpu使 用 率 90% 数据库连接过多 可用性问题 Standby切 换 故 障 成本和伸缩性问题 依 赖 高 成 本 的 硬 件 设 备App ID MEMBE_ID INFO1 pavarotti17 11 pavarotti17 MySQL ID MEMBE_ID INFO4 test1234 5 test1234 ID MEMBE_ID INFO3 abcd 9 abcd 20 abcd MySQLMySQLAppAppAppAppAppAppApp Cobar引入 连接复用App ID MEMBE_ID INFO1 pavarotti17 11 pavarotti17 MySQL ID MEMBE_ID INFO4 test1234 5 test1234 ID MEMBE_ID INFO3 abcd 9 abcd 20 abcd MySQLMySQLCobarProxyAppAppAppAppAppAppApp Oracle单点数据库 性能问题 中 文 站 offer总 数 : 08年 1亿 - 今 天 3亿 高 峰 时 : load 30、 cpu使 用 率 90% 数据库连接过多 可用性问题 Standby切 换 故 障 成本和伸缩性问题 依 赖 高 成 本 的 硬 件 设 备Cobar引入 ID MEMBE_ID INFO1 pavarotti17 11 pavarotti17 MySQLCobarApp X Cobar引入 failover ID MEMBE_ID INFO1 pavarotti17 11 pavarotti17 MySQL Master1CobarApp ID MEMBE_ID INFO1 pavarotti17 11 pavarotti17 MySQL Master2X MySQLReplication Cobar引入 failover ID MEMBE_ID INFO1 pavarotti17 11 pavarotti17 CobarApp ID MEMBE_ID INFO1 pavarotti17 11 pavarotti17 MySQLReplication MySQL Master1MySQL Master2 大纲n 中间件引入n Cobar策略n 系统实现n 实施应用 Oracle MySQL MySQL MySQLMySQL MySQL MySQLMySQL MySQL MySQLMySQL MySQL MySQL拆分数据表 水平拆分ID MEMBE_ID INFO1 pavarotti17 3 abcd 4 test1234 5 test1234 9 abcd 11 pavarotti17 20 abcd 水平拆分ID MEMBE_ID INFO1 pavarotti17 3 abcd 4 test1234 5 test1234 9 abcd 11 pavarotti17 20 abcd 拆分字段 水平拆分ID MEMBE_ID INFO1 pavarotti17 3 abcd 4 test1234 5 test1234 9 abcd 11 pavarotti17 20 abcd ID MEMBE_ID INFO1 pavarotti17 4 test1234 5 test1234 11 pavarotti17 ID MEMBE_ID INFO3 abcd 9 abcd 20 abcd f(pavarotti17)=库1f(test1234)=库1f(test1234)=库1f(pavarotti17)=库1f(abcd)=库2f(abcd)=库2f(abcd)=库2库1库2拆分字段 水平拆分ID MEMBE_ID INFO1 pavarotti17 3 abcd 4 test1234 5 test1234 9 abcd 11 pavarotti17 20 abcd ID MEMBE_ID INFO1 pavarotti17 4 test1234 5 test1234 11 pavarotti17 ID MEMBE_ID INFO3 abcd 9 abcd 20 abcd f(abcd)=库2库1库2拆分字段f(pavarotti17)=库1f(test1234)=库1f(test1234)=库1f(pavarotti17)=库1f(abcd)=库2f(abcd)=库2路由算法 路由算法pavarotti17f(pavarotti17)=库1 路由算法pavarotti17部 分 截 取hash( ) = 3170972965401 路由算法hash(pavarott) = 3170972965401 % 1024 = 5370 1023 路由算法hash(pavarott) = 3170972965401 % 1024 = 5370 255 256 511 512 767 768 1023256256256256分库1 分库2 分库3 分库4 路由算法hash(pavarott) = 3170972965401 % 1024 = 5370 255 256 511 512 767 768 1023256256256256分库1 分库2 分库3 分库4 路由算法扩容hash(pavarott) = 3170972965401 % 1024 = 5370 127 128 255 256 383 384 511 512 639 640 767 768 895 896 1023128 128 128 128 128 128 128 128分库1 分库2 分库3 分库4 路由算法扩容hash(pavarott) = 3170972965401 % 1024 = 5370 127 128 255 256 383 384 511 512 639 640 767 768 895 896 1023128 128 128 128 128 128 128 128分库1 分库2 分库3 分库4 分库5 分库6 分库7 分库8 原分库1 分库2 分库3 分库4原 原 原 路由算法非均匀分布hash(pavarott) = 3170972965401 % 1024 = 5370 511 512 767 768 895 896 1023512 256 128 128分库1 分库2 分库3 分库4 拆分表的数据访问SQL转发ID MEMBE_ID INFO1 pavarotti17 4 test1234 5 test1234 11 pavarotti17 ID MEMBE_ID INFO3 abcd 9 abcd 20 abcd CobarAppselect * from tb1 where member_id=test1234 拆分表的数据访问SQL转发ID MEMBE_ID INFO1 pavarotti17 4 test1234 5 test1234 11 pavarotti17 ID MEMBE_ID INFO3 abcd 9 abcd 20 abcd CobarAppselect * from tb1 where member_id=test1234 ID MEMBE_ID INFO1 pavarotti17 4 test1234 5 test1234 11 pavarotti17 ID MEMBE_ID INFO3 abcd 9 abcd 20 abcd CobarAppSELECT * FROM tb1 WHERE member_id IN (test1234,pavarotti17,abcd)拆分表的数据访问SQL转发 ID MEMBE_ID INFO1 pavarotti17 4 test1234 5 test1234 11 pavarotti17 ID MEMBE_ID INFO3 abcd 9 abcd 20 abcd CobarAppselect * from tb1 where member_id in (test1234,pavarotti17)select * from tb1 where member_id in (abcd)拆分表的数据访问SQL转发 ID MEMBE_ID INFO1 pavarotti17 4 test1234 5 test1234 11 pavarotti17 ID MEMBE_ID INFO3 abcd 9 abcd 20 abcd ResultMerger前台通信ResultSet:row1row2ResultSet:row3row4row5ResultSet:row3row1row4row5row2拆分表的数据访问结果返回 多维水平拆分visit表productuserinfoCoca-Cola A p e p s i C Fanta D Coca-Cola A Coca-Cola C Fanta B 7Up D p e p s i A productuserinfoCoca-Cola A Coca-Cola A Coca-Cola C productuserinfop e p s i C p e p s i A productuserinfoFanta D Fanta B productuserinfo7Up D SELECT * FROM visit WHERE user=A 多维水平拆分visit表productuserinfoCoca-Cola A p e p s i C Fanta D Coca-Cola A Coca-Cola C Fanta B 7Up D p e p s i A productuserinfoCoca-Cola A Coca-Cola A p e p s i A productuserinfop e p s i C Coca-Cola C productuserinfoFanta D 7Up D productuserinfoFanta B SELECT * FROM visit WHERE product = Coca-Cola 分 库 1 分 库 2 分 库 3 分 库 4分 库 5 分 库 6 分 库 7 分 库 8分 库 9 分 库 10 分 库 11 分 库 12分 库 13 分 库 14 分 库 15 分 库 16 product值Hash取 模user值Hash取 模01230123visit表USER PRODUCT 一张表的多个字段同时作为拆分字段 Hash(“A”)%4 = 分 库 1 分 库 2 分 库 3 分 库 4分 库 5 分 库 6 分 库 7 分 库 8分 库 9 分 库 10 分 库 11 分 库 12分 库 13 分 库 14 分 库 15 分 库 16 product值Hash取 模user值Hash取 模01230123CocaColaAHash(“CocaCola”)%4 = SELECT * FROM visit WHERE product=ColaCola AND user=A 分 库 1 分 库 2 分 库 3 分 库 4分 库 5 分 库 6 分 库 7 分 库 8分 库 9 分 库 10 分 库 11 分 库 12分 库 13 分 库 14 分 库 15 分 库 16 product值Hash取 模user值Hash取 模01230123CocaColaHash(“CocaCola”)%4 = SELECT * FROM visit WHERE product=ColaCola Hash(“A”)%4 = A分 库 1 分 库 2 分 库 3 分 库 4分 库 5 分 库 6 分 库 7 分 库 8分 库 9 分 库 10 分 库 11 分 库 12分 库 13 分 库 14 分 库 15 分 库 16 product值Hash取 模user值Hash取 模01230123SELECT * FROM visit WHERE product=ColaCola AND user=A Cobar的策略 MySQL集群替代Oracle单点 基于表的水平拆分和分布 根 据 字 段 值 的 一 致 性 Hash分 布 多 维 拆 分 数据查询方式 根 据 where中 的 拆 分 字 段 分 发 SQL语句其他元素的处理 将 Cobar收 到 的 SQL语 句 做 变 换 分 发 到 各 个 分 库 执 行 对 执 行 结 果 合 并 、 处 理 保 证 返 回 前 端 的 内 容 满 足 语 义 JOIN有限的处理 跨库JOIN问题SELECT * FROM tb1 INNER JOIN tb2 ON t1.MEMBER_ID=t2.NAME ID MEMBE_ID2 zzzz4 xyzxyz ID NAME4 efghijk5 aaaa6 abcdID MEMBE_ID1 efghijk3 xxxxxx5 abcd ID NAME2 zzzz3 xyzxyztb1tb1tb2tb2ID MEMBER_ID ID NAME1 efghijk 4 efghijk5 abcd 6 abcd2 zzzz 2 zzzz4 xyzxyz 3 xyzxyz 迭代查询SELECT * FROM tb1 INNER JOIN tb2 ON t1.MEMBER_ID=t2.NAME ID MEMBE_ID2 zzzz4 xyzxyz ID NAME4 efghijk5 aaaa6 abcdID MEMBE_ID1 efghijk3 xxxxxx5 abcd ID NAME2 zzzz3 xyzxyztb1tb1tb2tb2FOR row1 IN select * FROM tb1ADD(SELECT * FROM tb2 WHERE tb2.name = row1.member_id)TO RESULT 跨库索引ID MEMBE_ID 2 zzzz4 xyzxyz ID NAME4 efghijk5 aaaa6 abcdID MEMBE_ID1 efghijk3 xxxxxx5 abcd ID NAME2 zzzz3 xyzxyztb1tb1tb2tb2ID1 ID2 JOIN_COL2 2 zzzz4 3 xyzxyzidxID1 ID2 JOIN_COL1 4 efghijk5 6 abcdidx扫描idx,再根据每一行的id1,id2查到最终结果 跨库索引ID MEMBE_ID 2 zzzz4 xyzxyz ID NAME4 efghijk5 aaaa6 abcdID MEMBE_ID1 efghijk3 xxxxxx5 abcd ID NAME2 zzzz3 xyzxyztb1tb1tb2tb2SELECT * FROM tb1 INNER JOIN tb2 ON t1.MEMBER_ID=t2.NAME WHERE t1.id = 5SELECT * FROM idx WHERE id1 = 5再根据id1,id2查到最终结果 跨库索引ID MEMBE_ID 2 zzzz4 xyzxyz ID NAME4 efghijk5 aaaa6 abcdID MEMBE_ID1 efghijk3 xxxxxx5 abcd ID NAME2 zzzz3 xyzxyztb1tb1tb2tb2ID1 ID2 JOIN_COL2 2 zzzz4 3 xyzxyzidxID1 ID2 JOIN_COL1 4 efghijk5 6 abcdidx一定以 JOIN_COL 为索引的拆分字段吗? 跨库索引SELECT * FROM tb1 INNER JOIN tb2 ON t1.MEMBER_ID=t2.NAME WHERE t1.gmt600 ID MEMBE_ID GMT2 zzzz 5254 xyzxyz 1010 ID NAME4 efghijk5 aaaa6 abcdID MEMBE_ID GMT1 efghijk 12053 xxxxxx 1315 abcd 604 ID NAME2 zzzz3 xyzxyztb1tb1tb2tb2 跨库索引 ID MEMBE_ID GMT2 zzzz 5254 xyzxyz 1010 ID NAME4 efghijk5 aaaa6 abcdID MEMBE_ID GMT1 efghijk 12053 xxxxxx 1315 abcd 604 ID NAME2 zzzz3 xyzxyztb1tb1tb2tb2ID1 ID2 JOIN_COL2 2 zzzz4 3 xyzxyzidxID1 ID2 JOIN_COL1 4 efghijk5 6 abcdidx ID MEMBE_ID2 zzzz4 xyzxyzID MEMBE_ID1 efghijk3 xxxxxx5 abcdtb1tb1ID1 ID2 JOIN_COL2 2 zzzz4 3 xyzxyzidxID1 ID2 JOIN_COL1 4 efghijk5 6 abcdidxSELECT idx.id2, tb1.* FROM idx INNER JOIN tb1 ON idx.id1=tb1.id WHERE t1.gmt600SELECT idx.id2, tb1.* FROM idx INNER JOIN tb1 ON idx.id1=tb1.id WHERE t1.gmt600 SELECT * FROM tb1 INNER JOIN tb2 ON t1.MEMBER_ID=t2.NAME WHERE t1.gmt600跨库索引 跨库索引 ID MEMBE_ID GMT2 zzzz 5254 xyzxyz 1010 ID NAME TIME4 efghijk 1235 aaaa 9226 abcd 222ID MEMBE_ID GMT1 efghijk 12053 xxxxxx 1315 abcd 604 ID NAME TIME2 zzzz 12013 xyzxyz 1111tb1tb1tb2tb2SELECT * FROM tb1 INNER JOIN tb2 ON t1.MEMBER_ID=t2.NAME WHERE t1.gmt600 AND t2.time600ID1 ID2 JOIN_COL TIME2 2 zzzz 12014 3 xyzxyz 1111idx 跨库索引 ID1 ID2 JOIN_COL TIME2 2 zzzz 12014 3 xyzxyz 1111idxID1 ID2 JOIN_COL TIME1 4 efghijk 1235 6 abcd 222idx 索引表的拆分 WHERE条件中的字段所在表的拆分字段,作为索引拆分字段 索引包含 两 张 表 的 主 键 JOIN字 段 WHERE中 的 其 他 字 段 索引的更新 分 布 式 事 务 的 支 持 SELECT c1 FROM tb1 ORDER BY c1 LIMIT 4, 2select . order by c1 limit 0, 6select . order by c1 limit 0, 6select . order by c1 limit 0, 6分 库 1分 库 2分 库 3cobarOrder By/Limit 分 库 1分 库 2分 库 3Order By/Limit456327810651111314973返 回 结 果返 回 结 果返 回 结 果8SELECT c1 FROM tb1 ORDER BY c1 LIMIT 4, 2 分 库 1分 库 2分 库 3Order By/Limit456327810651111314973返 回 结 果返 回 结 果返 回 结 果80最 终 结 果 集SELECT c1 FROM tb1 ORDER BY c1 LIMIT 4, 2 分 库 1分 库 2分 库 3Order By/Limit45632781065111314973返 回 结 果返 回 结 果返 回 结 果81最 终 结 果 集SELECT c1 FROM tb1 ORDER BY c1 LIMIT 4, 2 分 库 1分 库 2分 库 3Order By/Limit4563781065111314973返 回 结 果返 回 结 果返 回 结 果82最 终 结 果 集SELECT c1 FROM tb1 ORDER BY c1 LIMIT 4, 2 分 库 1分 库 2分 库 3Order By/Limit456781065111314973返 回 结 果返 回 结 果返 回 结 果83最 终 结 果 集SELECT c1 FROM tb1 ORDER BY c1 LIMIT 4, 2 分 库 1分 库 2分 库 3Order By/Limit45678106511131497返 回 结 果返 回 结 果返 回 结 果84最 终 结 果 集SELECT c1 FROM tb1 ORDER BY c1 LIMIT 4, 2 最 终 结 果 集 分 库 1分 库 2分 库 3Order By/Limit5678106511131497返 回 结 果返 回 结 果返 回 结 果844SELECT c1 FROM tb1 ORDER BY c1 LIMIT 4, 2 最 终 结 果 集 分 库 1分 库 2分 库 3Order By/Limit4678106511131497返 回 结 果返 回 结 果返 回 结 果845SELECT c1 FROM tb1 ORDER BY c1 LIMIT 4, 2 Order By/Limit 方案总结select c1 from tb1 order by c1 limit 100000000, 2 所有分库都要查询100000002条数据 Cobar需要遍历100000002条数据 对如下SQL 一次交互得到结果 Offset大小有限制 Order By / Limit 优化 目标:解 决查 询 量 大 问 题遍 历 量 大 问 题 前提各 个 分 库 数 据 分 布 大 致 一 样 select c1 from tb1 order by c1 limit 9999999, 4select . order by c1 limit 33333333, 4select . order by c1 limit 33333333, 4 select . order by c1 limit 33333333, 4分 库 1分 库 2分 库 3 step1:分成3条语句发给分库 分 库 1分 库 2分 库 374538691076119返 回 结 果返 回 结 果返 回 结 果select c1 from tb1 order by c1 limit 9999999, 4 找出查询结果中最小和最大值 分 库 1分 库 2分 库 374538691076119返 回 结 果返 回 结 果返 回 结 果 step2:以最小值和最大值为界再查询select c1 from tb1 order by c1 limit 9999999, 43115311 分 库 1分 库 2分 库 374538691076119返 回 结 果返 回 结 果返 回 结 果 step3:反查出每一个返回结果的offsetselect c1 from tb1 order by c1 limit 9999999, 4311531133333331条33333333条33333332条 分 库 1分 库 2分 库 374538691076119返 回 结 果返 回 结 果返 回 结 果 类似于原始方案select c1 from tb1 order by c1 limit 9999999, 431153119999996 分 库 1分 库 2分 库 374538691076119返 回 结 果返 回 结 果返 回 结 果 类似于原始方案select c1 from tb1 order by c1 limit 9999999, 41153119999997 分 库 1分 库 2分 库 37458691076119返 回 结 果返 回 结 果返 回 结 果 类似于原始方案select c1 from tb1 order by c1 limit 9999999, 41153119999998 分 库 1分 库 2分 库 37458691076119返 回 结 果返 回 结 果返 回 结 果 类似于原始方案select c1 from tb1 order by c1 limit 9999999, 4115119999999最 终 结 果 集 最 终 结 果 集 分 库 1分 库 2分 库 37458691076119返 回 结 果返 回 结 果返 回 结 果 类似于原始方案select c1 from tb1 order by c1 limit 9999999, 4115119999999 最 终 结 果 集 分 库 1分 库 2分 库 37458691076119返 回 结 果返 回 结 果返 回 结 果 类似于原始方案select c1 from tb1 order by c1 limit 9999999, 4115119999999 最 终 结 果 集 分 库 1分 库 2分 库 37458691076119返 回 结 果返 回 结 果返 回 结 果 类似于原始方案select c1 from tb1 order by c1 limit 9999999, 4115119999999 最 终 结 果 集 分 库 1分 库 2分 库 37458691076119返 回 结 果返 回 结 果返 回 结 果 类似于原始方案select c1 from tb1 order by c1 limit 9999999, 4115119999999 Order By / Limit 再优化 Step1不必得到全部结果select min(c1) mi, max(c1) ma from (select c1 from tb1 order by c1 limit 3333333,4) t Step2和Step3合并select * from (select * from tb1 where c1 between mi and ma) t1, (select count(*) from tb1 where c1 mi) t2 Group BySELECT sum(price) FROM tb1 GROUP BY c1ID PRICE C11 12.3 22223 1.6 1315 8.8 6047 6.3 131 ID PRICE C12 4.4 6044 7.6 1316 99.9 56 Group BySELECT sum(price) FROM tb1 GROUP BY c1ID PRICE C11 12.3 22223 1.6 1315 8.8 6047 6.3 131 ID PRICE C12 4.4 6044 7.6 1316 99.9 56SELECT sum(price), c1 FROM tb1 GROUP BY c1 ORDER BY c112.322227.91318.860499.9567.61314.4604 Group BySELECT sum(price) FROM tb1 GROUP BY c1ID PRICE C11 12.3 22223 1.6 1315 8.8 6047 6.3 131 ID PRICE C12 4.4 6044 7.6 1316 99.9 56SELECT sum(price), c1 FROM tb1 GROUP BY c1 ORDER BY c112.322227.91318.86047.61314.4604最 终 结 果 集99.956 Group BySELECT sum(price) FROM tb1 GROUP BY c1ID PRICE C11 12.3 22223 1.6 1315 8.8 6047 6.3 131 ID PRICE C12 4.4 6044 7.6 1316 99.9 56SELECT sum(price), c1 FROM tb1 GROUP BY c1 ORDER BY c112.322227.91318.86047.61314.4604最 终 结 果 集99.956 最 终 结 果 集 Group BySELECT sum(price) FROM tb1 GROUP BY c1ID PRICE C11 12.3 22223 1.6 1315 8.8 6047 6.3 131ID PRICE C12 4.4 6044 7.6 1316 99.9 56SELECT sum(price), c1 FROM tb1 GROUP BY c1 ORDER BY c112.3222215.51318.86044.460499.956 最 终 结 果 集 Group BySELECT sum(price) FROM tb1 GROUP BY c1ID PRICE C11 12.3 22223 1.6 1315 8.8 6047 6.3 131ID PRICE C12 4.4 6044 7.6 1316 99.9 56SELECT sum(price), c1 FROM tb1 GROUP BY c1 ORDER BY c112.3222215.513113.260499.956 最 终 结 果 集 Group BySELECT sum(price) FROM tb1 GROUP BY c1ID PRICE C11 12.3 22223 1.6 1315 8.8 6047 6.3 131ID PRICE C12 4.4 6044 7.6 1316 99.9 56SELECT sum(price), c1 FROM tb1 GROUP BY c1 ORDER BY c112.3222215.513113.260499.956 SQL执行策略总结 WHERE - 基 于 SQL转 发 JOIN - 迭 代 分 布 式 索 引 ORDER BY/LIMIT - 多 次 查 询 减 小 数 据 量 GROUP BY - 增 加 ORDER BY Cobar 事务支持前端连接 sql1sql2commit Cobar 1.2 事务支持前端连接 分库1连接sql1sql2commit Cobar 1.2 事务支持前端连接 分库1连接sql1commit 分库2连接sql2 分库3连接sql2 Cobar 事务支持前端连接 分库1连接sql1commit 分库2连接sql2 分库3连接sql2 Commit有先后:隔离性问题 Commit有失败:一致性问题 大纲n 中间件引入n Cobar策略n 水 平 拆 分 的 数 据 分 布n 几 种 SQL元 素 的 执 行 策 略n 事 务 策 略n 系统实现n 实施应用 schema tableSpace dataNodedata sourcecndb pc2主 备 主 备default offer0 主 备offer1 主 备detail0 主 备defaultdefault offer detail detail 逻辑层次 接口同MySQLjdbc:mysql:/cobarIp:8066/cndb?user=foo ps.setLong(1, 12345);ResultSet rs = ps.executeQuery();MySQLServer Application1MySQLJDBCDriver JDBC和Server的通信协议MySQLServer Application1MySQLJDBCDriver PreparedStatement ps = conn.prepareStatement( select * from tb1 where id=?); ps.setLong(1, 12345);ResultSet rs = ps.executeQuery();select * from tb1where id=?stmt_id/param_num/columm_numparameter_type column_type JDBC和Server的通信协议PreparedStatement ps = conn.prepareStatement( select * from tb1 where id=?); ps.setLong(1, 12345);ResultSet rs = ps.executeQuery();MySQLServer Application1MySQLJDBCDriver JDBC和Server的通信协议PreparedStatement ps = conn.prepareStatement( select * from tb1 where id=?); ps.setLong(1, 12345);ResultSet rs = ps.executeQuery();MySQLServer Application1MySQLJDBCDriverstmt_id param+field_countcolumn_typecolumn_val+column_val+ JDBC和Server的通信协议Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery( “select * from tb1 where id=12345”); Application1MySQLJDBCDriversqlfield_countcolumn_typecolumn_val+column_val+MySQLServer JDBC和Server的通信协议Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery( “select * from tb1 where id=12345”); Application1MySQLJDBCDriversqlfield_countcolumn_typecolumn_val+column_val+MySQLServerCobarServer Processor(1) Processor(n) MySQL MySQL MySQL Cobar结构 Front-end Communication MySQL Protcol Adaptor (BIO) Application1 MySQL MySQL Protocol MySQL MySQLData NodesMonitorConfigure HA PoolMySQLMySQLSQL ExecutorSQL Router SQL Parser ResultMerger SQL ExecutorSQL RouterSQL Parser ResultMerger. Manager MySQL Protocol MySQL Protocol MySQL Protocol MySQL ProtocolManagement ProtocolSQL +ParametersResultSetMetaDataResultSet(Rows) Cobar 通信层 统一管理NIO的Buffer 4KBByteBuffer 4KBByteBuffer 4KBByteBuffer 4KBByteBuffer4KB ByteBuffer 4KBByteBuffer 4KBByteBuffer 4KBByteBuffer4KBByteBuffer 4KBByteBuffer4KBByteBuffer 4KBByteBuffer4KBByteBuffer 4KBByteBuffer4KBByteBuffer 4KBByteBuffer 4KBByteBuffer4KBByteBuffer4KBByteBuffer4KBByteBuffer共 16MBBuffer Pool Cobar 通信层 统一管理NIO的Buffer 4KBByteBuffer 4KBByteBuffer 4KBByteBuffer 4KBByteBuffer4KB ByteBuffer 4KBByteBuffer 4KBByteBuffer 4KBByteBuffer4KBByteBuffer4KBByteBuffer 4KBByteBuffer 4KBByteBuffer4KBByteBuffer4KBByteBuffer 4KBByteBuffer 4KBByteBuffer 4KBByteBuffer4KBByteBuffer4KBByteBuffer4KBByteBuffer共 16MBBuffer Poolselect * from tb1 where id=? Cobar 通信层 统一管理NIO的Buffer 4KBByteBuffer 4KBByteBuffer 4KBByteBuffer 4KBByteBuffer4KB ByteBuffer4KBByteBuffer 4KBByteBuffer 4KBByteBuffer4KBByteBuffer 4KBByteBuffer4KBByteBuffer 4KBByteBuffer4KBByteBuffer 4KBByteBuffer4KBByteBuffer 4KBByteBuffer 4KBByteBuffer4KBByteBuffer4KBByteBuffer4KBByteBuffer 共 16MB Buffer Poolselect * from tb1 where id=? Cobar 通信层 统 一 管 理 NIO的 Buffer 4KBByteBuffer 4KBByteBuffer 4KBByteBuffer 4KBByteBuffer4KB ByteBuffer4KBByteBuffer 4KBByteBuffer 4KBByteBuffer4KBByteBuffer 4KBByteBuffer4KBByteBuffer 4KBByteBuffer4KBByteBuffer 4KBByteBuffer4KBByteBuffer 4KBByteBuffer 4KBByteBuffer4KBByteBuffer4KBByteBuffer4KBByteBuffer 共 16MB Buffer Pool15万TPS . MySQL MySQL MySQLCobar结构 Front-end CommunicationMySQL Protcol Adaptor (BIO)Application1MySQL MySQL ProtocolMySQL MySQLData NodesMonitorConfigure HA PoolMySQLMySQL Processor(1) Processor(n)SQL ExecutorSQL Router ResultMerger SQL ExecutorSQL Router ResultMergerManager MySQL Protocol MySQL Protocol MySQL Protocol MySQL ProtocolManagement Protocol SQL Parser SQL Parser SELECT id, member_id FROM wp_image WHERE member_id = 123SQL Parserselect id member_id wp_image =member_id 123exprList from 架构演变 基于JavaCC生成SQL Parser 性 能 较 差 , 优 化 不 方 便 仿照ANTLR生成的Parser结构手写 基 于 LL(*)的 识 别 器 , 中 间 对 象 过 多 基于LL(2)识别器的手写 第 一 版第 二 版第 三 版 架构调整Lexertoken token token tokenChar ReaderExpression ParserDML Parser SQL String LexertokenExpression ParserDML ParserSQL char第三版LL(2)第二版LL(*) cache 功能对比第一版 第二版 第三版dontNO YES YES.123e-2YES YES YES7ElevenNO YES YES_latin 0 x123NO YES YESabc defNO YES YESINSERT(Quadratic, 3, 4, What)NO YES YES TRIM(LEADING x FROM xxxbarxxx)NO YES YESUnion selectYES YES YEStable joinPART PART YES 基本元素语法元素 MySQL 5.5 语法结构Identifier Keyword Literal Punctuation表达式Table ReferencesLimitOrderBy. Delete Update Insert Replace SelectCallSet/Show SQL语句Variable 基本元素 Keyword 227个 关 键 字 , 不 区 分 大 小 写 Identifier schema、 table、 column、 index、 alias 、 keywordSELECT aNy FROM t1 WHERE id IN AnY (SELECT id FROM t2)select、table1 ./*spam*/id、7Up Punctuation,、:=、!、 Variable User-Def SystemVariable:version 基本元素 - Literal String LiteralNabc、_latin1abc、 abc def”abc”d”、 abcd Number Literal123、.123、123.、123.e4、.123E-4123e4 vs 123e4f Hex/Bit Literal0 x89af、x89af、0b101011、b101011_latin1 0 x89af 基本元素语法元素 MySQL 5.5 语法结构Identifier Keyword Literal Punctuation表达式Table ReferencesLimitOrderBy. Delete Update Insert Replace SelectCallSet/Show SQL语句Variable 语法元素 Table Referencestable_references: table_reference , table_referencetable_reference: table_factor INNER|CROSS JOIN table_factor join_condition | STRAIGHT_JOIN table_factor ON conditional_expr | (LEFT|RIGHT) OUTER JOIN table_reference join_condition | NATURAL (LEFT|RIGHT) OUTER JOIN table_factor table_factor: tbl_name AS alias index_hint_list | table_sub
展开阅读全文