TiDB in Action

简单笔记. 主要看结构和实现. 操作就不细看了.

架构

  • 计算层

    • tidb

      • sql

        • F1

        • 工作

          • sql parse

            • parse –> ast -> logical opt -> logical plan -> physical opt -> physical plan

          • 优化

            • 逻辑优化

              • 列裁剪

              • 分区裁剪

              • 聚合消除

              • Max/Min优化

                • max => select c from t order by c desc limit 1

              • 外连接消除

              • 外连接转内连接

              • 子查询去关联

              • 谓词下推

              • 聚合下推

              • TopN / Limit 下推

          • query plan生成

            • op

              • 映射到tikv的kv api

              • 逻辑算子(ds, SPJ)

                • DataSource

                • S(S)election

                • P(P)rojection

                • J(J)oin

        • 分布式sql

          • 核心是最大程度进行本地计算

          • scan,filter,aggregate下推 - 计算出一个细粒度的结果后通过上层归并

            • 避免通信(rpc),避免计算堆积到上层, 称为瓶颈.

      • 数据映射

      • table <-> kv

          • TableID

          • RowID

            • 如果表的主键是整数, 不用分配RowID,直接用这个主键

        • 存储

          • Key: tablePrefix{TableID}_recordPrefixSep{RowID}

          • Value: [col1, col2, col3, col4]

        • 索引

      • 无状态

      • 索引

        • 主键/二级索引

  • 元信息/调度

    • PD(placement driver)

      • 数据分布

        • region的分布, 确保大体均匀

          • 调度算法的参考指标?

      • 集群拓扑

      • dashboard

      • 元信息

        • 上报

          • tikv节点上报

            • 磁盘/可用磁盘/写入速度/region数/发送接受snapshot数/负载情况/标签

          • raft group

            • leader上报

              • leader位置

              • follower位置, 掉线

              • replica数量

              • 读写速度

        • 上报的信息作为调度的依据

      • 调度策略 TODO

      • 弹性调度 (elastic schedule)

  • 分布式存储

    • tikv

      • 支持接口层面的分布式事务

        • snapshot isolation

          • 出现写-写冲突, 事务abort

      • 本地存储

        • rocksdb

      • raft

        • 几个功能

          • leader selection

          • 成员管理

          • log replication

            • tikv利用这个做节点点数据复制

              • 一次数据变更 -> raft一条日志

      • sharding

        • 按range划分

        • Region概念

          • 连续key及值组成的片段

            • [start_key, end_key]

          • 默认大小96mb

        • 数据分布的基本单位

        • raft复制的基本单位

          • 一个region的多个节点, 配置一个raft group

      • mvcc

        • 结构

          • 基础

            • key -> value

          • mvcc

            • key_v1 -> value

            • key_v0 -> value

            • 版本号大的在前, 利用rocksdb的SeekPrefix找到最新数据

      • 分布式ACID

    • tiflash

      • 列式存储引擎(for olap)

数据映射示例

CREATE TABLE User {
    ID int, Name varchar(20), Role varchar(20), Age int, PRIMARY KEY (ID), Key idxAge (age)
};

-- 三行数据
1, "TiDB", "SQL Layer", 10
2, "TiKV", "KV Engine", 20
3, "PD", "Manager", 30

映射到key-value上, 表数据

t10_r1 -> ["TiDB", "SQL Layer", 10]
t10_r2 -> ["TiKV", "KV Engine", 20]
t10_r3 -> ["PD", "Manager", 30]

索引数据

t10_i1_10_1 --> null
t10_i1_20_2 --> null
t10_i1_30_3 --> null

与mysql的区别

https://pingcap-incubator.github.io/tidb-in-action/session1/chapter5/mysql-compatibility.html

事务模型

使用PD作为TSO(timestamp oracle), 来分配全局唯一,单调递增的版本号.

特点:

  • tso

  • mvcc

  • 2pc

    • prewrite

    • commit

过程

  1. 客户端开始一个事务。

  2. TiDB向 pd 获取 tso 作为当前事务的 start_ts。

  3. 客户端发起读或写请求。

  4. 客户端发起 commit。

  5. TiDB开始两阶段提交,保证分布式事务的原子性,让数据真正落盘。

    1. TiDB 从当前要写入的数据中选择一个 Key 作为当前事务的 Primary Key。

    2. TiDB 并发地向所有涉及的 TiKV 发起 prewrite 请求。TiKV 收到 prewrite 数据后,检查数 据版本信息是否存在冲突或已过期。符合条件的数据会被加锁。

    3. TiDB 收到所有 prewrite 响应且所有 prewrite 都成功。

    4. TiDB 向 PD 获取第二个全局唯一递增版本号,定义为本次事务的 commit_ts。

    5. TiDB 向 Primary Key 所在 TiKV 发起第二阶段提交。TiKV 收到 commit 操作后,检查数 据合法性,清理 prewrite 阶段留下的锁。

  6. TiDB 向客户端返回事务提交成功的信息。

  7. TiDB 异步清理本次事务遗留的锁信息。

并发控制策略

  • 乐观(OCC)

    • tx提交阶段检测冲突(进入prewrite后)

  • 悲观(PCC)

    • tx执行阶段检测冲突(prewrite前, 加入AcquirePessimistic Lock阶段)