有幸参加了DTCC2016会议,今年的会议特别火爆,很想每个专场都去看,可惜分身乏术。做了很多笔记,这里把关于NewSql的部分梳理成KM,没有DBA专业和深入,有出入的请使劲拍砖!...
一、DTCC2016简介
二、数据库演化的3个阶段
三、补个基础:一个SQL的执行过程
四、补个基础:事务的ACID特性和实现技术
五、NewSql要解决的几个主要问题
六、基于mysql-handler实现数据分库分表
七、分布式事务相关协议
======================================================
一、DTCC2016简介
* 2016.05,北京,第七届中国数据库技术大会
* 以"数据定义未来"为主题,云集了国内外技术同行,探讨MySQL、NoSQL、Oracle、缓存技术、云端数据库、智能数据平台、大数据安全、数据治理、大数据和开源、大数据创业、大数据深度学习等领域的前瞻性热点话题与技术
* 首页:http://dtcc.it168.com/
* ppt资源:http://pan.baidu.com/s/1eSO6A4a(不是很全,但蛮多ppt写得很赞)
* 2个主会场和21个分会场,下面是每个会场的主题汇总。从主题上可看出当前业界比较关注的数据库领域:
第一天(上午)主场1:数据定义未来
第一天(下午)专场1:数据库架构设计
第一天(下午)专场2:NoSQL技术实践
第一天(下午)专场3:数据加速技术
第一天(下午)专场4:实时计算与流计算
第一天(下午)专场5:SAP技术交流专场
第一天(下午)专场6:我的DBA之路
第一天(下午)专场7:柏睿数据库技术专场
第二天(上午)主场2:聚焦大数据+引领行业变革
第二天(下午)专场8:数据库性能优化
第二天(下午)专场9:云端数据库
第二天(下午)专场10:大数据应用及实践
第二天(下午)专场11:数据库内核技术
第二天(下午)专场12:数据架构&治理
第二天(下午)专场13:数据挖掘&BI
第二天(下午)专场14:南大通用专场发布会
第三天(上午)专场15:SQL之美
第三天(上午)专场16:内存数据库进展
第三天(上午)专场17:大数据基础设施
第三天(上午)专场18:大数据安全
第三天(上午)专场19:大数据行业应用及探索
第三天(下午)专场20:数据库自动化运维
第三天(下午)专场21:推荐系统架构及算法
第三天(下午)专场22:大数据生态系统及开源
第三天(下午)专场23:数据库技术前瞻
第三天(下午)专场24:人工智能
第三天(下午)专场25:大数据创业
二、数据库演化的3个阶段
1、SQL RDBMS:传统关系型数据库,应用广泛,但扩展性差
2、NoSql:解决扩展性问题,但提供数据模型有限,不支持事务
3、NewSql:扩展性/可用性/一致性,支持事务
技术演化来源于需求,用户对数据库需求其实较简单:
* 用户需要:SQL,事务(ACID)
* 用户不想关心:数据分区,故障切换,数据一致性等
三、补个基础:一个SQL的执行过程
上图能较好反映一个sql在mysql-server内的执行过程,除了基础的网络连接和进程管理等,mysql-server在收到一个SQL语句后的主要流程:
1、SQL解析:SQL解析器(函数入口sql_prase.cc)会对SQL语句进行词法和语法分析,将SQL分解成token,并组成语法树,如:
网上也有一些基于Flex和Bison工具做SQL语句解析的例子,这个文章介绍得比较简洁:http://blog.csdn.net/qq910894904/article/details/34861173
2、SQL优化:查询优化器(函数入口sql_optimizer.cc)对SQL进行逻辑优化和物理优化,产生自认为较优的执行计划,这里可以用explain命令来查看。常用的优化点如利用索引存取、常量转换、无效条件或者代码过滤等
3、SQL执行:在明确SQL执行计划后,剩下的工作就是调用存储引擎读写数据了(函数入口sql_executor.cc)。这里涉及到mysql一个最大的特色 - 插件式存储引擎,这里后面会继续分析
四、补个基础:事务的ACID特性和实现技术
什么是事务?简单举例来说:A有200块钱,B有200块钱,A给B转50块钱,要么同时成功(A=150&B=250),要么同时失败(A=200&B=200),不存在其他情况。很多同学应该都听过这个转账的例子,可能我们一些互联网业务不一定需要用到,但很明显对于金融界的OLTP业务是多么重要,被称为商业世界稳定运行的基石
事务的ACID特性:用来判断数据库事务是否正确执行的四个基本要素
* A 原子性(Atomicity):要么全部执行,要么全部不执行。即要么A=150&B=250,要么A=200&B=200
* C 一致性(Consistency):事务运行不改变数据的一致性约束。即A+B=400这个约束不会变
* I 隔离性(Isolation):两个事务之间,执行互补干扰。比如A同时又给C转50块钱,这2件事是不会相互影响的
* D 持久性(Durability):事务执行完,数据就会持久保存,不会因为断电等事故回到原来状态
实现ACID核心技术之一:并发控制
* 怎么保证多个事务正确并发执行?使用并发控制算法调度多个事务,使得该执行是可串行化的(serializable,即效果和串行执行是等价的)。这里算法基于严格的数学定理推论,不讨论
* 并发控制技术-mvcc,多版本并发控制:事务执行过程只读到数据库某一时刻/版本的数据,即使这个数据被其他事务修改。最大的好处是读不加锁,读写不冲突,适用于短事务,多查询的场景。mysql的InnoDB就是使用这个方法
* 并发控制技术-2pl,两阶段锁:经典并发控制模型,事务执行在第一阶段(扩展阶段)获取所有读写数据的锁,在第二阶段(收缩阶段)释放所有加过的锁,这个阶段不会再申请任何锁
* 怎么权衡并发性能和正确性?完全串行化会导致性能不高,根据不同业务对一致性要求的不同,SQL标准定义了4种隔离级别。隔离级别越弱,事务并发度越好,也更容易引发不一致等异常
1、脏读:读未提交,会读到其他事务未提交的脏数据(事务间)
2、不可重复读:读已提交,事务过程中对一个数据读2次,可能读到不同值(事务内)
3、幻读:可重复读,事务过程中对一个数据读2次值都是一样的,但最后事务提交却发现这个数据已经不一样了,像之前读的是"幻影"一样(mysql默认隔离级别)
4、串行化
实现ACID核心技术之二:日志技术
* 事务处理中可能遇到的异常:
1、事务失败:如违反了一致性约束,需Abort事务,清除事务对数据库影响
2、系统故障:重启或者断电等,内存数据丢失,需保证已提交事务的修改不丢失,正在运行或Abort事务对数据库影响可清除
3、存储故障:如磁盘损坏等,需保证数据可恢复
* 怎么应对各种异常,实现异常恢复?常使用基于WAL协议的日志技术,来实现事务的redo/undo。即预写式日志,日志比数据先刷盘(是否fsync可配置),通过CheckPoint定位更新操作。包含3个规则和很多细节优化,这里不展开
五、NewSql要解决的几个主要问题
* 兼容mysql协议
* 数据自动sharding,解决扩展性问题,对用户透明(核心功能)
* 动态扩缩容
* 分布式事务
* 数据分区容灾,故障自动切换
* 统一部署运维监控
六、基于mysql-handler实现数据分库分表
前面说过mysql一个最大的特色就是插件式存储引擎,有特定需求的业务只需根据定义好的接口(sql/handler.h),就可以跳过sql解析和查询计划等步骤,编写自定义的存储引擎。几个主要的mysql-handler Api如下:
这个是mysql源码的官方例子(storage/example/ha_example.h),大体含义从函数名基本可以看出来。这里主要有2个类:handlerton类主要约定事务操作接口,handler类主要约定表、索引及记录操作接口。
这样只要我们把分库分表的功能实现在这些API内,就可以简单搭一个分布式数据库系统,而对用户屏蔽掉sharding的细节,对用户使用SQL无感知,如下所示:
分库分表之后,对于DDL/DML操作只需落到一个分区内就比较简单,比如select * from userinfo where uid=123; 但如果是落到多个分区,像select sum(age) from userinfo; 就需拆分SQL访问后端多个分区,由分区计算完中间结果返回后再做聚合。
如这个语句:select name, count(*) from userinfo where age>20 group by name; 需所有分区执行:select name, count(*) from userinfo_xxx where age>20 group by name; 获取所有分区的中间结果后,再对name相同的做count(*)叠加后才是最终结果
所以,这里需要对下面主要sql元素的分库分表实现做单独处理。例如复杂join或者各类异常可能让查询性能变得很差,这里得考虑更多的优化策略。
* 查询:select
* 更新:insert/update/delete
* 聚集:min/max/count/sum/avg
* 关联:join
* 排序:order by
* 分组:group by
七、分布式事务相关协议
分布式存储系统中,分布式事务用来保证数据在不同分区的一致性。作为一个业界难题,很多数据库系统都选择暂不支持。有时候,和业务方一起讨论如何规避分布式事务,反而是个更明智的选择。毕竟大多数技术都是使劲投人投资源就都能做成的,但是得考虑投入产出比的问题
解决分布式数据一致性问题,最常见的两个协议:2PC和Paxos
2PC:两阶段提交
事务过程涉及的2个角色:
1、协调者:事务发起者,即mysql client或者proxy
2、参与者:事务执行者,即各分区数据节点
事务的2个阶段:
1、表决阶段
* 协调者:通知所有参与者准备执行事务(Perpare T)
* 参与者:预写日志(undo+redo),返回表决结果,即是否可执行事务(Ready T/NotReady T)
2、提交阶段
* 协调者:只当所有参与者返回Ready T时,通知所有参与者执行事务(Commit T),否则发送结束事务(Abort T)
* 参与者:根据协调者的通知commit或rollback
很明显,这里还有很多异常需要处理。比如协调者和参与者的消息因故障丢失了怎么处理?这里需要引入超时机制,定义各类超时情况的超时操作。有些可以通过Abort事务来解决,但有些就没那么简单了,比如某个参与者在表决后,一直没收到协调者是否执行事务的消息,这时它处于一个不确定状态(可能是commit或者rollback),需要和协调者以及其他参与者发起一个商议,执行一个terminaion protocol并根据之前预写的日志来恢复事务
可见,2PC的实现复杂,而且在异常(机器宕机、网络波动等)较多的情况下吞吐量也不高。因为参与者在表决可执行事务后,就得在对应数据上加锁,直到再被通知事务commit或者rollback
Paxos
Google Chubby(Zookeeper为Chubby的开源版本)的作者Mike Burrows说过:世上只有一种一致性算法,那就是Paxos,其他一致性算法都是Paxos的不完整版。
但是,Paxos作为一种基于消息传递且具有高度容错特性的一致性算法,一直以来都被认为算法理论太难理解。这里我也没有完全弄懂,比较好的学习资料推荐一本书《从Paxos到Zookeeper》,以及网上的一些文章:
《分布式一致性Paxos算法学习笔记(二):算法详解》
http://www.cnblogs.com/ychellboy/archive/2009/12/29/1634801.html
《分布式系统Paxos算法》
http://www.jdon.com/artichect/paxos.html