TiDB的简单应用

Easter79
• 阅读 555

简介

    TiDB 是 PingCAP 公司受 Google Spanner / F1 论文启发而设计的开源分布式 HTAP (Hybrid Transactional and Analytical Processing) 数据库,结合了传统的 RDBMS 和 NoSQL 的最佳特性。TiDB 兼容 MySQL,支持无限的水平扩展,具备强一致性和高可用性。TiDB 的目标是为 OLTP (Online Transactional Processing) 和 OLAP (Online Analytical Processing) 场景提供一站式的解决方案。

特性

1)高度兼容 MySQL

    大多数情况下,无需修改代码即可从 MySQL 轻松迁移至 TiDB,分库分表后的 MySQL 集群亦可通过 TiDB 工具进行实时迁移。

2)水平弹性扩展

    通过简单地增加新节点即可实现 TiDB 的水平扩展,按需扩展吞吐或存储,轻松应对高并发、海量数据场景。

3)分布式事务

    TiDB 100% 支持标准的 ACID 事务。

4)真正金融级高可用

    相比于传统主从 (M-S) 复制方案,基于 Raft 的多数派选举协议可以提供金融级的 100% 数据强一致性保证,且在不丢失大多数副本的前提下,可以实现故障的自动恢复 (auto-failover),无需人工介入。

5)一站式 HTAP 解决方案

    TiDB 作为典型的 OLTP 行存数据库,同时兼具强大的 OLAP 性能,配合 TiSpark,可提供一站式 HTAP 解决方案,一份存储同时处理 OLTP & OLAP,无需传统繁琐的 ETL 过程。

6)云原生 SQL 数据库

    TiDB 是为云而设计的数据库,同 Kubernetes 深度耦合,支持公有云、私有云和混合云,使部署、配置和维护变得十分简单。

兼容性

    不支持的特性:视图、存储过程、触发器、自定义函数、外键约束、全文索引、空间索引、非UTF-8字符集。与我们实际应用不冲突。

与Mysql差异

 1)TiDB 的自增 ID (Auto Increment ID) 只保证自增且唯一,并不保证连续分配。TiDB 目前采用批量分配的方式,所以如果在多台 TiDB 上同时插入数据,分配的自增 ID 会不连续

 2)TiDB 支持常用的 MySQL 内建函数,但是不是所有的函数都已经支持,具体请参考语法文档

 3)TiDB 实现了 F1 的异步 Schema 变更算法,DDL 执行过程中不会阻塞线上的 DML 操作。目前支持的DDL包括数据库、表、索引、列的创建和删除操作以及列的修改操作。TiDB对列的修改有限制,如不支持从null改成not null,不支持对enum列修改等

事务

    TiDB 使用乐观事务模型,在执行 Update、Insert、Delete 等语句时,只有在提交过程中才会检查写写冲突,而不是像 MySQL 一样使用行锁来避免写写冲突。所以业务端在执行 SQL 语句后,需要注意检查 commit 的返回值,即使执行时没有出错,commit的时候也可能会出错。

文档

    在使用TiDB时,可以参照官方文档进行查阅,地址:https://www.pingcap.com/docs-cn/

架构

TiDB的简单应用

1)TiDB Server

     TiDB Server 负责接收 SQL 请求,处理 SQL 相关的逻辑,并通过 PD 找到存储计算所需数据的 TiKV 地址,与 TiKV 交互获取数据,最终返回结果。 TiDB Server 是无状态的,其本身并不存储数据,只负责计算,可以无限水平扩展,可以通过负载均衡组件(如LVS、HAProxy 或 F5)对外提供统一的接入地址

2)Placement Driver

    Placement Driver (简称 PD) 是整个集群的管理模块,其主要工作有三个: 一是存储集群的元信息(某个 Key 存储在哪个 TiKV 节点);二是对 TiKV 集群进行调度和负载均衡(如数据的迁移、Raft group leader 的迁移等);三是分配全局唯一且递增的事务 ID。PD 是一个集群,需要部署奇数个节点,一般线上推荐至少部署 3 个节点

3)TiKV Server 

    TiKV Server 负责存储数据,从外部看 TiKV 是一个分布式的提供事务的 Key-Value存储引擎。存储数据的基本单位是 Region,每个 Region 负责存储一个 Key Range (从 StartKey 到 EndKey 的左闭右开区间)的数据,每个 TiKV 节点会负责多个 Region 。TiKV 使用 Raft 协议做复制,保持数据的一致性和容灾。副本以 Region 为单位进行管理,不同节点上的多个 Region 构成一个 Raft Group,互为副本。数据在多个 TiKV 之间的负载均衡由 PD 调度,这里也是以 Region 为单位进行调度

解决问题

1)水平扩展

    无限水平扩展是 TiDB 的一大特点,这里说的水平扩展包括两方面:计算能力和存储能力。TiDB Server 负责处理 SQL 请求,随着业务的增长,可以简单的添加 TiDB Server 节点,提高整体的处理能力,提供更高的吞吐。TiKV 负责存储数据,随着数据量的增长,可以部署更多的 TiKV Server 节点解决数据量的问题(自动分库)PD 会在 TiKV 节点之间以 Region 为单位做调度,将部分数据迁移到新加的节点上。所以在业务的早期,可以只部署少量的服务实例(推荐至少部署 3 个 TiKV, 3 个 PD,2 个 TiDB),随着业务量的增长,按照需求添加 TiKV 或者 TiDB 实例

2)高可用

    高可用是 TiDB 的另一大特点,TiDB/TiKV/PD 这三个组件都能容忍部分实例失效,不影响整个集群的可用性。下面分别说明这三个组件的可用性、单个实例失效后的后果以及如何恢复。

  • TiDB 是无状态的,推荐至少部署两个实例,前端通过负载均衡组件对外提供服务。当单个实例失效时,会影响正在这个实例上进行的 Session,从应用的角度看,会出现单次请求失败的情况,重新连接后即可继续获得服务。单个实例失效后,可以重启这个实例或者部署一个新的实例。

  • PD 是一个集群,通过 Raft 协议保持数据的一致性,单个实例失效时,如果这个实例不是 Raft 的 leader,那么服务完全不受影响;如果这个实例是 Raft 的 leader,会重新选出新的 Raft leader,自动恢复服务。PD 在选举的过程中无法对外提供服务,这个时间大约是3秒钟。推荐至少部署三个 PD 实例,单个实例失效后,重启这个实例或者添加新的实例。

  • TiKV 是一个集群,通过 Raft 协议保持数据的一致性(副本数量可配置,默认保存三副本),并通过 PD 做负载均衡调度。单个节点失效时,会影响这个节点上存储的所有 Region。对于 Region 中的 Leader 结点,会中断服务,等待重新选举;对于 Region 中的 Follower 节点,不会影响服务。当某个 TiKV 节点失效,并且在一段时间内(默认 10 分钟)无法恢复,PD 会将其上的数据迁移到其他的 TiKV 节点上。

3)小彩蛋

    兼容 MySQL 5.7 及以上,同时更好地支持文档类型存储,表中包含一个 JSON 字段来存储复杂的信息

TiDB的简单应用

    TiDB的简单应用

    插入JSON数据

    TiDB的简单应用

TiDB的简单应用

    查询JSON数据,和 MongoDB 等文档数据库相同,可以在服务端支持用户各种复杂组合查询条件

    TiDB的简单应用

TiDB的简单应用

    除了插入、查询外,对 JSON 的修改也是支持的。目前支持的 MySQL 5.7 的 JSON 函数:JSON_EXTRACT、JSON_ARRAY、JSON_OBJECT、JSON_SET、JSON_REPLACE、JSON_INSERT、JSON_REMOVE、JSON_TYPE、JSON_UNQUOTE

 软硬件要求

    参照:https://www.pingcap.com/docs-cn/op-guide/recommendation/

安装

    由于服务器数量个数限制,这里采用单台安装测试,具体安装步骤如下:

    1)下载官方Binary压缩包,wget http://download.pingcap.org/tidb-latest-linux-amd64.tar.gz,wget http://download.pingcap.org/tidb-latest-linux-amd64.sha256

    2)检查文件完整性,sha256sum -c tidb-latest-linux-amd64.sha256

    3)解压文件,tar -xzf tidb-latest-linux-amd64.tar.gz && cd tidb-latest-linux-amd64

启动

    1)启动pd-server,./bin/pd-server --data-dir=pd

    2)启动tikv-server,./bin/tikv-server --pd="127.0.0.1:2379" -store=tikv

    3)启动tidb-server,./bin/tidb-server --store=tikv --path="127.0.0.1:2379"

    注:此三项启动顺序不能变更

连接

    启动成功后,可以通过Navicat等工具连接,TiDB对外的连接方式与Mysql一样,对于用户来说,根本感受不到使用的是TiDB还是Mysql。这里需要设置一下Centos的防火墙,Centos7防火墙的设置与Centos6不同,可以关闭防火墙或者开放端口

    1)关闭防火墙

    systemctl stop firewalld.service             #停止firewall

    systemctl disable firewalld.service        #禁止firewall开机启动

    两者可以同时使用,避免每次重启都得重新关闭防火墙

    2)开放端口

    firewall-cmd --zone=public --add-port=4000/tcp --permanent        #开放4000端口

    firewall-cmd --reload                                                                      #重新加载防火墙配置,此时4000端口才真正的开放

    其他功能可以使用firewall-cmd --help查看

**开始
**

    1)创建表

    CREATE TABLE `test_user` (

      `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'id',

      `name` varchar(32) NOT NULL COMMENT '名字',

      `age` tinyint(3) UNSIGNED DEFAULT NULL COMMENT '年纪',

      `summary` json DEFAULT NULL COMMENT '简介',

      PRIMARY KEY (`id`)

    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=30001 COMMENT='测试用户表';

    2)数据库连接

    连接池依然使用原有的com.alibaba.druid.pool.DruidDataSource,不需要修改原有任何类,只需要修改数据库连接地址及端口等配置信息即可

    jdbc.url=jdbc:mysql://192.168.32.129:4000/test?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
    jdbc.username=root
    jdbc.password=
    druid.timeBetweenEvictionRunsMillis=60000
    druid.minEvictableIdleTimeMillis=300000
    druid.maxActive=60
    druid.initialSize=2
    druid.maxWait=200
    druid.minIdle=30
    druid.maxOpenPreparedStatements=30

    3)用例测试

    进行了简单的CURD操作,都可以满足,尝试了一下JSON数据的查询,可以准确的查询到结果,后期可以进行压力测试,甚至代替mongo

集群

    由于TiDB的pd、tikv和tidb三部分都可以搭建集群,满足了高可用性,由于自己的虚拟机目前只有一台,暂未做测试,后续补上。

测试

    1)基础功能测试

    进行了简单的CURD操作,基本功能得以满足,对于mysql的函数及关键字的支持未测试

    2)写入测试

    为方便下面的查询测试,这里通过for循环为数据库添加了10万条数据,整个过程耗时18分钟,没有遇到错误,写入可用性不错

    3)查询测试

    这里以10万条数据做了简单的查询测试,由于目前只有单台服务,可能对实际结果有所偏差

条件

耗时(毫秒)

查询主键

82

查询普通索引列(varchar)

86

查询普通列(varchar)

505

查询JSON数据

729

总结

    综上所述,TiDB可以满足mysql既有的功能需求,能够达到线上使用的要求,但线上若想使用TiDB,需要开发、运维和DBA协调,包括软硬件是否能够满足,DBA维护工作是否可行等等。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解2016年09月02日00:00:36 \牧野(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fme.csdn.net%2Fdcrmg) 阅读数:59593
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k