正如我们之前所言,在 3.0 当中,我们在产品底层做了很大的变化调整,除了架构更加科学高效以外,用户体验也是我们重点优化的方向。以之前一篇文章为例:对于 Update 功能,用户不再需要任何配置 ,默认即是比 2.0 更完善的机制。(https://mp.weixin.qq.com/s/7E8kl9W8IXROx_K0EGQPkg)
切换到 3.0 版本之后(《如何把数据从 TDengine 2.x 迁移到 3.x ?》),我们面对的第一个问题就是建库建表,在 3.0 版本中,这部分逻辑发生了重大变化,这对于 3.0 初体验的用户来说是十分重要的,是数据库后续查询/写入性能保障的根基。有些表数量比较多的用户刚换到 3.0 的时候,会感觉性能和 2.x 差一些,其实就是因为建库时使用了默认配置,导致 vgroup 数量只有 2 个,因此无法利用到 TDengine 多线程并行的特性来处理数据。
相比起 2.0 ,3.0 的建表策略控制是很简单的,它可以让用户无难度无成本地找到自己适合的配置。
简而言之:只需要在建库的时候指定合适的参数即可。
在 2.0 版本中,很多用户都阅读过这篇文章:https://mp.weixin.qq.com/s/H2GCESF40wnWYf4IKP_-9g,以期用自定义的建表逻辑来获得更好的性能,更合理的开销。
这篇文章中的几个参数的逻辑着实是需要读者好好理解一番的,而它复杂的根本在于,在 2.0 版本下,每个 vnode 的表数量在固定后是不可再调整的,所以只可以通过前期设定相对复杂的规则来实施控制。
而在 3.0 中,为了支持云原生场景下资源的灵活调配,不论是时序数据与元数据都需要分布式技术才可以做到。为此,我们把存在于 mnode 的普通表元数据移除(具体细节可参考:https://www.taosdata.com/engineering/14534.html),让其完全分布到了 vnode 上,采取了一致性哈希这种具有较好的容错性和可扩展性的算法,以支持 vnode 的可拆分的特性(该特性会在未来的 3.x 企业版本中发布)
因此, 3.0 和 2.0 的建表流程是完全不一样的,细节如下:
- 首先在建库时,每个 vgroup 会负责存储 0 至 2 的 32 次方-1 的等分长度;
- 建表阶段,TDengine 3.0 首先会在客户端通过对表名进行 hash 计算,得到一个 hash 值;
- 向管理节点发出 rpc 请求,取回数据库配置和 vgroups 的相关内容等信息;
- 把建表请求中的 hash 值和取回的每个 vgroup 的 hash 范围做一个比对;
- 把请求直接发送到对应的 vgroup 中的 vnode 上完成建表。(如果对 vgroup 和 vnode 的关系并不清晰,可以先移步 https://docs.taosdata.com/tdinternal/arch/)
基于以上全新的建表方式,我们可以发现,所建的每一个表的走向完全是受哈希函数来控制的,我们只需要控制好容器的数量就行了。
因此,在 database 级别,我们引入了这样一个参数—— vgroups ,用来指定该数据库使用的 vgroup 的数量。
比如:
create database test vgroups 8 ;
就会创建一个拥有 8 个 vgroup 的数据库 test ,你在这个库下新建的所有表,都会均匀地分配在 8 个 vgroup 里面。
而在他的上一级,还有更高级别的参数 supportVnodes(默认 /etc/taos/taos.cfg 中配置),它决定了该数据节点可以支持的 vnode 数量,默认值为 0 ,代表 CPU 核数的2倍。
我们建库时需要确保所有 dnode(数据节点)的 supportVnodes 之和,大于等于所有库的 vnode 数目之和即可,否则会就报如下错误:Out of dnodes,提示你需要补充新的 dnode。
显然,在 3.0 的架构下,用户在建表的时候就省心多了,大家只需根据硬件资源规划好 vgroups 的数量就行了。
在 vgroups 参数值的估算上,对于大部分场景依然保持和 2.0 一样的逻辑。即——由于每个 vnode 都是一个相对独立的工作单元,具有独立的运行线程和内存空间,所以不超过该机器 CPU 核数的 2 倍即可。
但对于一些特定场景,vgroups 的值则需要结合多方因素做更精细化的计算,需要自己理解和多多调试,也欢迎联系企业版团队得到更深层次的性能优化。