精华内容
下载资源
问答
  • TDDL
    2021-01-19 04:03:21

    在使用tddl 之前首选安装 配置diamond

    基本信息说明

    appName=pay

    groupKey=groupKey

    dbKey=andor_qatest  备注 dbkey 为数据库名称

    dbType=mysql

    dbUserName=tddl

    一 .动态数据源配置

    TGroupDataSource 的配置

    1、配置读写分离权重:

    com.taobao.tddl.jdbc.group_V2.4.1_ “ groupKey ”

    例子:

    com.taobao.tddl.jdbc.group_V2.4.1_groupKey

    配置内容如下

    andor_qatest:r10w10

    TAtomDataSource 的配置(由 3 部分组成, global 、 app 、 user )

    1、基本数据源信息 (global) :

    com.taobao.tddl.atom.global. “ dbKey ”

    例子:

    com.taobao.tddl.atom.global.andor_qatest

    配置内容如下

    ip=127.0.0.1

    port=3306

    dbName=andor_qatest

    dbType=mysql

    dbStatus=RW

    2、数据库连接信息( app ,如果不配置时间单位,缺省为分钟):

    com.taobao.tddl.atom.app. “ appName ” . “ dbKey ”

    例子:

    com.taobao.tddl.atom.app.pay.andor_qatest

    配置内容如下

    userName=tddl

    minPoolSize=1

    maxPoolSize=2

    idleTimeout=10

    blockingTimeout=1000

    preparedStatementCacheSize=15

    connectionProperties=characterEncoding=utf-8

    3、数据库密码信息 (user) :

    此处的dbKey 为dbName

    com.taobao.tddl.atom.passwd. “ dbKey ” . “ dbType ” . “ dbUserName ”

    例子:

    com.taobao.tddl.atom.passwd.andor_qatest.mysql.tddl

    配置内容如下

    encPasswd=tddl

    4.配置server_topology.xml

    样例

    5.配置mysql_schema.xml

    样例

    id

    6.配置rule.xml

    样例

    init-method="init">

    7.配置TDataSource  如下

    样例

    更多相关内容
  • tddl使用与配置(详细)

    2017-09-04 01:43:37
    tddl使用与配置. TDDL除了拿到分库分表条件外,还需要拿到order by, group by, limit m,n , join信息, SUM,MAX,MIN等聚合函数信息,DISTINCT信息. 具有这些关键字的SQL在单库和多库情况下进行,语义是不同的.TDDL必须...
  • 分布式数据层TDDL.zip

    2019-07-16 03:44:44
    淘宝根据自己的业务特点开发了TDDL(Taobao Distributed Data Layer 外号:头都大了 ©_Ob)框架,主要解决了分库分表对应用的透明化以及异构数据库之间的数据复制,它是一个基于集中式配置的 jdbc datasource实现,...
  • mysql中间件研究(Atlas、cobar、TDDL、Mycat).docx
  • tddl原理讲解

    2017-12-14 17:39:59
    该文档介绍tddl server的原理,讲述了tddl如何工作,特别是想了解tddl原理服务的同学
  • mysql中间件研究(Atlas、cobar、TDDL、Mycat).doc
  • TDDL加入XA两阶段事务提交,本人自己跟代码画的这些图,从原公司离职没有保存代码,希望这个图可以给研究TDDL的朋友一些启发
  • tddl.rar_Different_TDDL

    2022-09-23 16:25:34
    Taobao tddl, used to integrate different data sources, very useful.
  • tddl 部署结构图

    2018-12-04 20:10:21
    tddl 是阿里巴巴开源的分布式数据库中间件,支持分裤分表
  • TDDL思考总结

    2021-03-03 19:21:32
    单机数据库分布式数据库TDDL原理与最佳实践1. 数据库的结构1.1. KV存储(id是K)1.2. B+树与红黑树B+树的特点是叶子节点是块状,一个叶子里面有多个数据,相邻数据是存在一起的,123,456起等,而磁盘也是按块的,B+树...

    单机数据库

    分布式数据库

    TDDL原理与最佳实践

    1. 数据库的结构

    1.1. KV存储(id是K)

    1.2. B+树与红黑树

    B+树的特点是叶子节点是块状,一个叶子里面有多个数据,相邻数据是存在一起的,123,456起等,

    而磁盘也是按块的,B+树的数据是按块存储的正好和磁盘的块的概念是相符的,

    所以在数据库里面大多采用了B+树或者类似的一种结构来存储数据。

    在java中实现treemap时选择是红黑树而不是B+树,B+面向的是磁盘的结构,

    java的treemap面向的是内存,随机读写数据快;

    另外一个原因是,B+树为了减少分裂的次数会在每个叶子结点中预留几个空洞来存入未来的数据,

    这个特点在磁盘中是可以的,因为磁盘都是白菜价,浪费一点没有关系,但内存就不一样了;

    红黑树本质是一颗二叉树,每个叶子只有一条数据,不需要预留任何的空间,

    在内存中就不会造成空间的浪费,也就是这两点,才选择了红黑树来实现java中的treemap.

    任何一种技术脱离了它的场景都是没有意义的;

    有些数据库不是按行存的,是按列存的,这样可对列的特点进行压缩,减少存储空间,

    进行max/min等运算也快,但这种特点不适合更新;

    没有一种数据库读的快写的也快,读写性能的差距也是由于背后所使用的存储不同导致的,

    如hbase使用的是lsm-tree这种存储,它的特点是写的很快,顺序写,但读的稍微有点慢,

    所以hbase经常用来存日志,产生的量,对读的性能要求不高。

    要判断读的多还是写的多,如果读的多,还要判断读的特点,是随机读还是范围的读,写的话,

    是只写还是会有删除和更新;B树是面向磁盘的,红黑树是面向内存的;

    2. 索引查询优化器

    主表和索引表都是映射,查询如果使用到了索引,就会分为两步,第一步先查索引,第二步通过索引再查主表,

    这一步叫回表。如果查询中的列(seletc a,b)都是索引中的列,那么就只有一步,只要查索引表就可以了,

    就不需要回表了,这叫索引覆盖。 如果索引包含所有的列,也就是主键对记录的索引,就是聚簇索引。

    如果索引包含部分的列,就是非聚簇索引, 非聚簇索引在查询的时候就可能需要做一个回表的操作才能查出所有的列来。

    索引太多时有两个缺点, 占空间,对记录进行写操作时也要修改索引,写入性能的下降。

    没有索引时就会全表扫描。

    主表的每一条记录都是一个KV映射,K就是主键,V就是整条记录,而索引就是列对K的索引而已。

    区分度比较高就比较适合做索引列。

    从某种程度上说,索引也是一种关系型数据库的表。

    关系型的数据库都有索引的概念,而NoSQL是没有索引的概念的,比如hbase就没有索引,只能按照rowkey来查,

    不能按照其他字段来查。

    sql语句会经过解析器,经过解析变成一个数据结构, 查询优化器会分析这个数据结构是什么意思,怎样执行会比较快,

    会生成一个执行计划,这个计划就包括查字典的整个过程。

    SQL->Optimizer->plan,底下的存储按照plan就会得到高效而且准确的结果。

    那么查询优化器会做哪些事情呢?

    1.索引选择

    当where有两个或者多个列都有索引时,就会涉及到索引选择的问题。一般会根据区分度选择合适的索引。

    2.下推

    select t1.name,t2.name from t1 join t2 on t1.id = t2.id

    就是说会让一些操作提前执行来减少中间过程的数据,也就是优化的过程。

    3.join策略的选择(自己了解)

    index netxt roup、block next roup,

    mysql语句前加上extern就会展示这条语句的执行计划,能大概读懂

    事务也是区分关系型数据库与nosql的指标

    3. 分布式数据库

    产生分布式数据库的原因,最重要的有两个:

    1.单机的硬盘容量(可能还包括内存容量、cpu容量、网络容量)不够,需要存储到多块硬盘上

    2.安全性原因,数据库存到多个地方备份

    RAID磁盘阵列的出现与分布式数据库的出现相似,一个是空间,一个是安全,

    RAID0的概念是把数据拆开存储在两块硬盘上,比如C盘数据存储在A上,D盘存储在B上,RAID1的概念是把数据复制存储在两个地方,比如CD盘在A盘上存一份,也在B盘上存一份。

    RAID01或者RAID10就是把两者结合起来,数据既分块,又对每块数据进行备份。

    对应到分布式数据库里面,就有了这样的概念:

    RAID0对应分布式数据库里的Partition(扩展性,一个分区不够,继续扩)

    RAID1对应分布式数据库里的Replication(安全性,一个挂了,不会掉数据)

    如何将数据复制到不同的地方去?

    1.异步?

    2.同步?

    假设有两块磁盘0和1(或者就是两个数据库),那如何保证两个数据是完全一样的?

    一种方式是同时向两个地方写,写完就是成功了;

    另一种方式是只写0,让0去写1,这就产生了如何返回数据写成功了?同步是0写完1才返回成功,

    异步是写完0就返回成功(如果此时就去读1就会出现还没有写入的数据,就会出现延迟,好处是不用等所有的库都写完,它的写入的延迟会低一些),这是两个点的情况,如果有更多的点(就是把一个点的数据复制了好几份),则就不能接受只有同步或者只有异步(只写一个点就返回)的情况了,就要把同步和异步结合起来,即每次同步写数个点后返回成功,剩下异步写剩下的点。

    那在分布式数据库中如何才能保证读到的数据是一致或者最新的呢?

    W+R>N,W代表同步写的个数,N表示总结点个数,即写的少,读的就越多,写的多,读的就越少。

    mysql是有主库和备库的区别的,主备库数据是完全一样的。内部的方案是读写都在主库,备库全部采用异步的方式备份。这是牺牲了备库的读性能来换取的,可以讲到同步的数据又不要同步的复制,来保证写的性能的提升。

    如果主库挂掉的话,怎么从剩下的备库中选举主库呢?大多是用PAXOS算法或者衍生的算法来选举主库,主要原理是获取多数支持的那一个才能是主库。这样就是自动的的过程,内部往往简单粗暴的,当主库挂掉的时候人工选择一个备库当主库。

    partition和replication在单机数据库中也是存在的,在单机数据库是也有分区表的概念,虽然是同一个机器,也会把表分成了好几个部分, 在单机数据库里面也会用磁盘陈列的方式做一些冗余,在单机数据库里也会这两种概念,那在分布式数据库要把这两点单独的拿出来说呢?最重要的是因为分布式数据库多了网络,延迟变大了,在单机里cpu总线的延迟是纳秒级,走网络的话延迟可能是毫秒级的。正是因为有延迟在在分布式数据库中才会把这两个东西单独拿出来说。

    以上主要是replication的讲解;

    partition的讲解在tddl里;

    4. Taobao Distributed Data Layer

    TDDL产生背景:

    单一数据库无法满足性能需求(数据切分 读写分离(只写主库只读备库))

    容灾(主备切换)

    配置变更(动态数据源(不需要数据库的账号信息,哪天数据库ip地址换了也没关系 只需要依赖appname tddl会自动地读取数据库账号用户名密码 当这些发生变更的时候会自动的通知到tddl,对用户无感知))

    切分有两种水平切分和垂直切分

    垂直切分不能无限切分, 因为列是有限的,而水平切分是可以无限扩展的, 只要行数是无限的。tddl能做的就是水平拆分,因为垂直拆分就是sql中的join操作

    主备切换也是tddl的功能,当主库挂掉的时候,会自动切换到备库上。

    水平拆分不一定按照id字段来拆,也可以选择其他字段,比如某个字段全是字符串,可以先求出它的hash值,再对1024取模(假如拆了1024张表,此时也可以再对表进行分库,如0-155属于库1),总之要按照字段本身的特点。

    这就是所谓的拆分算法。

    分布式数据库都会有两个特点一个是partition,一个是replication.

    那么hbase使用了一种B树的拆分方式,也就是说hbase各个存数据的节点(也就是分表的表)可以看作B树里面的一个节点,它在路由的时候就会根据树的算法来算出这条数据应该在哪一个节点里面,因为它使用了树,所以它继承了树的一些特点,所以在hbase中可以很方便来做一些范围的查询, 比如rowkey大于一个值或者小于一个值。但tddl默认使用的是一种hash算法,就很难做一个范围的查询, 比如1-1000在hbase中可能也就跨了几个分区布局,但是如果在tddl中可能就跨了所有的分区,因为hash算法是一种零散的算法。但为什么内部会默认使用hash算法来分表呢,因为内部经常做的操作是根据买家id\卖家id\羊肉串id\定单id来查,这样的话用hash算法就比较快。

    拆分字段的选择跟选索引差不多,选拆分字段的时候基本会选查询都会带上的那种列,比如说买家id卖家id,还有就是区分度的概念,用这个字段会路由到比较少的表中,而不是会路由1000张表。但如果像定单这种东西,它既有买家id又有卖家id,同时买家和卖家都会去关注,那选个字段作为拆分字段呢? 答案是两个都选,数据复制一份,一份按买家id来路由分表,另一份按卖家id来进行路由分表,也就是数据会存两份,相对应的我们就可以把买家和卖家理解为两种索引,因为是两种映射嘛。并且这种索引也可以做成聚簇,也可以做成非聚簇的,比如说在冗余的时候按所有字段进行冗余一遍,这样在查的时候就会查的比较快。

    规则路由—扩容

    怎样扩容才能减少数据的移动,比如以前是模32,现在变成模40了,就要把以前的结果按40重新模一遍,怎样选择才能减少数据移动呢?

    一般做法是一倍一倍的扩,比如以前是32,扩容后就变成64了。因为这种情况下只有一半的数据是需要移动的。

    多维拆分实际是把数据按照两维度冗余了一份

    组合索引就是先按一个列索引,再按另一个列索引

    多个字段同时作为拆分字段,实际上数据只存了一份

    两个字段就是二维,只提供一个字段就会定位到好几个张分表

    三个字段就是三维

    tddl三层数据源

    最底层是atom层,对应的是一个数据库,对应的就是一个ip用户名密码,一主一备就构成了第二层,就会变成一个group,同一个group会包含多个atom,但atom数据是一样的,也就是说group会完成读写分离这样一个操作,也可以完成主备切换,这两层就是绝大数应用使用的模型,因为绝大多数应用是小应用不需要做拆分,只要做读分离和主备切换这样的功能。多个group之后会组成一个matrix层,当我们分库之后,多个库会组成一个matrix,matrix层负责来做切分这样一个操作,就会有规则计算这样一个功能,就会算出sql应该到哪个group去。这就是tddl三层数据源的一个概念。

    TDDL5分为三层数据源结构

    Matrix,主要负责数据的水平切分

    Group,主要负责主备与读写分离

    Atom,主要负责物理数据源的管理

    TDDL5中一个查询操作在三层数据源中的流程如下图:

    048b6a089b43a4c5bb2c28795dbbd67c.png

    使用者通过JDBC,将SQL传递到TDDL5中,会按照以下流程进行执行:

    SQL Parser会将SQL解析并生成关系查询树;

    Query Optimizer对关系查询树进行优化,生成由KV查询组成的执行计划;

    在这个过程中,还将根据切分规则,对条件id=2与id=3进行计算,得出数据所在的节点。如在此例中,根据id % 3,得出id=2的数据在Group1上,id=3的数据在Group0上;

    Client会将执行计划发送给Matrix层,Matrix层会按照执行计划中指定的Group,将执行计划发送给对应的Group,在Group层,由于非强一致的读请求,会将读操作随机分配到数据节点Atom上;

    最终数据在Matrix上进行合并之后,结果返回给Client。

    matrix层:

    Parser

    Optimizer

    语法解析

    规则计算

    查询优化

    Executor

    聚合/Join/函数计算

    Repo(存储层)

    Mysql

    Group:主备切换,读写分离

    Atom:动态数据源

    Oceanbase/Hbase/Skiplist/Search(支持多存储)

    TDDL的查询优化器有一个最为核心的理念:offload,也是单机优化器里面讲到的一个基本的概念主是下推,下推的意思就是说尽量多的操作会让mysql自己去执行,比如说一些条件的过滤,一些join能让mysql去做的话就让它先来做,比如说索引选择,列的过滤,一些聚合函数的计算,一些排序,一些distinct去重这样的操作,能让mysql来做就让它来做,为什么呢?和单机数据库一样的道理,尽量减少中间数据,减少跨网络的延迟,offload的思想也是贯穿tddl基本的理念。也是tddl最佳实践最基本的思想。

    展开全文
  • tddl原理与架构

    2014-07-15 18:13:04
    TDDL 简单原理与架构 TDDL 使用 TDDL SEQUENCE原理与使用 控制中心JADE介绍 YUGONG动态数据复制组件介绍
  • TDDL

    2017-01-06 15:24:00
    2019独角兽企业重金招聘Python工程师标准>>> ...

    TAOBAO DISTRIBUTE DATA LAYER

    http://www.tuicool.com/articles/nmeuu2

    转载于:https://my.oschina.net/u/1445816/blog/819987

    展开全文
  • Tddl是一个分布式数据库中间件,主要是为了解决分布式数据库产生的相关问题,因此在学习tddl之前我们先了解一下分布式数据库的演化历程,所谓磨刀不误砍柴工,知其然亦要知其所以然,分布式数据库与数据库中间件...

    一、分布式数据库的演化

    Tddl是一个分布式数据库中间件,主要是为了解决分布式数据库产生的相关问题,因此在学习tddl之前我们先了解一下分布式数据库的演化历程,所谓磨刀不误砍柴工,知其然亦要知其所以然,分布式数据库与数据库中间件息息相关,了解学习是很有必要的。整个分布式数据库的演化过程如下:

    \

    1、单库单表

    通常刚开始的时候,应用的数据比较少,也不会很复杂,所以应用只有一个数据库,数据库中的业务表是一张对应业务的完整的表,这也是我们刚开始接触数据库时的数据库形态。

    2、读写分离

    随着业务的发展,数据量与数据访问量不断增长,很多时候应用的主要业务是读多写少的,比如说一些新闻网站,运营在后台上传了一堆新闻之后,所有的用户都会去读取这些新闻资讯,因此数据库面临的读压力远大于写压力,那么这时候在原来数据库 Master 的基础上增加一个备用数据库 Slave,备库和主库存储着相同的数据,但只提供读服务,不提供写服务。以后的写操作以及事务中的读操作就走主库,其它读操作就走备库,这就是所谓的读写分离。

    读写分离会直接带来两个问题:

    1)数据复制问题

    因为最新写入的数据只会存储在主库中,之后想要在备库中读取到新数据就必须要从主库复制过来,这会带来一定的延迟,造成短期的数据不一致性。但这个问题应该也没有什么特别好的办法,主要依赖于数据库提供的数据复制机制,常用的是根据数据库日志 binary-log 实现数据复制。

    2)数据源选择问题

    读写分离之后我们都知道写要找主库,读要找备库,但是程序不知道,所以我们在程序中应该根据 SQL 来判断出是读操作还是写操作,进而正确选择要访问的数据库。

    3、垂直分库

    数据量与访问量继续上升时,主备库的压力都在变大,这时候可以根据业务特点考虑将数据库垂直拆分,即把数据库中不同的业务单元的数据划分到不同的数据库里面。比如说,还是新闻网站,注册用户的信息与新闻是没有多大关系的,数据库访问压力大时可以尝试把用户信息相关的表放在一个数据库,新闻相关的表放在一个数据库中,这样大大减小了数据库的访问压力。

    垂直分库会带来以下问题:

    1)ACID 被打破

    数据分到不同的数据库之后,原来的事务操作将会受很大影响,比如说注册账户的时候需要在用户表和用户信息表中插入一条数据,单机数据库利用事务可以很好地完成这个任务,但是多机将会变得比较麻烦。以下两点也是因为数据库在不同的机子上而导致简单的操作变得复杂。

    2)Join 操作困难

    3)外键约束受影响

    4、水平分表

    经过长时间积累,特别对于 ugc 的业务,数据量会达到惊人的地步,每张表存放着大量的数据,任何 CRUD 都变成了一次极其消耗性能的操作,这个时候就会考虑水平分表,把一张表内大量的数据拆分成多张子表,比如说原来一张表中存放 50000 条数据,水平分成 5 张表之后,每张表只要存放 10000 条数据。这种结构可以比较容易的存储和维护海量数据。

    水平分表会在垂直分库的基础上带来更多的影响:

    1)自增主键会有影响

    这个影响很明显,分表中如果使用的是自增主键的话,那么就不能产生唯一的 ID 了,因为逻辑上来说多个分表其实都属于一张表,自增主键无法标识每一条数据。

    2)有些单表查询会变成多表

    比如说 count 操作,原来是一张表的问题,现在要从多张分表中共同查询才能得到结果。

    二、TDDL介绍

    1、产生背景

    由一中可以看出,数据库从单机走向分布式将会面临很多很多的问题,分布式数据库中间件就是为了解决这些问题而生的。Tddl作为开源分布式数据库中间件之一,由阿里研发,其出现解决了以上分布式数据库需求带来的问题,总结起来如下:

    1)单一数据库无法满足性能需求

    随着业务的发展,数据量急剧增大,使用单库单表时,数据库压力过大,因此通过分库分表,读写分离的方式,减轻数据库的压力。

    2)系统容灾

    使用单机数据库时,如果数据库宕机,则无法对外提供服务,因此产生了主备数据库的方案,当主库宕机后,会自动切换到备库,不影响对外的服务。

    3)运维管理

    直接连接单机数据库时,无法动态的切换数据源,使用TDDL中间件,可以动态的切换数据源。

    2、发展史

    1)TDDL 2.0 (2009~2011) 第一个流行版本

    2)TDDL 3.1 (2012~) 规则版本升级

    3)TDDL 3.3 (2013~) 引入druid链接池

    4)Andor (2012~2013) 一次全新的尝试,支持跨库查询

    5)TDDL 5.0 (2013) 基于Andor + TDDL3.3的发展而来,保留各自的优点

    6)TDDL 5.1 (2014~) 集成cobar,提供server模式,解决跨语言查询

    三、TDDL原理解析

    1、整体结构

    1)包结构

    \

    2)模型结构

    Tddl主要部署在ibatis、mybatis或者其他ORM框架之下,JDBC Driver之上。整个中间件实现了JDBC规范,所以可以将Tddl当做普通数据源实例并且注入到各种ORM框架中使用。由下图中的结构模型图可以看出,tddl是JDBC或者持久框架层与底层JDBC驱动交互的桥梁,或者也可以称之为中转站,起到进出的加工作用。

    \

    3)分布式数据库逻辑结构

    分布式数据库在经过读写分离和分库分表之后,数据库的结构变得复杂,逻辑上大致如下图所示:

    \

    除了最底层的物理DB,上两层的逻辑层是分布式数据库中间件着重要解决的问题,tddl的设计亦是以图中的三层逻辑模型为基础进行的。为了解决每一层所要应对的问题,tddl在结构上至上而下也分了三层,分别是 Matrix 层、Group层以及 Atom 层。具体来说,从逻辑上来看,最顶层是要进行分库分表才过渡到中间层的,分库分表所带来的问题是在 Matrix 层解决 ,包括SQL解释、优化和执行等;中间层是经过读写分离和主备切换才会出现最底层,因此读写分离与主备切换的工作由 Group 层解决;至于 Atom 层,它面对的是实实在在的每一个数据库,更多的工作在与对数据库的连接管理,比如说当数据库的 IP 地址发生改变时,Atom 层要动态感知,以免连接找不到地址。

    2、三层数据源结构(核心组件

    TDDL作为中间件,其作用是根据路由规则,将sql路由到正确的分库、分表上去执行,再将结果进行汇总,返回给用户,对于用户,不需要了解TDDL的原理,可以像使用单库单表一样去使用分布式数据库。在解析执行和封装这些类似于单库单表的SQL语句时,tddl有专门的组件来进行处理,这些组件就是核心的三层数据源,分别是Matrix层、Group层以及Atom层,其结构如下图所示:

    \

    1)Matrix层

    该层功能在于分库分表路由,SQL语句的解释、优化和执行,事务的管理规则的管理,各个子表查询出来结果集的Merge等。

    如上所述,Matrix 层可以解决分库分表带来的问题,从本质上来看,分库分表带来的最直接的影响是数据访问的路由。单库单表的时候,什么都不用想,就是去这个 DB 中找到这张 Table 再进行查询,但是多库多表的时候就必须要考虑数据存到哪个数据库,为什么要存到这个数据库诸如此类的问题。这里面涉及到数据访问路由算法,它规定了数据的存储位置,同样也由它来指明该去哪里查询数据,常见的数据访问路由算法有以下几种:

    a)固定哈希算法

    固定哈希就再简单不过了,就是根据某个字段(如整形的 id 或者字符串的 hashcode)对分库的数量或者分表的数量进行取模,根据余数路由到对应的位置。下面图中的例子,数据库垂直拆分成 4 个,其中有一张表水平拆分成两张,利用固定哈希算法进行路由的过程如下:

    b)一致性哈希算法

    固定哈希算法足够简单实用,基本能保证数据均匀分布,它也是 TDDL 的默认路由算法,但是在数据库扩容的时候,固定哈希算法带来的数据迁移成本也是不得不考虑的。依然是上面的例子,数据库拆分成 4 个,当需要增加数据库的时候,假设变成 5 个,由于取模的结果发生变化,原来数据库中的绝大部分数据都要进行迁移,只有在数据库倍增的时候,数据迁移量才是最少的,但也高达 50%,而且倍增的成本比较高。

    所以一致性哈希算法应景而生,它的原理就是通过该算法计算出 key 的 hashcode 之后对 2^32 取模,那么数据都会落在 0~2^32 所组成的环中;同样的,可以利用一致性哈希算法对机器的唯一属性计算所在位置,然后数据存储在顺时针方向最近的机器上。如图所示:

    \

    对于一致性哈希,增删机器的成本就降低很多了,比如说在上图 node2 与 node4 之间增加一台机器 node5,那么需要迁移的数据只分布在 node2 与 node5 之间,相比固定哈希来说迁移量小了很多。

    \

    c)虚拟节点

    一致性哈希已经可以解决大部分需求了,但是对于数据集中在热点的情况,一致性哈希同样面临比较大的挑战。比如说,上图的 node2 与 node4 之间集中了整个环中的大部分数据,当加入 node5 之后,其实起到的效果比较有限,因为还是要有大量的数据进行迁移。引入虚拟节点之后,情况就不一样了,所谓虚拟节点,它就是物理节点的映射,一个物理节点可以复制出多个虚拟节点,尽可能的让它均匀分布在环上,那么即使数据再集中,其实也会存储在不同的节点上,很好地起到了负载均衡的作用。

    d)自定义路由规则

    这是最不常用的方法,不过 TDDL 也支持,你可以实现自己的算法进行数据访问路由,但一般要么效果很差要么成本很高。

    2)Group层

    该层的作用在于数据库读写分离,基本上主数据库负责读写,备份数据库只负责读;主备切换状态对调后备库变为主库,主库变为备库;权重的选择 根据权重选择要去读哪些库;数据保护,数据库down掉后的线程保护, 数据库挂掉后的线程保护,不会因为一个数据库挂掉导致所有线程卡死。

    读写分离与主备切换带来的问题是 Group 层解决的核心。首先简单介绍一下主备切换,由于主库或者备库都有可能挂掉,但很小概率同时挂,所以当一方挂掉的时候,Group 层要马上把流量切到另一个库,保证挂掉一个不会让应用挂掉。

    读写分离最大的问题是数据复制,通常有两种复制场景,一种是镜像复制,即主库和从库的数据结构是一模一样的,通常根据主库上的日志变化,在从库中执行相同的操作;另外一种是非对称复制,意思就是主库与备库是以不同的方式分库的,它们的结构虽然相同,但是主备库中存储的记录是不相同的,主要目的是查询条件不同时,把请求分发到更加适合的库去操作。举个例子,对于订单数据库,买家会根据自己的 ID 去查自己的交易记录,所以主库可以用买家 ID 分库,保证单个买家的记录在同一个数据库中;但是卖家如果想看交易记录的话可能就得从多个库中进行查询,这时候可以利用卖家 ID 进行分库作为备库,这样一来主备库的复制就不能简单的镜像复制了,在进行复制操作之前还需要进行路由。

    3)Atom层

    Atom 模块真正和物理数据库交互,提供数据库配置动态修改能力。

    改层负责动态创建,添加,减少数据源。管理着底层的数据库IP,连接等信息;底层对物理数据库做了代理,对单库的JDBC做了一层封装,执行底层单库的SQL;线程数、执行次数等状态的统计等。

    3、执行流程

    1)执行流程

    \

    TDDL的工作流程类似上图,client发送一条SQL的执行语句,会优先传递给Matrix层。由Martix 解释 SQL语句,优化,并根据查询条件路由到各个group,转发sql进行查询,各个group根据权重选择其中一个Atom进行查询,各个Atom再将结果返回给Matrix,Matrix将结果合并返回给client。具体的工作流程的可以拆分成如下图:

    \

    Matrix层会先执行以下四个过程:

    a)Sql的解析。首先将Sql语句解析成一颗抽象语法树(Abstract Syntax Tree),解析成我们比较好处理的一个结构

    b)规则的匹配与计算。基于上一步创建的语法树查找匹配的规则,再根据规则去确定分库分表的结果。这里有一个概念就是规则,规则这里可以简单的看做就是定义数据库怎么进行分库分表,要分成几张库几张表,库名和表名的命名是怎么样的。规则的匹配就是根据SQL的语句确定,具体查询的子表是哪几张。

    c)表名替换。对于开发人员来说,它查询的表直接就是select * from A.B limit 10(A为数据库名,B为数据表名)。但底层其实会把这些表名替换成类似select * from A_000.B_001,select * from A_000.B_002,select * from A_001.TABLE_001这样的形式。表名替换就是把总表的名称替换为这些子表的名字。

    d)Sql的转发。将上一步生成的各个sql语句转发到对应的Group进行执行。这里如上图,我查询的条件是where id = 2 or 3。那么转发给Group0的查询为where id=3,转发给group1的查询为where id =2 。查询的条件也会发生一定修改。

    这样四个步骤可以在Matrix层就实现了分库分表的功能,对原始的Sql进行分解,将原本单库单表的查询语句,底层转发到多库多表并行的进行执行,提高了数据库读写的性能。

    接下来由Group执行两个过程:

    e)根据权重选择AtomDs。通常会在主节点和副节点上读取数据,只在主节点上写入数据。

    f)具有重试的策略地在AtomDs上执行SQL。这个可以防止单个的AtomDs发生故障,那么会进入读重试,以确保尽可能多的数据访问可以在正常数据库中访问。

    然后是Atom层执行两个过程:

    g)读写数控制、线程并发数控制 。同时会统计线程数、执行次数等信息。

    h)执行sql,返回结果集。Atom底层利用druid进行连接池的管理,具体查询还是对JDBC做了一定封装。执行完Sql后对将结果返回给Matrix。

    最后Matrix执行最后一个过程:

    i)结果集合并。Matrix将Atom层的返回的各个结果集进行合并Merge,返回给Client端。

    2)路由与扩容(固定哈希算法为例)

    a)数据库水平拆分路由

    \

    f(pavarotti17)= hash(pavarotti17) % 1024,然后根据该值找对应的DB,

    \

    b)扩容

    固定哈希算法是常用的算法,其扩容一般推荐每次以2倍的形式扩容,这样只需要迁移一半的数据。

    \

    4、Senquence全局唯一id标识生成原理

    1)背景

    目前基于tddl进行分库分表后,原本一个数据库上的自增id的结果,在分库分表下并不是全局唯一的。所以,分库分表后需要有一种技术可以生成全局的唯一id。

    2)工作原理

    a)主要职责

    生成全局唯一的id;保持高性能;保持高可用。

    b)目前常见的几种全局ID的思路

    方案一

    oracle sequence:基于第三方oracle的SEQ.NEXTVAL来获取一个ID

    优势:简单可用。

    缺点:需要依赖第三方oracle数据库。

    方案二

    mysql id区间隔离:不同分库设置不同的起始值和步长,比如2台mysql,就可以设置一台只生成奇数,另一台生成偶数. 或者1台用0~10亿,另一台用10~20亿.。

    优势:利用mysql自增id 。

    缺点:运维成本比较高,数据扩容时需要重新设置步长。

    方案三

    基于数据库更新+内存分配:在数据库中维护一个ID,获取下一个ID时,会对数据库进行ID=ID+100 WHERE ID=XX,拿到100个ID后,在内存中进行分配 。

    优势:简单高效。

    缺点:无法保证自增顺序。

    目前tddl sequence也是选择的方案3进行实现,但会有几点额外的要求:

    a. 只要生成id的数据库不全部挂掉,均可以顺畅提供服务;

    b. 生成id的数据库数量不定,按照应用对容灾的需求指定不同机架不同机房的数据库; (比如需要考虑单元化多机房的id生成)

    c. 支持生成id的数据库hang住快速略过和恢复自动加入 。

    总结一下:生成id的数据库可以是多机,其中的一个或者多个数据库挂了,不能影响id获取,保证严格高可用。

    目前我们针对多机的id生成方案: 每个数据库只拿自己的那一段id,如下图左:

    \

    sample_group_0-sample_group_3是我们生成全局唯一id的4个数据库,那么每个数据库对于同一个id有一个起始值,比如间隔是1000。

    应用真正启动的时候,可能某一台机器上去取id,随机取到了sample_group_1,那么这台机器上的应用会拿到1000-1999这一千个id(批量取,这个也就保证了应用端取id性能),而这个时候4个数据库上id起始值会变成右图所示,你也许注意到了,下次从sample_group_1上取得的id就变成了4000-4999。那么也就是这样,完全避免了多机上取id的重复。比如sample_group_1他会永远只会取到1000-1999,4000-4999,8000-8999,12000-12999…其他数据库也一样,相互不会重叠。

    这种产生全局唯一id的方式相当有效,保证基本的全局唯一特性和高性能的同时,可以对生成id的数据库分机架分机房部署达到容灾的目的。

    3)配置

    ?

    1

    2

    3

    4

    <bean class="com.taobao.tddl.client.sequence.impl.GroupSequence" id="sequence" init-method="init">

    <property name="sequenceDao" ref="sequenceDao_one_db">

    <property name="name" value="ni">

    </property></property></bean>

    5、tddl适用场景

    1)高并发实时交易场景

    面向客户端的电商、金融、O2O、零售等行业普遍存在用户基数大、营销活动频繁、核心交易系统数据库响应日益变慢的问题,制约业务发展。 TDDL 提供线性水平扩展能力,能够实时提升数据库处理能力,提高访问效率,峰值 TPS 达150万+,轻松应对高并发的实时交易场景。

    2)海量数据存储访问场景

    企业客户随着业务的快速发展,业务数据增长迅猛,会产生超过单机数据库存储能力极限的数据,造成数据库容量瓶颈,限制业务发展。 TDDL 可以线性扩展存储空间,提供 PB 级存储能力,可广泛应用于工业制造、智能家居、车联网等超大规模数据存储访问场景。

    3)高性价比数据库解决方案

    初创型企业初期发展阶段技术积累相对比较薄弱,资金投入有限,业务发展快,数据库的稳定性风险高。TDDL 继承了阿里巴巴多年的分布式数据库技术积累,能够提供简单易用的数据库运维系统,降低企业的技术运维成本,赋予企业强大的数据库支撑能力。

    当业务数据和访问量增加到一定量时,如政务机构、大型企业、银行等行业为了支持大规模数据存储和高并发数据库访问,传统方案需要强依赖小型机和高端存储等高成本的商业解决方案,以达到扩展服务能力的目的。TDDL 能够利用普通服务器提供阿里巴巴双十一同等处理能力的高性价比国产数据库解决方案。

    4)数据存储平滑扩容

    当应用单机存储(MySQL)出现容量或性能瓶颈时,TDDL 提供在线数据扩容功能(该功能需要结合阿里其它内部中间件使用)。传统数据库容量扩展往往意味着服务中断,很难做到业务无感知或者少感知。

    展开全文
  • 淘宝TDDL

    2018-09-04 18:26:38
    com.taobao.tddl.rule.le.GomePosUat.v_1.0.0   com.taobao.tddl.rule.le.GomePosUat.v_1.0.0   com.taobao.tddl.v1_GomePosUat_dbgroups       ...
  • 分布式数据库中间件—TDDL

    千次阅读 2018-06-05 21:15:20
    项目中一直在用着TDDL,但除了接入时简单了解了下他的用法和原理外,也没有过多的深究其背后的实现,毕竟在阿里内部用到的中间件太多,每一个都深入的学习需要的周期太长,再者项目中数据库层也没有用到分布式,没有...
  • mysql中间件研究(Atlas_cobar_TDDL)
  • Spring源码分析之TDDL

    2020-11-24 22:12:30
    其实tddl的实现逻辑并不难,就是创建多个datasource数据源,然后通过一个Datasource代理类统一控制每次调用哪个数据源。而datasource数据源可以不是真实的数据源,而是连接池比如Druid。所以tddl可以说只是一个类似...
  • 总体描述TDDL动态数据源主要分为2层,每一层都实现了jdbc**规范**,以方便地集成到各种orm框架或者直接使用.每一层都各司其职.TGroupDataSource(tddl group ds)默认情况下依赖TAtomDataSource(tddl atom ds),但是可以...
  • 2、发展史 1)TDDL 2.0 (2009~2011) 第一个流行版本 2)TDDL 3.1 (2012~) 规则版本升级 3)TDDL 3.3 (2013~) 引入druid链接池 4)Andor (2012~2013) 一次全新的尝试,支持跨库查询 5)TDDL 5.0 (2013) 基于Andor + ...
  • 分布式数据库中间件 TDDL 学习笔记

    万次阅读 2019-04-26 18:12:37
    之前介绍过从分库分表到数据访问层中间件,Tddl是一个分布式数据库中间件,它在阿里内部被广泛的使用,主要是为了解决分布式数据库产生的相关问题,分布式数据库与数据库中间件息息相关。最近三年社区最流行的是...
  • 前言在开始讲解淘宝的TDDL(Taobao Distribute Data Layer)技术之前,请允许笔者先吐槽一番。首先要开喷的是淘宝的社区支持做的无比的烂,TaoCode开源社区上面,几乎从来都是有人提问,无人响应。再者版本迭代速度也...
  • Atom层(可独立使用) ...tddl-sample/src/main/resources/rule_local/tddl-rule.xml xml   version = "1.0"   encoding = "gb2312" ?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" " ...
  • TDDL使用

    千次阅读 2016-12-12 16:43:03
     在tddl 的ops中->TDDL配置管理->新增配置,然后将编写的规则文件内容复制进去,提交即可  2)本地配置  将规则文件放置在项目路径中即可 3.创建应用  (1)添加依赖 ...
  • 分库分表之淘宝TDDL的原理

    千次阅读 2019-01-09 15:35:28
    淘宝TDDL的原理一、互联网当下的数据库拆分过程二、TDDL的架构原型三、下载TDDL的Atom层和Group层源代码四、Diamond简介五、Diamond的安装和使用六、动态数据源层的Master/Salve读写分离配置与实现七、Matrix层的分...
  • TDDL分库分表规则

    2021-02-05 22:08:29
    规则如下:判断一个ID在哪个库里的公式是:id % 4 / 2判断一个ID在哪个表里的公式是:id % 4 % 2其中4表示总共有多少个分表,2表示总共有多少个数据库;上面这个例子,表示总共有2个数据库,每个数据库有2个分表,...
  • 阿里巴巴TDDL

    万次阅读 2017-03-01 10:56:12
    阿里巴巴 TDDL Diamond
  • 布式数据库中间件TDDL、Amoeba、Cobar、MyCAT架构比较分比较了业界流行的MySQL分布式数据库中间件,关于每个产品的介绍,网上的资料比较多,本文只是对几款产品的架构进行比较,从中可以看出中间件发展和演进路线...
  • 淘宝分布式数据层TDDL

    2018-06-13 17:55:00
    剖析淘宝TDDL(TAOBAO DISTRIBUTE DATA LAYER) 注:原文:http://gao-xianglong.iteye.com/blog/1973591 前言 在开始讲解淘宝的TDDL(Taobao Distribute Data Layer)技术之前,请允许笔者先吐槽一番。首先要开...
  • TDDL实践

    2018-10-12 17:36:00
    数据源配置,tddl的入口,从datasource切入 <bean id="tddlDataSource" class="com.taobao.tddl.client.jdbc.TDataSource" init-method="init"> <property name="appName" value="tddl_sample" ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,428
精华内容 2,571
关键字:

TDDL