分布式数据库-TiDB应用场景简介

前言:最近公司要讨论分库分表,正好一起参加了培训。一般mysql单表数据库容量达到一定的极限,性能会急剧下降,之前工作的时候已经大佬们高喊几次了分库分表,但是最终没能实现或者落地的方案不佳。在这里一篇很好的文章指出了当前开源的分库分表的框架的不足,并介绍了使用TiDb作为新的分布式数据库的各种优点传送门。

目前的常用的分库分表概述

一种是中间件代理,例如mycat和sharding-proxy,对于应用是比较透明的,支持的语言也多;第二种是侵入式,也就是数据库直连,例如sharding-jdbc。sharding-proxy和sharding-jdbc都已经整合到sharding-Sphere里,中文文档可以点击这里

sharding-sphere作为分库分表的实现短板。

sharding-sphere包含三个项目:sharding-jdbc、sharding-proxy和Sharding-Sidecar。如果有兴趣大家可一查看demo,里面包含各种应用场景。我仅仅以后台人员的角度来看局限性。

  • shrdingkey粘连 例如sharding-jdbc里面需要指出分库键和分表键,如果你的业务很复杂,意味着你要建立很多shrdingkey;即使你认为这没有啥,最要命的是你增删改查都必须带上这个shrdingkey才能路由到你要去的那张表,这就好比回娘家,还真得左右一只鸡右手一只鸭,不然娘家不认你。
  • 数据冷热均衡、高可用复杂度很高 一般分表分库数据,热点数据我就需要设计非常复杂的算法,提前规划好几张库几张表;例如购物记录表,你设计2个库,每个库水平切4张表,再为这些表设计一套均衡的数据分流,但是人员表你最多一个库两张表,再为这冲业务维度设计一套数据均衡。最后,你要为这些来个主从、读写分离保证高可用,...同志,你确定你能行吗?牛逼的话希望可以给口饭吃。
  • 扩容非常困难 如果你已经提前规划好了几个库几个表,并且为每个业务表都设计好一套牛逼的算法,保证一百年性能不出问题,并且也给了我一口汤喝,百年之后老板的儿子要扩容。运维人员需要根据你的算法,再来扩容,4库变成8个库,每个库再来切一下,再来弄个高可用,再来迁移数据。运维黑人问号脸:我去你***%……%%35433454
  • sql不支持关联查询、分布式事务复杂度高、一致性差。不过这些都是分布式都面临的问题,已阅。

TIDB原理简介

分布式数据库-TiDB应用场景简介_第1张图片

TIDB.png

  • TiDB Server :解析SQL 请求,最后通过 PD 找到存储计算所需数据的 TiKV (键值对)然后返回。TiDB 是无状态的,也就是无脑传话机,本身不存储任何数据。
  • PD Server: TiKV存储集群的元信息;对 TiKV 集群进行调度和负载均衡;分配全局唯一且递增的事务 ID。他是集群,集群是要选举的,必须是奇数个哦! PD Server是指挥官,负责调度。
  • TiKV Server: 负责存储数据,基本单元就是Region,也就是一个K-V。多个Region组成一个TiKV 节点,多个节点组成一个GROUP。

TiDB作为分布式数据库的优点

  • 对于现有得应用非常透明化。Tidb的原理是解析sql语句,进入自己的key-value存储单元获取数据,使得现有得应用可以平滑过渡,挂的是关系型数据库的皮,做的是NOSQL数据库的事,我们叫他不是个东...new SQL。他借用了mysql引擎,所以你直接在NAVICAT上就可以直接界面化操作啦。
  • 可以非常快捷的伸缩,实现冷热数据的均衡。例如使用sharding-jdbc,要实现热点数据的分布存储,抛开复杂的分库分表算法不说,每次扩容对于运维人员非常繁琐。但是TIDB就不存在啦,只要扩展TiDB Server 节点增加计算能力,扩展TIKV节点增加存储能力就可以。这是一场战争,号角吹响,补兵不行补兵,传话的不够加传话的,指挥官挂了选新的。男人不能说自己不xing.
  • 支持分布式事务,数据强一致性,百亿级存储。根据官网吹牛(shihua)逼(shishuo)说,金融级高可用。

TiDB作为分布式数据库的缺点

  • 存储过程、触发器、事件、外键约束不支持,但是这个是人家谦(chenqie)虚的说法(zuobudao),分布式数据库谁还用这些鸡肋玩意儿,特别是触发器。
  • 硬件要求高,不多说的,反正就是高,你想想人家这么快肯定IO轻松不了,人家大神都说了,最好全换成SSD。

     

    分布式数据库-TiDB应用场景简介_第2张图片

    image.png

TiDB的安装

作为后台人员,我们就是用最快捷的docker快速安装搭建TIDB,Tidb官网已经给出了非常完整的文档,这里不再详述。

 

参看文章

  • docker-compose安装TIDB:官方安装
  • tiDB SQL优化:TiDB 的正确使用姿势
  • 十问 TiDB

 

 

TiDB和Mysql的sql差异总结

简介
根据网上一些使用案例列出目前TiDB和mysql在使用上的区别和目前的遇到的常见问题及解决方案,当然具体的使用问题还需要大量的线下测试才能确认。

 

问题类型    问题描述    原因及解决办法
DDL    在一个 DDL 里不能对多个列或者多个索引做操作。    
ADD/DROP INDEX/COLUMN 操作目前不支持同时创建或删除多个索引或列,

需要拆分单独执行,官方表示 3.0 版本有计划改进。

 

建表语句执行速度相比 MySQL 较慢    
多台 TiDB 的时候,Owner 和接收 create table 语句的 TiDB Server 不在一台 Server 上时,

可能比 MySQL 慢一些,每次操作耗时在 0.5s 左右,官方表示会在后续的版本中不断完善。

大表建索引时对业务有影响    官方建议在业务低峰期操作,在 2.1 版本中已经增加了操作优先级以及并发读的控制,情况有改善。


TiDB 对于 MySQL 用户授权 SQL 语法的兼容支持尚不完善,

目前不支持 SHOW CREATE USER 语法,

有时候不得不读取系统表(mysql.user)来查看一个数据库账户的基本信息

希望后续版本优化


DML      
部分操作符查询优化器支持不够好,比如 or 操作符会使用 TableScan,

改写成 union all 可避免。

官方表示目前使用 or 操作符确实在执行计划上有可能不准确,

已经在改进计划中,后续 3.0 版本会有优化。

 

MySQL 事务中,可以通过影响条数,作为写入(或修改)是否成功的依据;

而在 TiDB 中,这却是不可行的。

原因:
对于 MySQL,当更新某条记录时,会先获取该记录对应的行级锁(排他锁),

获取成功则进行后续的事务操作,获取失败则阻塞等待。

对于 TiDB,使用 Percolator 事务模型:可以理解为乐观锁实现,事务开启、

事务中都不会加锁,而是在提交时才加锁。

解决方案:

在业务层,可以借助分布式锁,实现串行化处理,但是会增加开发成本。

 

对于热数据,数据量一般不大,但是查询频度很高,比如查询 sql 为:
SELECT * FROM t_job_record where status=0
and execute_time<= 1546361579646
这个在 MySQL 中很高效的查询,在 TiDB 中虽然也可从索引检索,

但其耗时却不尽人意(百万级数据量,耗时百毫秒级)。

原因:在 TiDB 中,底层索引结构为 LSM-Tree。当从内存级的 C0 层查询不到数据时,

会逐层扫描硬盘中各层;且 merge 操作为异步操作,索引数据更新会存在一定的延迟,可能存在无效索引。

由于逐层扫描和异步 merge,使得查询效率较低。

解决方案:

尽可能缩小过滤范围,比如结合异步 job 获取记录频率,在保证不遗漏数据的前提下,

合理设置 execute_time 筛选区间,例如 1 小时,sql 改写为:

SELECT * FROM t_job_record where status=0 and execute_time>1546357979646
and execute_time<= 1546361579646

 

select count(1) tidb查询慢    
原因:和上面类似。

tidb因为存储结构和查询方式的不同,tidb其实是暴力扫表。很多使用方也都反应慢,

这个是目前的TiDB的一个常见的问题。这里给出官方的解决方案:

 

尚不支持的sql语法:    
增加、删除主键
非 UTF8 字符集
视图(即将支持)、存储过程、触发器、部分内置函数
Event
全文索引、空间索引
 


PD     
重启一个 PD 节点的时候,业务能捕捉到 PD 不可用的异常,

会报 PD server timeout 。

因为重启的是 Leader 节点,所以重启之前需要手动切换 Leader,然后进行重启。

官方建议这里可以通过重启前做 Leader 迁移来减缓,

另外后续 TiDB 也会对网络通讯相关参数进行梳理和优化。

 

pd-ctl 命令行参数解析严格,多一个空格会提示语法错误。    官方表示低版本中可能会有这个问题,在 2.0.8 及以上版本已经改进。


TiDB    
现在 TiDB 的 GC 对于每个 kv-instance 是单线程的,

当业务删除数据的量非常大时,会导致 GC 速度较慢,

很可能 GC 的速度跟不上写入。

目前可以通过增多 TiKV 个数来解决,长期需要靠 GC 改为多线程执行,后续版本会支持。
TiKV     存储空间放大问题    
该问题属于 RocksDB,RocksDB 的空间放大系数最理想的值为 1.111,

官方建议在某些场景下通过 TiKV 开启 RocksDB 的 dynamic-level-bytes 以减少空间放大。

 

TiKV 容易发生 Write Stall    
原因:

TiKV 底层有 2 个 RocksDB 作为存储。新写的数据写入 L0 层,当 RocksDB 的 L0 层数量达到一定数量,

就会发生减速,更高则发生 Stall,用来自我保护。

生 L0 文件过多可能的原因有 2 个:

写入量大,Compact 完不成。
Snapshot 一直创建不完,导致堆积的副本一下释放,rocksdb-raft 创建大量的 L0 文件
解决:

TiKV调优:

减缓 Raft Log Compact 频率(增大 raft-log-gc-size-limit、raft-log-gc-count-limit)
加快 Snapshot 速度(整体性能、包括硬件性能)
调整max-sub-compactions 、max-background-jobs参数等
添加 TiKV 节点后需要较长时间才能完成数据再平衡    1TB 数据大约需要 24 个小时才能完成拷贝,建议在低峰期引入

 

 

TiDB和Mysql优缺点对比
简单总结一下TiDB的优缺点:

TiDB优点
高度兼容mysql协议,迁移成本低
高可用:相比于传统主从(M-S)复制方案,基于 Raft 的多数派选举协议可以提供金融级的 100% 数据强一致性保证,且在不丢失大多数副本的前提下,可以实现故障的自动恢复(auto-failover),无需人工介入。
支持海量数据,可拓展性强:分布式数据库,可通过增加TiKV节点拓展,支持分裂和自动迁移,对业务基本无感知。
和传统的分库分表,相比业务拓展性较强:传统的分库分表技术,开发和维护成本都较高,业务侵入性也较大,使用TiDB会明显降低 RD 和 DBA 的开发维护成本。
分布式事务
TiDB的不足
对机器配置门槛要求较高,特别是内存和CPU的要求很高,当数据量不大时会增加机器的资源使用成本。
TiDB对sql的支持尚不完善,对一些sql的执行性能并不理想,一些复杂sql需要重新设计,还有一些mysql的功能并不支持。
TiDB技术较新,尚在不断优化中,因此也容易踩坑。


综合
综上所述,个人认为和mysql相比,

TiDB目前更适合TB级的海量数据处理,数据量越大,使用场景和优势越明显,
也比较适合对查询性能要求不高的数据分析场景或离线计算场景
即时场景下查询上最适合海量数据下进行多维度的精确查询
整体而言TiDB技术仍不能算成熟,目前还在快速的更新和迭代过程中,容易采坑,建议引入也是先从离线业务->非核心业务->核心业务的使用过程。

 


 
 

你可能感兴趣的:(分库分表,数据库)