我们需要什么样的数据库
1.一键水平扩缩容
2.强一致性高可用性
3.支持标准sql,支持acid事务
4.实时 HTAP(Hybrid Transactional/Analytical Processing)
5.兼容主流生态与协议
6.云原生的 发挥云计算的优势并适应云环境的特点
实时 HTAP(Hybrid Transactional/Analytical Processing)是一种数据处理模式,结合了事务处理(Transactional Processing)和分析处理(Analytical Processing)的能力,并且能够在实时或近实时的情况下进行。这种模式旨在实现在同一系统中同时支持事务处理和复杂分析查询的能力。
传统上,事务处理和分析处理是在不同的系统中进行的。事务处理通常涉及对数据库中的数据进行增删改操作,旨在保持数据的一致性和完整性。而分析处理则是从大数据集中进行复杂的查询和分析,以获取洞察力和支持决策。
实时 HTAP的目标是通过将事务处理和分析处理合并到同一系统中,提供更高的数据处理效率和更快的响应时间。它允许用户在进行事务处理的同时进行实时的分析查询,而无需将数据复制到不同的系统中。
数据技术栈领域常见的基础因素
1.数据模型:关系模型(mysql表),文档模型(json,xml),KV模型
2.数据存储与检索结构:B-Tree B+Tree,LSM-Tree,跳表,红黑树
3.数据格式:结构化数据,非结构化数据,半结构化数据
4.存储引擎:Innodb,RockDB
5.复制协议:Raft,Paxos,ZAB协议
6.分布式事务模型:XA-2PC(两阶段提交),3PC(两阶段提交,增加了超时)
7.数据架构:计算引擎共享一份数据或者每个都有一份数据
8.优化器算法:根据数据分布和统计信息生成成本最低的执行计划
9.执行引擎:火山模型,向量化,大规模并行计算
10.计算引擎:是否是一个标准的sql引擎
Raft将分布式系统中的节点划分为三个角色:Leader(领导者)、Follower(跟随者)和Candidate(候选者)。其中Leader负责处理客户端请求,并将数据复制到其他节点;Follower和Candidate则负责接收Leader的指令,并按照Leader的指令进行操作。
Raft的核心思想是通过选举机制来确保系统中只有一个Leader,从而保证数据的一致性。选举过程分为两个阶段:选举和复制。
在选举阶段,当系统启动或者Leader失效时,节点会自动转变为Candidate,并向其他节点发送选举请求。其他节点收到请求后,会比较自己的任期(Term)与Candidate的任期,如果Candidate的任期更大,则将自己转变为Follower,并投票给Candidate。如果Candidate收到了大多数节点的选票,就成为新的Leader。如果选举过程中出现了多个Candidate收到相同选票数的情况,那么就会进行新的选举,直到只有一个Candidate成为Leader。
在复制阶段,Leader负责处理客户端请求,并将数据复制到其他节点。当Leader收到客户端的请求,首先将请求写入自己的日志(Log)中,并将该日志复制给其他节点。一旦大多数节点确认接收并复制了该日志,Leader将该日志应用到自己的状态机,并将结果返回给客户端。其他节点也会按照Leader的指令将该日志应用到自己的状态机。
Raft通过Leader选举和日志复制等机制,实现了分布式系统的强一致性。它具有简单、易理解和可验证的特点,适用于各种分布式系统场景。
网络硬件的升级,带宽的提升,计算与存储分离是趋势
因为计算和存储强绑定,两种资源会有一种浪费,服务器选型会纠结是计算型还是存储型,降低通用型。分离后计算节点和存储设备可以独立扩展,以提高系统性能
TiDB 简介
TiDB一款开源分布式关系型数据库,具有上面的优点
TiDB 应用场景
1.海量数据及高并发
2.实时 HTAP 场景
3.金融行业场景对
数据一致性及高可靠、系统高可用、可扩展性、容灾要求较高
TiDB整体架构
TiDB Service
负责接受客户端的连接,执行 SQL 解析和优化,最终生成分布式执行计划。TiDB 层本身是无状态的,实践中可以启动多个 TiDB 实例,通过负载均衡组件(如 LVS、HAProxy 或 F5)对外提供统一的接入地址,客户端的连接可以均匀地分摊在多个 TiDB 实例上以达到负载均衡的效果。TiDB Server 本身并不存储数据,只是解析 SQL,将实际的数据读取请求转发给底层的存储节点 TiKV(或 TiFlash)。
PD
整个 TiDB 集群的大脑
负责存储每个 TiKV 节点实时的数据分布情况和集群的整体拓扑结构,提供 TiDB Dashboard 管控界面,并为分布式事务分配事务 ID。PD 不仅存储元信息,同时还会根据 TiKV 节点实时上报的数据分布状态,下发数据调度命令给具体的 TiKV 节点,可以说是整个集群的“大脑”。此外,PD 本身也是由至少 3 个节点构成,拥有高可用的能力。建议部署奇数个 PD 节点。
TiKV 、TiFlash
Key-Value 形式存储数据,数据持久化
TiFlash 是一类特殊的存储节点,和普通 TiKV 节点不一样的是,在 TiFlash 内部,数据是以列式的形式进行存储,主要的功能是为分析型的场景加速。
经常暴力遍历的放在TiFlash
OLTP:实时的数据更新操作
OLAP:复杂的数据分析操作
本地存储 (RocksDB)
任何持久化的存储引擎,数据终归要保存在磁盘上,TiKV 也不例外。但是 TiKV 没有选择直接向磁盘上写数据,而是把数据保存在 RocksDB 中,具体的数据落地由 RocksDB 负责,可以简单的认为 RocksDB 是一个单机的持久化 Key-Value Map。
Raft 协议
想办法把数据复制到多台机器上,这样一台机器无法服务了,其他的机器上的副本还能提供服务
Raft 提供几个重要的功能:
Leader(主副本)选举
成员变更(如添加副本、删除副本、转移 Leader 等操作)
日志复制
总结一下
通过单机的 RocksDB,TiKV 可以将数据快速地存储在磁盘上;通过 Raft,将数据复制到多台机器上,以防单机失效。数据的写入是通过 Raft 这一层的接口写入,而不是直接写 RocksDB。通过实现 Raft,TiKV 变成了一个分布式的 Key-Value 存储,少数几台机器宕机也能通过原生的 Raft 协议自动把副本补全,可以做到对业务无感知。
Region
首先,为了便于理解,在此节,假设所有的数据都只有一个副本。前面提到,TiKV 可以看做是一个巨大的有序的 KV Map,那么为了实现存储的水平扩展,数据将被分散在多台机器上。对于一个 KV 系统,将数据分散在多台机器上有两种比较典型的方案:
- Hash:按照 Key 做 Hash,根据 Hash 值选择对应的存储节点。
- Range:按照 Key 分 Range,某一段连续的 Key 都保存在一个存储节点上。
TiKV 选择了第二种方式,将整个 Key-Value 空间分成很多段,每一段是一系列连续的 Key,将每一段叫做一个 Region,可以用 [StartKey,EndKey) 这样一个左闭右开区间来描述。每个 Region 中保存的数据量默认维持在 96 MiB 左右(可以通过配置修改)。
将数据划分成 Region 后,TiKV 将会做两件重要的事情:
- 以 Region 为单位,将数据分散在集群中所有的节点上,并且尽量保证每个节点上服务的 Region 数量差不多。
- 以 Region 为单位做 Raft 的复制和成员管理。
这两点非常重要:
先看第一点,数据按照 Key 切分成很多 Region,每个 Region 的数据只会保存在一个节点上面(暂不考虑多副本)。TiDB 系统会有一个组件 (PD) 来负责将 Region 尽可能均匀的散布在集群中所有的节点上,这样一方面实现了存储容量的水平扩展(增加新的节点后,会自动将其他节点上的 Region 调度过来),另一方面也实现了负载均衡(不会出现某个节点有很多数据,其他节点上没什么数据的情况)。同时为了保证上层客户端能够访问所需要的数据,系统中也会有一个组件 (PD) 记录 Region 在节点上面的分布情况,也就是通过任意一个 Key 就能查询到这个 Key 在哪个 Region 中,以及这个 Region 目前在哪个节点上(即 Key 的位置路由信息)。至于负责这两项重要工作的组件 (PD)
对于第二点,TiKV 是以 Region 为单位做数据的复制,也就是一个 Region 的数据会保存多个副本,TiKV 将每一个副本叫做一个 Replica。Replica 之间是通过 Raft 来保持数据的一致,一个 Region 的多个 Replica 会保存在不同的节点上,构成一个 Raft Group。其中一个 Replica 会作为这个 Group 的 Leader,其他的 Replica 作为 Follower。默认情况下,所有的读和写都是通过 Leader 进行,读操作在 Leader 上即可完成,而写操作再由 Leader 复制给 Follower。
mvcc
TiKV 的 MVCC 实现是通过在 Key 后面添加版本号来实现
注意,对于同一个 Key 的多个版本,版本号较大的会被放在前面,版本号小的会被放在后面
这样当用户通过一个 Key + Version 来获取 Value 的时候,可以通过 Key 和 Version 构造出 MVCC 的 Key,也就是 Key_Version。然后可以直接通过 RocksDB 的 SeekPrefix(Key_Version) API,定位到第一个大于等于这个 Key_Version 的位置。
参考pingcap官方文档:https://docs.pingcap.com/