作者:刘安

爱可生测试团队成员,主要负责 DTLE 开源项目相关测试任务,擅长 Python 自动化测试开发。

本文来源:原创投稿

*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。


背景:

最近接到一个工单:DTLE client 被部署在两个机房,其中只有 DTLE clinst 可以相互访问,所以希望故障转移时能在对应机房内切换。

网络结构如下图:

通过分析网络结构可知:

  1. DTLE client 只能访问本地机房的 MySQL
  2. 如果发生故障转移,只能调度到本地机房的 DTLE client 上执行才能保证新的 task 能访问到对应的 MySQL 实例

因为 DTLE 只是作为 Nomad 的插件运行,其只负责数据传输任务,任务调度工作则是由 Nomad 来完成的,所以还是要到 Nomad 的文档里去寻找答案。

查看 Nomad 的文档发现可以通过在 job 中配置constraint属性来指定故障转移的范围,接下来我们就展示一下constraint属性怎么使用。

一、DTLE job 的结构

一个 DTLE job 里包含两个 group ,每个 gourp 里包含一个 task ,task 里包含了 DTLE 任务的配置信息,task 最终被部署到 DTLE client 上执行。如下图:

二、constraint 简介

  1. constraint可以严格限制符合条件的 client 集,该属性可以定义在 job、group 或者 task 层上。

由于 DTLE job 的每个 group 下只有一个 task ,我们的目的是约束 task 的故障转移域,而源端 task 和目标端 task 又有不同的故障转移域,所以对于工单中遇到的问题,我们可以把constraint定义在 group 层或者 task 层。

  1. constraint的参数包括attributeoperatorvalue

    a. attribute 指定要过滤的属性,可以是任何Nomad的节点属性。以下是节点属性的完整列表:

    Variable Description Example Value
    ${node.unique.id} 36 character unique client identifier 9afa5da1-8f39-25a2-48dc-ba31fd7c0023
    ${node.region} Client’s region global
    ${node.datacenter} Client’s datacenter dc1
    ${node.unique.name} Client’s name nomad-client-10-1-2-4
    ${node.class} Client’s class linux-64bit
    ${attr.} Property given by property on the client ${attr.cpu.arch} => amd64
    ${meta.} Metadata value given by key on the client ${meta.foo} => bar


Property Description
${attr.cpu.arch} CPU architecture of the client (e.g. amd64, 386)
${attr.cpu.numcores} Number of CPU cores on the client
${attr.cpu.totalcompute} cpu.frequency × cpu.numcores but may be overridden by client.cpu_total_compute
${attr.consul.datacenter} The Consul datacenter of the client (if Consul is found)
${attr.driver.} See the task drivers for property documentation
${attr.unique.hostname} Hostname of the client
${attr.unique.network.ip-address} The IP address fingerprinted by the client and from which task ports are allocated
${attr.kernel.name} Kernel of the client (e.g. linux, darwin)
${attr.kernel.version} Version of the client kernel (e.g. 3.19.0-25-generic, 15.0.0)
${attr.platform.aws.ami-id} AMI ID of the client (if on AWS EC2)
${attr.platform.aws.instance-type} Instance type of the client (if on AWS EC2)
${attr.platform.aws.placement.availability-zone} Availability Zone of the client (if on AWS EC2)
${attr.os.name} Operating system of the client (e.g. ubuntu, windows, darwin)
${attr.os.version} Version of the client OS

以上属性中${node.datacenter}${node.unique.name}等都是可以在DTLE节点启动时在配置文件中指定的

b. operator指定比较运算符,默认值为=。更多的运算符可以在 https://www.nomadproject.io/docs/job-specification/constraint#operator 查看。

c. value指定要与使用指定操作的属性进行比较的值, 默认值为空字符串。

三、具体操作

  1. 挑选合适的节点属性

    a. ${node.unique.id}${node.unique.name}只能过滤指定的一个节点,所以不能做故障转移的筛选条件

    b. 根据Nomad的文档介绍,一个job下的task是不能部署在两个不同的region上的,所以${node.region}不能做故障转移的筛选条件

    c. ${attr.<property>}是 DTLE 节点添加到集群时自动收集的节点服务器信息,所以不适合做故障转移的筛选条件

    d. 最后只剩下${node.datacenter}${node.class}${meta.<key>}三个可配置的属性作为故障转移的筛选条件。其中${node.datacenter}${node.class}可以看做在节点上配置一个可供筛选的标签,而${meta.<key>}则可以看做是在节点上同时配置多个可供筛选的标签

  2. 部署DTLE 集群

    a. 部署一个有三个 DTLE client 节点的集群,一个节点的datacenter设为shanghai,两个节点的datacenter设为beijing

   # dtle配置文件
   name = "dtle-1" # rename for each node
   datacenter = "shanghai" 
   ...

b. 提交一个 DTLE job ,分别配置源端 task 和目标端 task 的constraint属性为shanghaibeijing

   job "test_constraint" {
     # 此处表示该job可以运行在datacenter为"shanghai"和"beijing"的节点上。${node.class}、${meta.<key>}不需关注此项配置
     datacenters = ["shanghai", "beijing"]
   
     group "Src" {
       constraint {
         attribute  = "${node.datacenter}"
         operator   = "="
         value      = "shanghai"
       }
       task "src" {
         driver = "dtle"
         config {
           ReplicateDoDb = [{
             TableSchema = "test"
           }]
           ConnectionConfig = {
             Host = "172.100.9.1"
             Port = 3306
             User = "test_src"
             Password = "test_src"
           }
         }
       }
     }
     group "Dest" {
       constraint {
         attribute  = "${node.datacenter}"
         operator   = "="
         value      = "beijing"
       }
       task "dest" {
         driver = "dtle"
         config {
           ConnectionConfig = {
             Host = "172.100.9.2"
             Port = 3306
             User = "test_dest"
             Password = "test_dest"
           }
         }
       }
     }
   }

c. 查看 task 分配状态,task 被正确的分配在不同的datacenter节点上

查看 job overview 页面:

查看 clients 页面:

d. 停止dtle-2节点,按预期目标端 task 转移到datacenter同为beijingdtle-3节点上运行

查看 job overview 页面,故障转移完成:

clients 页面:

e. 停止dtle-3节点。因为没有datacenterbeijing的 DTLE 节点,即使还有dtle-1在正常运行,但是无法完成故障转移,任务失败

查看 job overview 页面,显示无法找到datacenterbeijing的 DTLE 节点:

查看 clients 页面:

四、结语

本文展示了如何利用datacenter属性来实现故障转移域的限制。如何利用 Nomad 的其他属性、其他的比较运算符来配置约束条件,大家可以在 DTLE 开源群中一起讨论。


参考文档:

https://www.nomadproject.io/docs/job-specification/constraint

https://www.nomadproject.io/docs/runtime/interpolation#interpreted_node_vars

DTLE repo:

https://github.com/actiontech/dtle

QQ讨论群:852990221


avatar
100
  Subscribe  
提醒