当我们使用 Mysql
数据库到达一定量级以后,性能就会逐步下降,而解决此类问题,常用的手段就是引入数据库中间件进行分库分表处理,比如使用 Mycat、ShadingShpere、tddl,但是这种都是过去式了,现在使用分布式数据库可以避免分库分表
点击了解数据库之Sharding分库分表操作详解
那么为什么不建议分库分表呢,分库分表以后,会面临以下问题:
以上只是列举了一部分问题,为了避免这些问题,可以使用分布式数据库TiDB
来处理
TiDB
是 PingCAP
公司研发的一款开源分布式关系型数据库,从 2015年 9 月开源,至今已经有9 年时间,可以说已经非常成熟,它是一款同时支持OLTP
(在线事务处理)和OLAP
(在线分析处理)的融合型分布式数据库产品,具备水平扩缩容,金融级高可用、实时 HTAP(Hybrid Transactional and Analytical Processing)
、云原生的分布式数据库,兼容 MySQL 5.7
协议和 MySQL
生态等重要特性,它适合高可用、强一致要求较高、数据规模较大等各种应用场景。
核心特性:
HTAP
,提供TIKV
行存储引擎和TiFlash
列存储引擎MySQL协议
和MySQL生态
应用场景:
OLTP
场景SQL
层,对外暴露 MySQL
协议的连接 endpoint
,负责接收SQL
请求,处理SQL相关的逻辑,并通过PD找到存储计算所需数据的TiKV
地址,与TiKV
交互获取数据,最终返回结果。TiDB Server
是无状态的,其本身并不存储数据,只负责计算,可以无限水平扩展,可以通过负载均衡组件(LVS、HAProxy或F5)对外提供统一的接入地址,客户端的连接可以均匀地分摊在多个 TiDB
实例上以达到负载均衡的效果。
整个集群的管理模块,其主要工作有三个:
TiKV
集群进行调度和负载均衡、Leader
选举;PD
是一个集群,需要部署奇数个节点,一般线上推荐至少部署3个节点。PD
在选举的过程中无法对外提供服务,这个时间大约是3秒。
TiDB
现在同时支持OLTP
和 OLAP
,而TiKV
负责存储OLTP
数据,从外部看TiKV
是一个分布式的提供事务的Key-Value
存储引擎。存储数据的基本单位是Region
,每个Region
负责存储一个Key Range
(从StartKey到EndKey的左闭右开区间)的数据,每个TiKV节点会负责多个Region。
简单理解,就是把数据复制到多台机器上,这样一个节点down
机,其他节点上的副本还能继续提供服务;复杂理解,需要这个数据可靠并且高效复制到其他节点,并且能处理副本失效的情况,那怎么做呢,就是使用 Raft
一致性算法
Region
与副本之间通过 Raft
协议来维持数据一致性,任何写请求都只能在 Leader
上写入,并且需要写入多数副本后(默认配置为 3 副本,即所有请求必须至少写入两个副本成功)才会返回客户端写入成功。
TiKV
支持分布式事务,我们可以一次性写入多个 key-value
而不必关心这些 key-value
是否处于同一个数据切片 (Region
) 上,TiKV
的分布式事务参考了Google
在 BigTable
中使用的事务模型Percolator
支持的特性:
不支持的功能特性:
TIDB Server
的自增,不支持多个TIDB Server
的自增。资源使用情况:
TiDB
具有很高的数据压缩比,MySQL
中的 10.8 TB
数据在 TiDB
中变成了 3.2 TB,还是三副本的总数据量。因此,MySQL
与 TiDB
的空间使用比例为 3.4:1。
同等量级,使用2 年以后,资源使用情况
MySQL使用32 个节点,而 TiDB 只有 14 个
MySql 用了 512 个 CPU 核心,而 TiDB 将仅使用 224 个,不到 MySQL 的一半。
MySQL 使用 48 TB 存储空间,而 TiDB 将使用 16 TB,仅为 MySQL 的 1/3。
五个 ecs 实例,使用了不同配置,以此测试
MySQL
中的数据库大小为 70Gb,TiDB 中的数据库大小为 30Gb(压缩)。该表没有二级索引(主键除外)。
测试用例:
select count(*) from ontime;
select count(*), year from ontime group by year order by year;
select * from ontime where UniqueCarrier = 'DL' and TailNum = 'N317NB' and FlightNum = '2' and Origin = 'JFK' and Dest = 'FLL' limit 10;
select SQL_CALC_FOUND_ROWS
FlightDate, UniqueCarrier as carrier,
FlightNum,
Origin,
Dest
FROM ontime
WHERE
DestState not in ('AK', 'HI', 'PR', 'VI')
and OriginState not in ('AK', 'HI', 'PR', 'VI')
and flightdate > '2015-01-01'
and ArrDelay < 15
and cancelled = 0 and Diverted = 0
and DivAirportLandings = '0'
ORDER by DepDelay DESC
LIMIT 10;
系统基准测试
在 m4.16xlarge 实例上使用 Sysbench 进行点选择(意味着通过主键选择一行,线程范围从 1 到 128)(内存限制:无磁盘读取)。结果在这里。条形代表每秒的交易数量,越多越好:
测试分两阶段进行,第一阶段测试数据为100万单,第二阶段测试数据为1300万单。在此基础上,使用Jmeter压力测试10万单结果如下:
从测试结果来看,在小数据量mysql
性能是好于TiDB
,因为 TiDB
是分布式架构,如果小数据量,在网络通讯节点分发一致性等方面花的时间就很多,然后各个节点执行完还要汇总返回,所以开销是比较大的,但是数据量一上来TiDB 优势就体现出来了,因此数据量比较小,没必要使用 TiDB