㈠ tidb数据库如何更改多列字段
1、首先打开ManagementStudio软件,输贺迅入服务器地址,接着输入用户名密码点击连接按钮。
2、其次选中需要修改的字段所册拆在的数据库,鼠标右击选择新建查询窗口。
3、然后在查询窗口中先使用Select语句,查州拍枣询表中字段值。
㈡ TiDB修改配置参数
在TiDB 中,“修改配置参数”似乎是个不精准的说法,它实际包含了以下内容:
TiDB的配置修改比较混乱,先做个总结,再介绍具体内容:
查看TiDB系统变量:
集群中所有 TiDB Server 都生效;
持久化在哪里?
持久化在 kv 存储中,跟数据一样持久化了,不会持久化在 conf/tidb.toml 配置文件中。所以不用担心 tiup upgrade 和 tiup reload 等运维操作会把配置文件覆盖,不会导致修改失效,因为这个修改的持久化不依赖配置文件。
有些参数的作用域只有会话级别。也就是只能会话级修改,这不代表着不能被动态修改。
修改方式和会话级修改一样:
修改 Instance 级别的参数修改不会持久化,那么如何持久化呢?
a. 手工修改 TiDB 的配置文件:
b. 并使用 tiup edit-config 来修改对应的配置项,不需要做 tiup reload:
内容如下:
目前查看官方文档,发现只有3个只读变量:hostname、tidb_config、tidb_current_ts,没法通过 set variables 修改。作用域比较奇怪,用法介绍也不清楚,看起来没有修改的必要。如果一定要修改可以通过 tiup 方法修改。
修改集群配置包括TiDB、TiKV 以及 PD 在内的各组件的配置进行修改。
使用 edit-config 命令来编辑参数,以编辑模式打开该集群的配置文件:
如果配置的生效范围为该组件全局,则配置到 server_configs,比如修改所有 tikv 的 log-level 为 waring(默认是 info):
如果配置的生效范围为某个节点,则配置到具体节点的 config 中。例如:
tiup reload 分发配置并滚动重启组件,无论是否可以动态修改的参数都会重启,并且默认会重启所有组件,可以选择指定节点或者组件:
tiup cluster reload ${cluster-name} [-N <羡历nodes>] [-R <roles>]
示例中我们只修改 tikv 的 log-level 为 waring,所以用 -R tikv 指定只重启 tikv 节点:
set config 当前4.0版本属于兄纤搜实验性功能,不建议在生产使用: https://docs.pingcap.com/zh/tidb/stable/dynamic-config
目前只支持修改 TiKV 和 PD 的配置,TIDB的配置修改用上面的 set variables 方法。
查看当前参数设置:
用竖槐 set config 修改参数,会持久化到配置文件。log-level 无法动态修改,不会报错但是会有 warnings,对于不能动态修改的参数使用 tiup 进行修改:
动态修改示例:
虽然TiKV的配置文件 conf/tikv.toml 会持久化这个修改,但是为了防止tiup upgrade 和 tiup reload 等运维操作把配置文件覆盖导致修改失效,还需要执行 tiup edit-config 来编辑参数。
㈢ TiDB 基础操作集
1、测试环境推荐配置
2、生产环境推荐配置
3、 如果 tikv 服务器的 CPU及磁盘配置较高,可以考虑多实例部署,按照每个 tikv 实例16~20core + 64G 内存 + 800G 磁盘的比例分配硬件资派蠢源。
同时需要注意 inventory.ini 及 ansible/conf/tikv.yml 的相关配置。
4、tidb 服务器视业务类型,如果业务逻辑有偏 AP 类的 sql,需要考虑配置大内存,防止出现 OOM。
如果是纯 TP 类业务,tidb 服务器 CPU 配置较高的话唤型,也可以考虑多实例部署,每个 tidb-server 分配20~32core,可以避免无谓的CPU上下文切换, 减少 system cpu 消耗。
5、pd 服务器的磁盘可以配置200~500G 的SSD 盘,主要用来保存源数据信息。在集群规模较大,源数据信息较多的和羡猜时候,SSD 磁盘能够避免源数据信息存取成为集群的瓶颈点。
1、操作系统版本要求
建议 centos 7.3及以上,支持 redhat 7.3版本及以上,不推荐其他版本的系统。
2、ansible、jinja 等软件依赖包版本,只需要验证中控机(运行ansible 机器)上软件版本满足条件即可
中控机:
监控机(grafana):
3、测试环境磁盘 IO 不满足需求
ansible-playbook bootstrap.yml --extra-vars "dev_mode=True"
加上 dev_mode=True 可以在部署时,绕过系统磁盘相关的 benchmark
4、关闭防火墙、开启时钟同步
systemctl status firewalld
systemctl status chronyd/ntpd
5、集群下所有服务器要配置不同的 hostname
如果否,可以编辑 inventory.ini 的配置项 set_hostname=True 来自动修改 hostname
6、调整参数
参数在 ansible/conf/目录下,tidb.yml,tikv.yml,常见的可能需要调整的参数
tidb.yml:
grpc-connection-count: 如果服务器 CPU 配置较高,tikv 实例个数较多,该参数可以调整至20~32之间
slow-threshold:slow-query 记录的阈值,默认300ms
level:日志级别,默认 info,可以视情况调整为 debug 或 error
tikv.yml:
sync-log:raft-log sync配置,默认值true,对于磁盘 io 消耗较高,测试/非金融生产环境建议设置为 false
region-split-check-diff:检测 region 分裂的阈值,非 SSD 磁盘建议调大至32MB
rocksdb defaultcf block-cache-size(GB) = MEM * 80% / TiKV 实例数量 * 30%(多实例部署下配置,单实例部署不需要修改)
rocksdb writecf block-cache-size(GB) = MEM * 80% / TiKV 实例数量 * 45%(多实例部署下配置,单实例部署不需要修改)
rocksdb lockcf block-cache-size(GB) = MEM * 80% / TiKV 实例数量 * 2.5% (最小 128 MB)(多实例部署下配置,单实例部署不需要修改)
raftdb defaultcf block-cache-size(GB) = MEM * 80% / TiKV 实例数量 * 2.5% (最小 128 MB)(多实例部署下配置,单实例部署不需要修改)
多实例情况下,需要修改
readpool:
coprocessor:
high-concurrency
normal-concurrency
low-concurrency
三个参数,推荐为实例数*参数值 = CPU 核数 * 0.8。
raftstore:
capacity
磁盘总容量 / TiKV 实例数量,例如 “100GB”
修改完后,可以使用下面命令验证
cat tidb-ansible/conf/tikv.yml |grep -Ev "^$|#"
无误后执行
ansible-playbook rolling_update.yml --tags=tidb/tikv
滚动升级,tags 可选
7、官网有比较完善的在线+离线部署方案、在线升级指导、在线扩容缩容文档,具体参考:
https://pingcap.com/docs-cn/op-guide/ansible-deployment/
https://pingcap.com/docs-cn/op-guide/offline-ansible-deployment/
https://pingcap.com/docs-cn/op-guide/ansible-deployment-scale/
1、从 MySQL 迁移
TiDB 兼容 MySQL 语法,小数据量建议直接使用 mysqlmp、mymper 来全量导出数据,再通过 source、myloader 的方式导入 TiDB。
./bin/mymper -h 127.0.0.1 -P 3306 -u root -t 16 -F 64 -B test -T t1,t2 --skip-tz-utc -o ./var/test
./bin/loader -h 127.0.0.1 -u root -P 4000 -t 32 -d ./var/test
详情请参考: https://pingcap.com/docs-cn/op-guide/migration/#使用-mymper-loader-全量导入数据
如果数据量较大,超过几百 G,可以联系原厂申请试用 lightning 工具,loader 导入数据平均速度是20G/小时,lightning 约为100~150G/小时
2、从 Oracle 迁移
目前有几种方式可以参考
使用 OGG 做全量+增量同步
使用 Navicat Premium 版的 data transfer 功能,支持从 Oracle/SqlServer 迁移全量数据至 TiDB
通过 kafka 等消息队列工具,解析 OGG 的日志,开发写入 TiDB/MySQL 的工具
目前我们也在积极跟专业的数据异构平台合作,争取能够尽快在更多的数据迁移工具中兼容 TiDB 数据源。
1、启动集群
ansible-playbook start.yml --tags=tidb/tikv/pd
在正确的 ansible 目录下,确保 inventory.ini 里的配置正确,tags 可选
2、停止集群
ansible-playbook stop.yml --tags=tidb/tikv/pd
在正确的 ansible 目录下,确保 inventory.ini 里的配置正确,tags 可选
3、停止单个 tidb-server / tikv-server
ansible-playbook stop.yml --tags=tidb/tikv/pd -l IP
-l 后面接 inventory.ini 配置的IP 或别名
4、访问 tidb
TiDB 兼容 MySQL 协议,所有连接 MySQL 的方式都适用于TiDB
mysql -uroot -h127.0.0.1 -P4000 -p
常见的图形化界面工具,navicat 等都可以直接访问 tidb
同时也支持jdbc、odbc 等,需要注意的是 mysql 8.0版本的客户端,及 mariadb 客户端可能存在兼容性问题,不建议使用
SQL 语法基本兼容 MySQL,某些不兼容的场景见: https://pingcap.com/docs-cn/sql/mysql-compatibility/#与-mysql-兼容性对比
5、修改参数
可以通过修改 tidb-ansible/conf/tidb.yml 配置文件,然后执行
ansible-playbook rolling_update.yml --tags=tidb/tikv
也可以直接登录服务器,找到deploy_dir/conf/tidb.toml,直接编辑文件,然后 pkill tidb-server 来重启服务
6、查看 tidb 版本信息
select tidb_version();
Release Version: v2.1.0-rc.3-24-g23f90a6
Git Commit Hash:
Git Branch: HEAD
UTC Build Time: 2018-10-10 09:18:39
GoVersion: go version go1.11 linux/amd64
Race Enabled: false
TiKV Min Version: 2.1.0-alpha.1-
Check Table Before Drop: false
7、备份 tidb 数据
全量备份可以采用 mymper,增量备份需要开启 binlog,实时恢复采用商业版工具 reparo。
8、查看监控数据
在 ansible 的配置文件 inventory.ini 里,有一个监控服务器的配置
[monitoring_servers]
10.1.163.87
deploy 的时候会默认在这个配置服务器上部署 grafana 组件,通过
http://10.1.163.87:3000 admin/admin 访问
具体一些常见的监控指标,请参考: https://pingcap.com/docs-cn/op-guide/dashboard-overview-info/
9、收集统计信息
set @@tidb_build_stats_concurrency=20;
set @@tidb_distsql_scan_concurrency=100;
set @@tidb_index_serial_scan_concurrency=20;
analyze table xxx index xxx;
修改上面三个参数可以提升 scan 效率。
具体统计信息相关,请参考: https://pingcap.com/docs-cn/sql/statistics/#统计信息简介
1、Transaction too large
TiDB 对于事务有限制,简单来说以下几点:
单个事务的SQL 语句数量不能超过5000,( 在 tidb.yml 可配 stmt-count-limit )
单条 KV entry 不超过 6MB
KV entry 的总条数不超过 30w
KV entry 的总大小不超过 100MB
备注:假设某张表有4个索引,那么一条数据对应的 kv entry 为数据+索引,一共5个kv 记录。
如果是批量 insert 或delete,建议先修改
set tidb_batch_insert = 1;
set tidb_batch_delete = 1;
update mysql.tidb set variable_value='24h' where variable_name='tikv_gc_life_time';
再执行 SQL。
如果是批量 update,建议采用 limit 循环的方式执行。
2、GC life time is shorter than transaction ration
GC Life Time 间隔时间过短,长事务本应读到的数据可能被清理了,可使用如下命令增加 GC Life Time :
update mysql.tidb set variable_value='30m' where variable_name='tikv_gc_life_time';
3、Lost connection to MySQL server ring query
log 中是否有 panic
dmesg 中是否有 oom,命令: dmesg -T | grep -i oom
长时间没有访问,也会收到这个报错,一般是 tcp 超时导致的,tcp 长时间不用, 会被操作系统 kill。
㈣ tidb的数据类型查询问题
tidb对于类型要橡肢求比较严格,例如 varchar 存液如芹储的字段内容,查询时用整形查,tidb会先转化类型后再查询,闹毕速度超级慢
id int(11) primary key
advertiser_id varchar(32) not null
advertiser_id 存储的都是 123,445,666之类
select * from table where name in (445,666) 这样查询会很慢
select * from table where name in ('445','666') 数据类型一致时会很快
㈤ 国内重要的 Go 语言项目:TiDB 3.0 GA,稳定性和性能大幅提升
TiDB 是 PingCAP 自主研发的开源分布式关系型数据库,具备商业级数据库的数据可靠性,可用性,安全性等特性,支持在线弹性水平扩展,兼容 MySQL 协议及生态,创新性实现 OLTP 及 OLAP 融合。
TiDB 3.0 版本显着提升了大规模集群的稳定性,集群支持 150+ 存储节点,300+TB 存储容量长期稳定运行。易用性方面引入大量降低用户运维成本的优化,包括引入 Information_Schema 中的多个实用系统视图、EXPLAIN ANALYZE、SQL Trace 等。在性能方面,特别是 OLTP 性能方面,3.0 比 2.1 也有大幅提升,其中 TPC-C 性能提升约 4.5 倍,Sysbench 性能提升约 1.5 倍,OLAP 方面,TPC-H 50G Q15 因实现 View 可以执行,至此 TPC-H 22 个 Query 均可正常运行。新功能方面增加了窗口函数、视图(实验特性)、分区表、插件系统、悲观锁(实验特性)。
截止本文发稿时 TiDB 已在 500+ 用户的生产环境中长期稳定运行,涵盖金融、保险、制造,互联网, 游戏 等领域,涉及交易、数据中台、 历史 库等多个业务场景。不同业务场景对关系型数据库的诉求可用 “百花齐放”来形容,但对关系数据库最根本的诉求未发生任何变化,如数据可靠性,系统稳定性,可扩展性,安全性,易用性等。请跟随我们的脚步梳理 TiDB 3.0 有什么样的惊喜。
3.0 与 2.1 版本相比,显着提升了大规模集群的稳定性,支持单集群 150+ 存储节点,300+TB 存储容量长期稳定运行,主要的优化点如下:
1. 优化 Raft 副本之间的心跳机制,按照 Region 的活跃程度调整心跳频率,减小冷数据对集群的负担。
2. 热点调度策略支持更多参数配置,采用更高优先级,并提升热点调度的准确性。
3. 优化 PD 调度流程,提供调度限流机制,提升系统稳定性。
4. 新增分布式 GC 功能,提升 GC 的性能,降低大集群 GC 时间,提升系统稳定性。
众所周知,数据库查询计划的稳定性对业务至关重要,TiDB 3.0 版本采用多种优化手段提升查询计划的稳定性,如下:
1. 新增 Fast Analyze 功能,提升收集统计信息的速度,降低集群资源的消耗及对业务的影响。
2. 新增 Incremental Analyze 功能,提升收集单调递增的索引统计信息的速度,降低集群资源的消耗及对业务的影响。
3. 在 CM-Sketch 中新增 TopN 的统计信息,缓解 CM-Sketch 哈希冲突导致估算偏大,提升代价估算的准确性,提升查询计划的稳定性。
4. 引入 Skyline Pruning 框架,利用规则防止查询计划过度依赖统计信息,缓解因统计信息滞后导致选择的查询计划不是最优的情况,提升查询计划的稳定性。
5. 新增 SQL Plan Management 功能,支持在查询计划不准确时手动绑定查询计划,提升查询计划的稳定性。
1. OLTP
3.0 与 2.1 版本相比 Sysbench 的 Point Select,Update Index,Update Non-Index 均提升约 1.5 倍,TPC-C 性能提升约 4.5 倍。主要的优化点如下:
1. TiDB 持续优化 SQL 执行器,包括:优化 NOT EXISTS 子查询转化为 Anti Semi Join,优化多表 Join 时 Join 顺序选择等。
2. 优化 Index Join 逻辑,扩大 Index Join 算子的适用场景并提升代价估算的准确性。
3. TiKV 批量接收和发送消息功能,提升写入密集的场景的 TPS 约 7%,读密集的场景提升约 30%。
4. TiKV 优化内存管理,减少 Iterator Key Bound Option 的内存分配和拷贝,多个 Column Families 共享 block cache 提升 cache 命中率等手段大幅提升性能。
5. 引入 Titan 存储引擎插件,提升 Value 值超过 1KB 时性能,缓解 RocksDB 写放大问题,减少磁盘 IO 的占用。
6. TiKV 新增多线程 Raftstore 和 Apply 功能,提升单节点内可扩展性,进而提升单节点内并发处理能力和资源利用率,降低延时,大幅提升集群写入能力。
TiDB Lightning 性能与 2019 年年初相比提升 3 倍,从 100GB/h 提升到 300GB/h,即 28MB/s 提升到 85MB/s,优化点,如下:
1. 提升 SQL 转化成 KV Pairs 的性能,减少不必要的开销。
2. 提升单表导入性能,单表支持批量导入。
3. 提升 TiKV-Importer 导入数据性能,支持将数据和索引分别导入。
4. TiKV-Importer 支持上传 SST 文件限速功能。
RBAC(Role-Based Access Control,基于角色的权限访问控制) 是商业系统中最常见的权限管理技术之一,通过 RBAC 思想可以构建最简单“用户-角色-权限”的访问权限控制模型。RBAC 中用户与角色关联,权限与角色关联,角色与权限之间一般是多对多的关系,用户通过成为什么样的角色获取该角色所拥有的权限,达到简化权限管理的目的,通过此版本的迭代 RBAC 功能开发完成。
IP 白名单功能(企业版特性) :TiDB 提供基于 IP 白名单实现网络安全访问控制,用户可根据实际情况配置相关的访问策略。
Audit log 功能(企业版特性) :Audit log 记录用户对数据库所执行的操作,通过记录 Audit log 用户可以对数据库进行故障分析,行为分析,安全审计等,帮助用户获取数据执行情况。
加密存储(企业版特性) :TiDB 利用 RocksDB 自身加密功能,实现加密存储的功能,保证所有写入到磁盘的数据都经过加密,降低数据泄露的风险。
完善权限语句的权限检查 ,新增 ANALYZE,USE,SET GLOBAL,SHOW PROCESSLIST 语句权限检查。
1. 新增 SQL 方式查询慢查询,丰富 TiDB 慢查询日志内容,如:Coprocessor 任务数,平均/最长/90% 执行/等待时间,执行/等待时间最长的 TiKV 地址,简化慢查询定位工作,提高排查慢查询问题效率,提升产品易用性。
2. 新增系统配置项合法性检查,优化系统监控项等,提升产品易用性。
3. 新增对 TableReader、IndexReader 和 IndexLookupReader 算子内存使用情况统计信息,提高 Query 内存使用统计的准确性,提升处理内存消耗较大语句的效率。
4. 制定日志规范,重构日志系统,统一日志格式,方便用户理解日志内容,有助于通过工具对日志进行定量分析。
5. 新增 EXPLAIN ANALYZE 功能,提升SQL 调优的易用性。
6. 新增 SQL 语句 Trace 功能,方便排查问题。
7. 新增通过 unix_socket 方式连接数据库。
8. 新增快速恢复被删除表功能,当误删除数据时可通过此功能快速恢复数据。
TiDB 3.0 新增 TiFlash 组件,解决复杂分析及 HTAP 场景。TiFlash 是列式存储系统,与行存储系统实时同步,具备低延时,高性能,事务一致性读等特性。 通过 Raft 协议从 TiKV 中实时同步行存数据并转化成列存储格式持久化到一组独立的节点,解决行列混合存储以及资源隔离性问题。TiFlash 可用作行存储系统(TiKV)实时镜像,实时镜像可独立于行存储系统,将行存储及列存储从物理隔离开,提供完善的资源隔离方案,HTAP 场景最优推荐方案;亦可用作行存储表的索引,配合行存储对外提供智能的 OLAP 服务,提升约 10 倍复杂的混合查询的性能。
TiFlash 目前处于 Beta 阶段,计划 2019 年 12 月 31 日之前 GA,欢迎大家申请试用。
未来我们会继续投入到系统稳定性,易用性,性能,弹性扩展方面,向用户提供极致的弹性伸缩能力,极致的性能体验,极致的用户体验。
稳定性方面 V4.0 版本将继续完善 V3.0 未 GA 的重大特性,例如:悲观事务模型,View,Table Partition,Titan 行存储引擎,TiFlash 列存储引擎;引入近似物理备份恢复解决分布数据库备份恢复难题;优化 PD 调度功能等。
性能方面 V4.0 版本将继续优化事务处理流程,减少事务资源消耗,提升性能,例如:1PC,省去获取 commit ts 操作等。
弹性扩展方面,PD 将提供弹性扩展所需的元信息供外部系统调用,外部系统可根据元信息及负载情况动态伸缩集群规模,达成节省成本的目标。
我们相信战胜“未知”最好的武器就是社区的力量,基础软件需要坚定地走开源路线。截止发稿我们已经完成 41 篇源码阅读文章。TiDB 开源社区总计 265 位 Contributor,6 位 Committer,在这里我们对社区贡献者表示由衷的感谢,希望更多志同道合的人能加入进来,也希望大家在 TiDB 这个开源社区能够有所收获。
TiDB 3.0 GA Release Notes: https://pingcap.com/docs-cn/v3.0/releases/3.0-ga/
㈥ TiDB 集群的可用性详解及 TiKV Label 规划
目 录
一、前言
二、TiDB 集群核心组件可用性概览
1. TiDB Server 的可用性
三、Multi-Raft 集群的可用性限制
1. Raft 简介
2. Raft Group 副本数的选择
3. PD 是单一 Raft Group
4. TiKV 是 Multi-Raft 系统
5. Multi-Raft 集群的可用性限制
四、规划 TiKV Label 以提升 TiKV 集群的可用性
1. TiKV Label 简介
2. Label 相关的 PD 调度策略解读
3. TiKV Label 的规划
4. 使用 Label 的注意事项
五、典型两地三中心跨中心高可用多活容灾备配置
1. 物理服务器主机配置
2. 服务器,机柜,机房,网络要求
3. 两地三中心集群的扩容策略
分布式系统的核心理念是让多台服务器协同工作,完成单台服务器无法处理的任务。单点的硬件和网络等都是不可靠的,想要提高硬件的可靠性需要付出大量的成本,因此分布式系统往往通过软件来实现对于硬件的容错,通过软件来保证整体系统的高可靠性。
TiDB 集群中包含了串-并联系统,表决系统等,相对于一般的分布式系统更为复杂,TiDB 中所保存的数据的可用性由诸多因素控制,通过本篇文章的介绍,您可以了解到怎样在给定的资源下设计部署架好顷皮构以尽可能地提高数据的可用性。
在 TiDB 集群的三个核心组件 PD,TiKV,TiDB 中,PD 和 TiKV 都采用 Raft 协议实现持久化数据的容灾以及自动的故障转移,有关 PD 和 TiKV 的可用性的详细解读,请参见第三章的内容。
TiDB Server 组件不涉及数据的持久化,因此 TiDB 被设计成了无状态的,TiDB 进程可以在任意位置被启动,多个 TiDB 之间的关系是对等的,并发的事务通过同一台 TiDB 发送给集群和通过多台 TiDB 发送给集群所表现的行为完全一致。单一 TiDB 的故障只会影响这个 TiDB 上当前的连接,对其他 TiDB 上的连接没有任何影响。
根据用户最佳实践,在 TiDB 之上一般会部署负载均衡器(F5,LVS,HAproxy,Nginx 等),因此负载均衡器所连接的 TiDB 越多,其整体可用性就越高,其整体所能承载的并发请求数量也越多。
在使用负载均衡器的场景下,建议使用的负载均衡算法为 least connection,当某个 TiDB 发生故障依然会导致当时连接到该 TiDB 上的请求失败,负载均衡器识别到 TiDB 的故障之后,将不再向此 TiDB 建立新的连接,而是将新的连接建立到可用的 TiDB 上,以此来实现整体的高可用。
Raft 是一种分布式一致性算法,在 TiDB 集群的多种组件中,PD 和 TiKV 都通过 Raft 实现了数据的容灾。Raft 的灾难恢复能力通过如下机制实现:
Raft 算法本身以及 TiDB 中的 Raft 实现都没有限制一个 Raft Group 的副本数,这个副本数可以为任意正整数,当副本数为 n 的时候,一个 Raft Group 的可靠性如下:
我们一般建议将 Raft Group 的副本数设置为奇数,其原因如下:
在一般的非关键业务场景乎旅下,建议将副本数选为 3;而在关键业务中建议将副本数选为 5。
遵循 Raft 可靠性的特点,放到现实场景中:
PD 集群只包含一个 Raft Group,即 PD 集群中 PD 服务的个数决定了 PD 的副本数,3 PD 节点集群的 PD 副本数为 3,5 PD 节点集群的 PD 副本数为 5。
由上一段落中 Raft 原理可知,一个 Raft Group 的容灾能力随节点数增加而加强,在一般的非关键业务场景下,建议部署 3 个 PD;建议在关键业务中部署 5 个 PD。
TiKV 是一个 Key-Value 存储系友差统,它是一个巨大的 Map,TiKV 提供有序遍历方法。下图展示了 region 以 3 副本模式存储在 4 台 TiKV 节点上的数据分布,TiKV 中的数据被切分成了 5 份 —— region 1~5,每个 region 的 3 个副本构成了一个 Raft Group,集群中共有 5 个 Raft Group,因此 TiKV 是 Multi-Raft 系统。
如上图所展示,虽然这个集群当前有 4 个 TiKV 实例,但一个 region 的 3 个副本只会被调度到其中 3 个 TiKV 上,也就是说 region 的副本数与 TiKV 实例数量无关,即使将上图的集群扩容到 1000 个 TiKV 实例,它也仍然是一个 3 副本的集群。
前面说到 3 副本的 Raft Group 只能容忍 1 副本故障,当上图的集群被扩容到 1000 个 TiKV 实例时,这个集群依然只能容忍一个 TiKV 实例的故障,2 个 TiKV 实例的故障可能会导致某些 region 丢失多个副本,整个集群的数据也不再完整,访问到这些 region 上的数据的 SQL 请求将会失败。
而 1000 个 TiKV 中同时有两个发生故障的概率是远远高于 3 个 TiKV 中同时有两个发生故障的概率的,也就是说 Multi-Raft 集群在逐步扩容中,其可用性是逐渐降低的。
TiKV Label 用于描述 TiKV 的位置信息,在 inventory.ini 中,其写法如下:
上面案例中规划了 4 层位置信息的 Label,Label 信息会随着 deploy.yml 或 rolling_update.yml 操作刷新到 TiKV 的启动配置文件中,启动后的 TiKV 会将自己最新的 Label 信息上报给 PD,PD 根据用户登记的 Label 名称(也就是 Label 元信息),结合 TiKV 的拓扑进行 region 副本的最优调度。用户可以根据自己的需要来定制 Label 名称,以及 Label 层级(注意层级有先后顺序),但需要注意 PD 会根据它读到的 Label 名称(含层级关系)去匹配 TiKV 的位置信息,如果 PD 读到的 TiKV Label 信息与 PD 中设置的 Label 名称不匹配的话,就不会按用户设定的方式进行副本调度。Label 名称的设置方法如下,在初次启动集群时,PD 会读取 inventory.ini 中的设置:
非初次启动的集群,需要使用 pd-ctl 工具进行 Label 名称设置:
从本质上来说,Label 系统是一种 PD 对 region 副本(replica)的隔离调度策略。
PD 首先读取到集群的 region 副本数信息*,假定副本数为 5。PD 将所有 TiKV 汇报给它的 Label 信息进行汇总(以本章第 1 小节的 TiKV 集群为例),PD 构建了整个 TiKV 集群的拓扑,其逻辑如下图所示:
PD 识别到第一层 Label - dc 有 3 个不同的值,无法在本层实现 5 副本的隔离。PD 进而判断第二层 Label - zone,本层有 z1~z5 这 5 个 zone,可以实现 5 副本的隔离调度,PD 会将各个 region 的 5 个副本依次调度到 z1~z5 中,因此 z1~z5 各自所对应的 4 个 TiKV 所承载的 region 数量总和应完全一致。此时,PD 的常规调度策略,如 balance-region,hot-region 等 region 相关的 scheler 将严格遵守 Label 的隔离策略进行调度,在带有 z1~z5 Label 信息的 TiKV 尚在的情况下不会将同一个 region 的多个副本调度到同一个 zone 中。如图,图中将 TiKV 按照 zone 做 4 个一组隔离开了,一个 region 的一个副本只会在本 zone 的 4 个 TiKV 之间调度。
PD 天生不会将同一个 region 的多个副本调度到同一个 TiKV 实例上,增加 Label 信息后,PD 不会将同一个 region 的多个副本调度到同一个 host 上,以避免单台服务器的宕机导致丢失多个副本。
当带有某一个 zone Label 的 TiKV 全部故障时,如图中所有带有 z5 Label 的几个 TiKV 实例 kv252-1,kv252-2,kv253-1,kv253-2 同时故障时,集群会进入缺失一个副本的状态,在达到 TiKV 最大离线时间的设置值(max-store-down-time,默认值 30min)之后,PD 便开始在其他 4 个 zone 中补全所有缺失副本的 region,同时遵循上面一段所提到的约束,在为 region1 补全副本时,PD 会避开所有包含 region1 的服务器(本例中的 host)h208,h210,h414,h416 所涉及的 8 个 TiKV 实例,而在另外 8 个 TiKV 实例中挑选一个进行副本补全调度。
*副本数设置方法如下,以 5 副本为例:
Label 登记的是 TiKV 的物理位置信息,PD 根据 TiKV 的物理位置进行最优调度,其目的是在具有相近物理位置的 TiKV 上只放置一个副本,以尽可能的提高 TiKV 集群的可用性。举个例子,假设某一时刻集群中一定要有两个 TiKV 同时发生故障,那么你一定不想它们上面存储着一个 region 的两个副本,而通过合理规划让同时故障的两个 TiKV 出现在同一个隔离区的概率变高,TiKV 集群的整体可用性也就越高。因此 Label 规划要与 TiKV 物理位置规划一起进行,两者是相辅相成的。
举例而言,机房可能会由于电源故障,空调故障,网络故障,火灾,自然灾害等原因而整体不可用;机柜可能由于交换机故障,UPS 故障,消防喷淋等原因而整体不可用;服务器可能由于常见的内存等故障而宕机。通过妥善的 Label 规划,使 region 调度按物理位置进行隔离,可以有效地降低一个区域故障造成的整体影响。
物理位置的层级结构一般为机房,机柜,服务器,在大型基础设施中还会在机房与机柜之间多一个楼层信息。设计 Label 层级结构的最佳实践是基于物理层级结构再加上一层逻辑层级,该逻辑层级专门用于控制保持与集群副本数一致,在本案例中,zone 就是逻辑层级,该层级的值在集群搭建初期与 rack 保持一一对应,用于控制副本的隔离。而不直接采用 dc,rack,host 三层 Label 结构的原因是考虑到将来可能发生 rack 的扩容(假设新扩容的 rack 编号是 r6,r7,r8,r9,r10),这个扩容会导致 rack 数变多,当多个 TiKV 实例同时发生故障时,这些故障的 TiKV 出现在在多个 rack 上的概率也会增加,也就是会将第三章提到的 Multi-Raft 集群的可用性随节点数增加而下降问题再次引入到集群中。而通过使用逻辑层级 zone 保持与副本数一致可以将多个故障的 TiKV 出现在不同的隔离区(本例中的 zone)的概率降至最低,将来扩容 rack 也可以充分的利用到更多的 rack 的物理隔离来提高可用性。
在使用了 Label 隔离的集群中,存在以下限制:
规划了 Label 的集群再扩容时需要对每个隔离区进行容量一致的扩容,在本章的案例中,隔离区为 dc 和 rack 标示的位置,因此需要对每种 dc+rack 组合的区域进行容量一致的扩容,比如将要扩容 5 台 TiKV 服务器,其分配方法如下:
zone1=>dc1:rack1 增加一台 TiKV
zone2=>dc1:rack2 增加一台 TiKV
zone3=>dc2:rack1 增加一台 TiKV
zone4=>dc2:rack2 增加一台 TiKV
zone5=>dc3:rack1 增加一台 TiKV**
㈦ 在 ARM64 上面运行 TiDB
相比于 Intel 的 x86-64 架构,ARM 架构虽然作为后来者,但在服务器领域也开始在不停庆颂地攻城拔寨,很多企业也开始将自己的服务迁移到 ARM 架构上面,自然,对于 TiDB 来说,大家也想将 TiDB 运行到 ARM 上面。因为 AWS 上面直接提供了 ARM 机型,所以我们决定先尝试在 AWS 的 ARM 上面编译运行 TiDB。
TiDB 主要包含三个组件 - PD,TiKV 和 TiDB,对于 PD 和 TiDB 来说,使用的是 Go 进行编译的,所以我们只需要在 ARM 机器上面装好 Go 的版本就可以了。这里,我使用的是 go1.12.6.linux-arm64 这个版本。
用 Go 编译 TiDB 和 PD 比较容易,中途遇到了一个 TiDB 的编译问题,只需要升级下 vendor 就解决了。
编译 TiKV 就比较麻烦了,因为我们使用的是 CentOS 系统,系统用 yum 就能安装相关的依赖,除了 cmake3 ,装 cmake 需要做如下处理:
当然,编译 RocksDB 还有 Titan 的时候还遇到了一些错误,不过多数就是传递编译参数的时候需要处理下 ARM64 相关的选项,并不是特别的困难。
总的来说,编译并没有花太多的时间,这里有一个 脚本 ,大家可以自行去看如何在 ARM64 上面编译 TiDB。对于运行集群需要的 Grafana 和 Prometheus,官方都提供了 ARM64 版本,大家可以直接去 Google。
编译好了 ARM64 的版本,自然就是测试了,这里我使用了 go-ycsb 进行了简单的测试,这里我使用的是 16c32g 的 ARM64 机器,顺带也开了一台同配置的 x86 作为对比。
在每台测试机器上面,启动一个 PD,一个 TiKV,使用的是默认配置,然后 go-ycsb 使用 100 并发,导入 1 百万数据,操作次数 1 百万,batch size 为 0。
结果如下:
可以看到,ARM 的机器性能比 x86 的差了很多,需要来优化了。在网上找了这篇 文章 ,使用了上面的脚本,但发现没有什么变化。在这个脚本里面,主要的优化就是将网卡中断的处理绑定到某一个 CPU 上面,然后将 RPS 分散到不同的 CPU。对于 16c32g 的机器来说,这个脚本将网卡中断的处理绑定到 CPU core 0 和 8 上面,然后把 RPS 分散到所有的 CPU 上面,但是我通过 mpstat 发现,core 0 和 8 几乎被打满:
于是我重新调了下,将 RPS 分散到除开 core 0 和 8 的地方:
然后 OPS 稍微提升了一点,但 CPU core 0 和 8 仍然是瓶颈。而这个瓶颈明显是网络处理造成的,直观的优化就是减少网络消息的处理,于是将 batch size 设为 128,可以发现在 ARM 上面性能提升很多,譬如对于 workload C,OPS 能提升到 118270。但即使这样,CPU core 0 和 8 还是会成为瓶颈。
对比 ARM,x86 下面 CPU 的分配明显的均匀很多:
所以后面我磨差山们要考虑的事情就是如何让 ARM 能更好的处理网络消息。
上面简单的说了一下如何在 ARM 上面瞎中编译运行 TiDB,以及一些调优策略。个人认为,虽然 ARM 在性能上面还赶不上相同配置的 x86,但低功耗,成本这些是一个非常大的优势,加上很多不可说的原因,个人认为会有越来越多的企业使用 ARM,所以这块也会是趋势。