关系型DB(MySQL,MyBatis )

数据库中间件/分库分表相关知识点整理

2019-07-10  本文已影响0人  南岩飞雪

来源

来自对大佬们文章的总结,参考的文章都列在最后啦

1 数据库拆分

垂直拆分 -> 读写分离 -> 分库分表(水平拆分)

1.1 垂直拆分

1.2 读写分离

1.2.1 优点

1.2.1 挑战

1.3 分库分表

垂直分库 + Master/Salve 模式 -> 高并发访问操作;但是业务表中的数据还是会很大 -> 维护和性能

1.3.1 优点

1.3.2 挑战

希望像操作单库单表一样操作分库分表

2 主流数据库中间件设计方案

单库单表,通过连接池与数据库建立连接,进行读写操作
读写分离和分库分表,应用都要操作多个数据库实例,需要使用数据库中间件

2.1 设计方案

典型:proxy、smart-client

2.1.1 proxy模式

2.1.1.1 优点

2.1.1.2 缺点

2.1.2 smart-client模式

通常smart-client是在连接池或者driver的基础上进行了一层封装,smart-client内部与不同的库建立连接,sql交给smart-client

2.1.2.1 优点

2.1.2.2 缺点

2.2 业界产品

各有优缺点

proxy实现

目前的实现方案有:

smart-client实现

目前的实现方案有:

3 读写分离核心要点

3.1 基本路由功能

3.1.1 sql类型判断

3.1.2 强制走主库

具体实现上有2种方案:hint 或API

3.2 从库路由策略

一些简单的选择策略包括:

3.3 HA、Scalable相关

3.3.1 配置中心

事实上:主从变更,增加从库 -> 配置信息变更 -> 监听配置中心
配置中心的选择:

3.3.1.1 问题

3.3.2 轻量级的HA保障

3.3.3 限流和降级

4 分库分表

核心要点:希望像操作单个数据库实例那样编写sql,数据库中间件帮忙屏蔽所有底层的复杂逻辑
示例场景:批量插入

4.1 SQL解析

目前较为流行的sql解析器包括:

4.2 SQL路由

分库分表的字段称为路由字段,或者分区字段。
注意点:SQL中应该包含这个路由字段- INSERT- SELECT- UPDATE、DELETE。
路由规则有:

4.3 SQL改写

很复杂,支持简单的OLTP场景,迈向OLAP
补充知识点:OLTP(On-Line Transaction Processing,联机事务处理),OLAP(On-Line Analytical Processing,联机分析处理),HTAP

4.4 SQL执行

拆出来的多个SQL,并发执行

4.5 结果集合并

权衡实现复杂度、执行效率,case by case分析

4.6 二级索引(辅维度同步)

user_id分库分表,同步到另一个集群,按phone_id分库分表

4.7 分布式id生成器

4.8 分布式事务

4.8.1 事务简介

事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)

4.8.2 本地事务

只需要操作单一的数据库,ACID特性由数据库支持
补充:spring @Transitional 使用注意

4.8.3 分布式事务典型场景

4.8.4 X/Open DTP模型与XA规范

4.8.4.1 DTP模型(分布式事务处理 Distributed Transaction Processing)

5个基本元素:
- 应用程序(Application Program ,简称AP):用于定义事务边界(即定义事务的开始和结束),并且在事务边界内对资源进行操作。
- 资源管理器(Resource Manager,简称RM):如数据库、文件系统等,并提供访问资源的方式。
- 事务管理器(Transaction Manager ,简称TM):负责分配事务唯一标识,监控事务的执行进度,并负责事务的提交、回滚等。
- 通信资源管理器(Communication Resource Manager,简称CRM):控制一个TM域(TM domain)内或者跨TM域的分布式应用之间的通信。
- 通信协议(Communication Protocol,简称CP):提供CRM提供的分布式应用节点之间的底层通信服务。CRM底层采用OSI TP(Open Systems Interconnection — Distributed Transaction Processing)通信服务

4.8.4.2 XA规范

XA是DTP模型定义TM和RM之间通讯的接口规范。

4.8.4.2.1 两阶段提交协议(2PC)
4.8.4.2.1.1 XA规范对2PC的2点优化
4.8.4.2.1.2 存在的问题
4.8.4.2.2 三阶段提交协议(Three-phase commit)
4.8.4.2.2.1 3PC针对2PC改动点
4.8.4.2.2.2 3PC和2PC区别

相对于2PC,3PC主要解决的单点故障问题,并减少阻塞
都无法彻底解决分布式的一致性问题

4.8.5 BASE理论与柔性事务

4.8.5.1 经典的分布式系统理论-CAP

4.8.5.2 BASE理论

BASE理论是对CAP理论的延伸,核心思想是即使无法做到强一致性(Strong Consistency,CAP的一致性就是强一致性),但应用可以采用适合的方式达到最终一致性(Eventual Consitency)

4.8.5.3 典型的柔性事务方案

4.8.5.3.1 最大努力通知
4.8.5.3.2 TCC两阶段补偿型(maybe目前最火)
4.8.5.3.2.1 TCC两阶段提交 VS XA两阶段提交
4.8.5.3.2.2 补偿性事务(Compensation-Based Transactions)

补偿是一个独立的支持ACID特性的本地事务,用于在逻辑上取消服务提供者上一个ACID事务造成的影响,对于一个长事务(long-running transaction),与其实现一个巨大的分布式ACID事务,不如使用基于补偿性的方案,把每一次服务调用当做一个较短的本地ACID事务来处理,执行完就立即提交

4.8.5.3.2.3 TCC事务模型 VS DTP事务模型
4.8.5.3.2.4 TCC事务的优缺点
4.8.5.3.3 可靠消息最终一致性

两种方案

4.9 分库分表常用方案

分库分表方案中有常用的方案,hash取模和range范围方案

4.9.1 hash取模

4.9.2 range范围方案

4.9.3 俩者结合

4.9.4 分库分表能无限扩容么

4.10 什么时候分库分表?数据的量级?

5. 异地多活

tddl 配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
    <bean id="vtabroot" class="com.taobao.tddl.interact.rule.VirtualTableRoot" init-method="init">
        <property name="dbType" value="MYSQL" />
        <property name="defaultDbIndex" value="XXX_0000_GROUP" />
        <property name="tableRules">
            <map>
                <entry key="xxx_user" value-ref="xxx_user" />
                <entry key="xxx_dept" value-ref="xxx_dept" />
            </map>
        </property>
    </bean>
    <bean id="xxx_user" class="com.taobao.tddl.interact.rule.TableRule">
        <property name="dbNamePattern" value="XXX_{0000}_GROUP" />
        <property name="tbNamePattern" value="xxx_user_{0000}" />
        <property name="dbRuleArray" value="(#corp_id,1,1024#.hashCode().abs().longValue() % 1024).intdiv(64)" />
        <property name="tbRuleArray" value="(#corp_id,1,1024#.hashCode().abs().longValue() % 1024)" />
        <property name="allowFullTableScan" value="false" />
    </bean>
    <bean id="xxx_dept" class="com.taobao.tddl.interact.rule.TableRule">
        <property name="dbNamePattern" value="XXX_{0000}_GROUP" />
        <property name="tbNamePattern" value="xxx_dept_{0000}" />
        <property name="dbRuleArray" value="(#corp_id,1,1024#.hashCode().abs().longValue() % 1024).intdiv(64)" />
        <property name="tbRuleArray" value="(#corp_id,1,1024#.hashCode().abs().longValue() % 1024)" />
        <property name="allowFullTableScan" value="false" />
    </bean>
</beans>
<bean id="dataSource" class="com.taobao.tddl.client.jdbc.TDataSource" init-method="init">
        <!--<property name="appName" value="XXX_APP"/>-->
        <property name="appName" value="XXX_APP"/>
        <property name="appRuleFile" value="/xxx/tddl-rule.xml"/>
        <property name="dynamicRule" value="true"/>
</bean>

参考

DRDS 实例中的连接

分库分表的基本思想

分库分表?如何做到永不迁移数据和避免热点?

MySQL binlog原来可以这样用?各种场景和原理剖析!

leaf:美团开源的分布式ID生成系统剖析

UidGenerator:百度开源的分布式ID服务(解决了时钟回拨问题)

数据库中间件详解

1.0 分布式事务概述

分布式事务

扎心一问:分库分表就能无限扩容吗

饿了么异地多活技术实现

数据库异地多活解决方案

异地多活没那么难

2017双11技术揭秘—TDDL/DRDS 的类 KV 查询优化实践

上一篇下一篇

猜你喜欢

热点阅读