diff --git a/basic-features.md b/basic-features.md index 2ff9db7f3fe6..2f8ae215a200 100644 --- a/basic-features.md +++ b/basic-features.md @@ -1,5 +1,6 @@ --- title: TiDB 基本功能 +summary: 了解 TiDB 的基本功能。 category: introduction --- @@ -9,17 +10,17 @@ category: introduction ## 数据类型 -- 数值类型: BIT、BOOL|BOOLEAN、SMALLINT、MEDIUMINT、INT|INTEGER、BIGINT、FLOAT、DOUBLE、DECIMAL。 +- 数值类型:BIT、BOOL|BOOLEAN、SMALLINT、MEDIUMINT、INT|INTEGER、BIGINT、FLOAT、DOUBLE、DECIMAL。 -- 日期和时间类型: DATE、TIME、DATETIME、TIMESTAMP、YEAR。 +- 日期和时间类型:DATE、TIME、DATETIME、TIMESTAMP、YEAR。 -- 字符串类型: CHAR、VARCHAR、TEXT、TINYTEXT、MEDIUMTEXT、LONGTEXT、BINARY、VARBINARY、BLOB、TINYBLOB、MEDIUMBLOB、LONGBLOB、ENUM、SET。 +- 字符串类型:CHAR、VARCHAR、TEXT、TINYTEXT、MEDIUMTEXT、LONGTEXT、BINARY、VARBINARY、BLOB、TINYBLOB、MEDIUMBLOB、LONGBLOB、ENUM、SET。 - JSON 类型。 ## 运算符 -- 算术运符、位运算符、比较运算符、逻辑运算符、日期和时间运算符等。 +- 算术运算符、位运算符、比较运算符、逻辑运算符、日期和时间运算符等。 ## 字符集及排序规则 @@ -29,19 +30,19 @@ category: introduction ## 函数 -- 控制流函数、字符串函数、日期和时间函数、位函数、数据类型转换函数、数据加解密函数、压缩和解压函数、信息函数、JSON 函数、聚合函数、窗口函数、信息函数等。 +- 控制流函数、字符串函数、日期和时间函数、位函数、数据类型转换函数、数据加解密函数、压缩和解压函数、信息函数、JSON 函数、聚合函数、窗口函数等。 ## SQL 语句 -- 完全支持标准的 Data Definition Statements 语句,例如:CREATE、DROP、ALTER、RENAME、TRUNCATE 等。 +- 完全支持标准的 Data Definition Language (DDL) 语句,例如:CREATE、DROP、ALTER、RENAME、TRUNCATE 等。 -- 完全支持标准的 Data Manipulation Statements 语名,例如:INSERT、REPLACE、SELECT、Subqueries、UPDATE、LOAD DATA 等。 +- 完全支持标准的 Data Manipulation Language (DML) 语句,例如:INSERT、REPLACE、SELECT、Subqueries、UPDATE、LOAD DATA 等。 -- 完全支持标准的 Transactional and Locking Statements 语名,例如:START TRANSACTION、COMMIT、ROLLBACK、SET TRANSACTION 等。 +- 完全支持标准的 Transactional and Locking 语句,例如:START TRANSACTION、COMMIT、ROLLBACK、SET TRANSACTION 等。 -- 完全支持标准的 Database Administration Statements 语名,例如:SHOW、SET 等。 +- 完全支持标准的 Database Administration 语句,例如:SHOW、SET 等。 -- 完全支持标准的 Utility Statements语句, 例如:DESCRIBE、EXPLAIN、USE 等。 +- 完全支持标准的 Utility 语句,例如:DESCRIBE、EXPLAIN、USE 等。 - 完全支持 SQL GROUP BY 和 ORDER BY 子语句。 @@ -69,7 +70,7 @@ category: introduction ## 安全 -- 支持基于 RBAC 的权限管理。 +- 支持基于 RBAC (role-based access control) 的权限管理。 - 支持密码管理。 @@ -81,7 +82,7 @@ category: introduction ## 工具 -- 支持快速备份功能 +- 支持快速备份功能。 - 支持通过工具从 MySQL 迁移数据到 TiDB。 diff --git a/mysql-compatibility.md b/mysql-compatibility.md index 4fd7471d883a..7d7ffeac07cb 100644 --- a/mysql-compatibility.md +++ b/mysql-compatibility.md @@ -206,4 +206,4 @@ mysql> select _tidb_rowid, id from t; + 不支持 SERIAL (alias for BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE)。 -+ 不支持 SQL_TSI_* (包括 SQL_TSI_YEAR、SQL_TSI_MONTH、SQL_TSI_WEEK、SQL_TSI_DAY、SQL_TSI_HOUR、SQL_TSI_MINUTE 和 SQL_TSI_SECOND)。 ++ 不支持 `SQL_TSI_*`(包括 SQL_TSI_YEAR、SQL_TSI_MONTH、SQL_TSI_WEEK、SQL_TSI_DAY、SQL_TSI_HOUR、SQL_TSI_MINUTE 和 SQL_TSI_SECOND)。 diff --git a/overview.md b/overview.md index 942d43ac4080..41931f331d63 100644 --- a/overview.md +++ b/overview.md @@ -33,17 +33,17 @@ TiDB 是 PingCAP 公司自主设计、研发的开源分布式关系型数据库 ## 四大核心应用场景 - 对数据一致性及高可靠、系统高可用、可扩展性、容灾要求较高的金融行业属性的场景 - - 众所周知,金融行业对数据一致性及高可靠、系统高可用、可扩展性、容灾要求较高,传统的解决方案是同城两个机房提供服务、异地一个机房提供数据容灾能务但不提供服务,此解决方案存在资源利用率低、维扩成本高、RTO 及 PRO 无法真实达到企业所期望的值。TiDB 采用多副本 + Mutli Raft 协议的方式将数据调度到不同的机房、机架、机器,当部分机器故障时系统可自动进行切换,确保系统的 RTO <= 30s 及 RPO = 0 。 - -- 对存储容量、可扩展性、并发要求较高的海量数量及高并的 OLTP 场景 - + + 众所周知,金融行业对数据一致性及高可靠、系统高可用、可扩展性、容灾要求较高。传统的解决方案是同城两个机房提供服务、异地一个机房提供数据容灾能务但不提供服务,此解决方案存在以下缺点:资源利用率低、维护成本高、RTO (Recovery Time Objective) 及 RPO (Recovery Point Objective) 无法真实达到企业所期望的值。TiDB 采用多副本 + Multi-Raft 协议的方式将数据调度到不同的机房、机架、机器,当部分机器出现故障时系统可自动进行切换,确保系统的 RTO <= 30s 及 RPO = 0 。 + +- 对存储容量、可扩展性、并发要求较高的海量数据及高并发的 OLTP 场景 + 随着业务的高速发展,数据呈现爆炸性的增长,传统的单机数据库无法满足因数据爆炸性的增长对数据的容量要求,可行方案是采用分库分表的中间件产品或者 NewSQL 数据库替代、采用高端的存储设备等,其中性价比最大的是 NewSQL 数据库,例如:TiDB。TiDB 采用计算、存储分离的架构,可对计算、存储分别进行扩容和缩容,计算节点最大支持 512 节点,每个节点最大支持 1000 并发,集群容量最大支持 PB 级别。 - + - Real-time HTAP 场景 - - 随着 5G、物联网、人工智能的高速发展,企业所生产的数据会越来越多,其规模可能达到数百 TB 甚至 PB 级别,传统的解决方案是通过 OLTP 型数据库处理在线联机交易业务,通过 ETL 工具将数据同步到 OLAP 型数据库进行数据分析,这种处理方案存在存储成本高、实际性差等多方面的问题。TiDB 在 4.0 版本中引入列存储引擎 TiFlash 结合行存储引擎 TiKV 构建真正的 HTAP 数据库,在增加少量存储成本的情况下,可以同一个系统中做联机交易处理、实时数据分析,极大的节省企业的成本。 - + + 随着 5G、物联网、人工智能的高速发展,企业所生产的数据会越来越多,其规模可能达到数百 TB 甚至 PB 级别,传统的解决方案是通过 OLTP 型数据库处理在线联机交易业务,通过 ETL 工具将数据同步到 OLAP 型数据库进行数据分析,这种处理方案存在存储成本高、实际性差等多方面的问题。TiDB 在 4.0 版本中引入列存储引擎 TiFlash 结合行存储引擎 TiKV 构建真正的 HTAP 数据库,在增加少量存储成本的情况下,可以同一个系统中做联机交易处理、实时数据分析,极大的节省企业的成本。 + - 数据汇聚、二次加工处理的场景 - - 当前绝大部分企业的业务数据都分散在不同的系统中,没有一个统一的汇总,随着业务的发展,企业的决策层需要了解整个公司的业务状况方便即时的做出决策,故需要将分散在各个系统的数据汇聚在同一个系统并进行二次加工处理生成 T + 0/1 的报表。传统常见的解决方案是采用 ETL + Hadoop 来完成,但 Hadoop 体系统太复杂,运维、存储成本太高无法满度用户的需求。与 Hadoop 相比,TiDB 就会简单得多,业务通过 ETL 工具或者 TiDB 的同步工具将数据同步到 TiDB,在 TiDB 中可通过 SQL 直接生成报表。 + + 当前绝大部分企业的业务数据都分散在不同的系统中,没有一个统一的汇总,随着业务的发展,企业的决策层需要了解整个公司的业务状况方便即时的做出决策,故需要将分散在各个系统的数据汇聚在同一个系统并进行二次加工处理生成 T + 0/1 的报表。传统常见的解决方案是采用 ETL + Hadoop 来完成,但 Hadoop 体系统太复杂,运维、存储成本太高无法满足用户的需求。与 Hadoop 相比,TiDB 就简单得多,业务通过 ETL 工具或者 TiDB 的同步工具将数据同步到 TiDB,在 TiDB 中可通过 SQL 直接生成报表。 diff --git a/tune-tikv-thread-performance.md b/tune-tikv-thread-performance.md index 776ae8555ce7..c5a57c26d819 100644 --- a/tune-tikv-thread-performance.md +++ b/tune-tikv-thread-performance.md @@ -12,40 +12,57 @@ category: reference 在 TiKV 4.0 中,线程池主要由 gRPC、Scheduler、UnifyReadPool、Raftstore、Apply、RocksDB 以及其它一些占用 CPU 不多的定时任务与检测组件组成,这里主要介绍几个占用 CPU 比较多且会对用户读写请求的性能产生影响的线程池。 -* gRPC 线程池处理所有网络请求,它会把不同任务类型的请求转发给不同的线程池。 -* Scheduler 线程池负责检测写事务冲突,把事务的两阶段提交、悲观锁上锁、事务回滚等请求转化为 key-value 对数组,然后交给 Raftstore 线程进行 Raft 日志复制。 -* Raftstore 线程池负责处理所有的 Raft 消息以及添加新日志的提议 (Propose)、将日志写入到磁盘,当日志在多数副本中达成一致后,它就会把该日志发送给 Apply 线程。 -* Apply 线程收到从 Raftstore 线程池发来的已提交日志后将其解析为 key-value 请求,然后写入 RocksDB 并且调用回调函数通知 gRPC 线程池中的写请求完成,返回结果给客户端。 -* RocksDB 线程池是 RocksDB 进行 Compact 和 Flush 任务的线程池,关于 RocksDB 的架构与 Compact 操作请参考 [RocksDB: A Persistent Key-Value Store for Flash and RAM Storage](https://github.com/facebook/rocksdb)。 -* UnifyReadPool 是 TiKV 4.0 推出的新特性,它由之前的 Coprocessor 线程池与 Storage Read Pool 合并而来,所有的读取请求包括 kv get、kv batch get、raw kv get、coprocessor 等都会在这个线程池中执行。 +* gRPC 线程池:负责处理所有网络请求,它会把不同任务类型的请求转发给不同的线程池。 +* Scheduler 线程池:负责检测写事务冲突,把事务的两阶段提交、悲观锁上锁、事务回滚等请求转化为 key-value 对数组,然后交给 Raftstore 线程进行 Raft 日志复制。 +* Raftstore 线程池:负责处理所有的 Raft 消息以及添加新日志的提议 (Propose)、将日志写入到磁盘,当日志在多数副本中达成一致后,它就会把该日志发送给 Apply 线程。 +* Apply 线程池:当收到从 Raftstore 线程池发来的已提交日志后,负责将其解析为 key-value 请求,然后写入 RocksDB 并且调用回调函数通知 gRPC 线程池中的写请求完成,返回结果给客户端。 +* RocksDB 线程池:RocksDB 进行 Compact 和 Flush 任务的线程池,关于 RocksDB 的架构与 Compact 操作请参考 [RocksDB: A Persistent Key-Value Store for Flash and RAM Storage](https://github.com/facebook/rocksdb)。 +* UnifyReadPool 线程池:TiKV 4.0 推出的新特性,由之前的 Coprocessor 线程池与 Storage Read Pool 合并而来,所有的读取请求包括 kv get、kv batch get、raw kv get、coprocessor 等都会在这个线程池中执行。 ## TiKV 的只读请求 -TiKV 的读取请求分为两类,一类是指定查询某一行或者某几行的简单查询,这类查询会运行在 Storage Read Pool 中;另一类是复杂的聚合计算、范围查询,这类请求会运行在 Coprocessor Read Pool 中。从 4.0 版本开始,支持两类读取请求使用同一个线程池,以减少线程数量,降低用户使用成本,默认不开启(默认点查询和 Coprocessor 请求使用不同的线程池)。用户可以通过设置配置 `readpool.storage.use-unified-pool` 为 true 来打开统一线程池。 +TiKV 的读取请求分为两类: + +- 一类是指定查询某一行或者某几行的简单查询,这类查询会运行在 Storage Read Pool 中。 +- 另一类是复杂的聚合计算、范围查询,这类请求会运行在 Coprocessor Read Pool 中。 + +从 4.0 版本开始,支持两类读取请求使用同一个线程池,以减少线程数量,降低用户使用成本,默认不开启(默认点查询和 Coprocessor 请求使用不同的线程池)。用户可以通过将 `readpool.storage.use-unified-pool` 设置为 true 来打开统一线程池。 ## TiKV 线程池调优 -* gRPC 线程池的大小默认配置(`server.grpc-concurrency`)是 4。由于 gRPC 线程池几乎不会有多少计算开销,它主要负责网络 IO、反序列化请求,因此该配置通常不需要调整,如果部署的机器 CPU 特别少(小于等于 8),可以考虑将该配置(`server.grpc-concurrency`)设置为 2,如果机器配置很高,并且 TiKV 承担了非常大量的读写请求,观察到 Grafana 上的监控 Thread CPU 的 gRPC poll CPU 的数值超过了 server.grpc-concurrency 大小的 80%,那么可以考虑适当调大 `server.grpc-concurrency` 以控制该线程池使用率在 80% 以下 (即 Grafana 上的指标低于 `80% * server.grpc-concurrency` 的值)。 +* gRPC 线程池的大小默认配置(`server.grpc-concurrency`)是 4。由于 gRPC 线程池几乎不会有多少计算开销,它主要负责网络 IO、反序列化请求,因此该配置通常不需要调整。 + + - 如果部署的机器 CPU 核数特别少(小于等于 8),可以考虑将该配置(`server.grpc-concurrency`)设置为 2。 + - 如果机器配置很高,并且 TiKV 承担了非常大量的读写请求,观察到 Grafana 上的监控 Thread CPU 的 gRPC poll CPU 的数值超过了 server.grpc-concurrency 大小的 80%,那么可以考虑适当调大 `server.grpc-concurrency` 以控制该线程池使用率在 80% 以下(即 Grafana 上的指标低于 `80% * server.grpc-concurrency` 的值)。 + +* Scheduler 线程池的大小配置 (`storage.scheduler-worker-pool-size`) 在 TiKV 检测到机器 CPU 核数大于等于 16 时默认为 8,小于 16 时默认为 4。它主要用于将复杂的事务请求转化为简单的 key-value 读写。但是 **scheduler 线程池本身不进行任何写操作**。 -* Scheduler 线程池的大小配置 (`storage.scheduler-worker-pool-size`) 在 TiKV 检测到机器 CPU 数大于等于 16 时默认为 8,小于 16 时默认为 4。它主要用于将复杂的事务请求转化为简单的 key-value 读写。但是 **scheduler 线程池本身不进行任何写操作**,如果检测到有事务冲突,那么它会提前返回冲突结果给客户端,否则的话它会把需要写入的 key-value 合并成一条 Raft 日志交给 Raftstore 线程进行 raft 日志复制。通常来说为了避免过多的线程切换,最好确保 scheduler 线程池的利用率保持在 50%~75% 之间。(如果线程池大小为 8 的话,那么 Grafana 上的 TiKV-Details.Thread CPU.scheduler worker CPU 应当在 400%~600% 之间较为合理) + - 如果检测到有事务冲突,那么它会提前返回冲突结果给客户端。 + - 如果未检测到事务冲突,那么它会把需要写入的 key-value 合并成一条 Raft 日志交给 Raftstore 线程进行 Raft 日志复制。 + + 通常来说为了避免过多的线程切换,最好确保 scheduler 线程池的利用率保持在 50%~75% 之间。(如果线程池大小为 8 的话,那么 Grafana 上的 TiKV-Details.Thread CPU.scheduler worker CPU 应当在 400%~600% 之间较为合理) -* Raftstore 线程池是 TiKV 最为复杂的一个线程池,默认大小(`raftstore.store-pool-size`)为 2,所有的写请求都会先在 Rafttore 线程 fsync 的方式写入 RocksDB (除非手动将 `raftstore.sync-log` 设置为 false;而 `raftstore.sync-log` 设置为 false,可以提升一部分写性能,但也会增加在机器故障时数据丢失的风险)。由于存在 IO,Raftstore 线程理论上不可能达到 100% 的 CPU。为了尽可能地减少写磁盘次数,将多个写请求攒在一起写入 RocksDB,最好控制其整体 CPU 使用在 60% 以下(按照线程数默认值 2,则 Grafana 监控上的 TiKV-Details.Thread CPU.Raft store CPU 上的数值控制在 120% 以内较为合理)。不要为了提升写性能盲目增大 Raftstore 线程池大小,这样可能会适得其反,增加了磁盘负担让性能变差。 +* Raftstore 线程池是 TiKV 最为复杂的一个线程池,默认大小(`raftstore.store-pool-size`)为 2,所有的写请求都会先在 Raftstore 线程 fsync 的方式写入 RocksDB(除非手动将 `raftstore.sync-log` 设置为 false;而 `raftstore.sync-log` 设置为 false,可以提升一部分写性能,但也会增加在机器故障时数据丢失的风险)。 -* UnifyReadPool 负责处理所有的读取请求。默认配置(`readpool.unified.max-thread-count`)大小为机器 CPU 数的 80% (如机器为 16核,则默认线程池大小为 12)。通常建议根据业务负载特性调整其 CPU 使用率在线程池大小的 60%~90% 之间 (如果用户 Grafana 上 TiKV-Details.Thread CPU.Unified read pool CPU 的峰值不超过 800%, 那么建议用户将 `readpool.unified.max-thread-count` 设置为 10,过多的线程数会造成更频繁的线程切换,并且抢占其他线程池的资源)。 + 由于存在 I/O,Raftstore 线程理论上不可能达到 100% 的 CPU。为了尽可能地减少写磁盘次数,将多个写请求攒在一起写入 RocksDB,最好控制其整体 CPU 使用在 60% 以下(按照线程数默认值 2,则 Grafana 监控上的 TiKV-Details.Thread CPU.Raft store CPU 上的数值控制在 120% 以内较为合理)。不要为了提升写性能盲目增大 Raftstore 线程池大小,这样可能会适得其反,增加了磁盘负担让性能变差。 + +* UnifyReadPool 负责处理所有的读取请求。默认配置(`readpool.unified.max-thread-count`)大小为机器 CPU 数的 80% (如机器为 16核,则默认线程池大小为 12)。 + + 通常建议根据业务负载特性调整其 CPU 使用率在线程池大小的 60%~90% 之间 (如果用户 Grafana 上 TiKV-Details.Thread CPU.Unified read pool CPU 的峰值不超过 800%, 那么建议用户将 `readpool.unified.max-thread-count` 设置为 10,过多的线程数会造成更频繁的线程切换,并且抢占其他线程池的资源)。 * RocksDB 线程池是 RocksDB 进行 Compact 和 Flush 任务的线程池,通常不需要配置。 - * 如果机器 CPU 数较少,可将 `rocksdb.max-background-jobs` 与 `raftdb.max-background-jobs` 同时设置为 4。 + * 如果机器 CPU 核数较少,可将 `rocksdb.max-background-jobs` 与 `raftdb.max-background-jobs` 同时设置为 4。 * 如果遇到了 Write Stall,可查看 Grafana 监控上 **RocksDB-kv** 中的 Write Stall Reason 有哪些指标不为 0。 - * 如果是由 pending compaction bytes 相关原因引起的,可将 `rocksdb.max-sub-compactions` 设置为 2 或者 3(该配置表示单次 compaction job 允许使用的子线程数量,TiKV 4.0 版本默认值为 3, 3.0 版本默认值为 1)。 - * 如果原因是 memtable count 相关,建议调大所有列的 `max-write-buffer-number`(默认为 5)。 - * 如果原因是 level0 file limit 相关,建议调大如下参数为 64 或者更高: - - ``` - rocksdb.defaultcf.level0-slowdown-writes-trigger - rocksdb.writecf.level0-slowdown-writes-trigger - rocksdb.lockcf.level0-slowdown-writes-trigger - rocksdb.defaultcf.level0-stop-writes-trigger - rocksdb.writecf.level0-stop-writes-trigger - rocksdb.lockcf.level0-stop-writes-trigger - ``` + * 如果是由 pending compaction bytes 相关原因引起的,可将 `rocksdb.max-sub-compactions` 设置为 2 或者 3(该配置表示单次 compaction job 允许使用的子线程数量,TiKV 4.0 版本默认值为 3, 3.0 版本默认值为 1)。 + * 如果原因是 memtable count 相关,建议调大所有列的 `max-write-buffer-number`(默认为 5)。 + * 如果原因是 level0 file limit 相关,建议调大如下参数为 64 或者更高: + + ``` + rocksdb.defaultcf.level0-slowdown-writes-trigger + rocksdb.writecf.level0-slowdown-writes-trigger + rocksdb.lockcf.level0-slowdown-writes-trigger + rocksdb.defaultcf.level0-stop-writes-trigger + rocksdb.writecf.level0-stop-writes-trigger + rocksdb.lockcf.level0-stop-writes-trigger + ```