TiDB DM扩容和监控

TiDB DM扩容和监控
简介
• TiDB Data Migration (DM) 是一体化的数据迁移任务管理平台,支持从 MySQL 或 MariaDB 到 TiDB 的全量数据迁移和增量数据复制。我们使用DM实时同步数据从MySQL到TiDB。dm开始配置时dm-master和dm-work都是单节点,为保证同步的可靠性对dm节点进行扩容和状态配置报警。
• DM2.0提供了DM-master和DM-work的高可用,把之前的单节点修改为多节点增加可靠性。
• 修改报警方式实现自定义报警功能。Prometheus+Alertmanager+python三个部分实现自定义报警。
– dm单节点扩容成三节点。
– Prometheus负责配置警报规则,将警报发送到Alertmanager。
– Alertmanager 负责管理这些警报,包括沉默,抑制,合并和发送通知。
现状
• 上游MySQL做了分库分表同步到一个TiDB集群,DM对分库分表进行合并。合并后的数据统计和分析。
• DM-master和DM-worker开始部署成了单点,虽然不是核心业务但也要保重数据实效性,保证dm的高可用必不可少。
• 现在DM的报警也不完善,需要修改成通过公司自己的报警接口实现打电话和发短信功能。
• dm现在集群结构:
[tidb@BJTIDB-1 ~]$ tiup dm display xx-dm
Found dm newer version:

The latest version:         v1.2.3
Local installed version:    v1.1.1
Update current component:   tiup update dm
Update all components:      tiup update --all

Starting component dm: /home/tidb/.tiup/components/dm/v1.1.1/tiup-dm display xx-dm
dm Cluster: xx-dm
dm Version: v2.0.0
ID Role Host Ports OS/Arch Status Data Dir Deploy Dir


10.1.1.2:9095 alertmanager 10.1.1.2 9095/9096 linux/x86_64 Up /data/dm/dm-data/alertmanager-9095/data /data/dm/dm-deploy/alertmanager-9095
10.1.1.3:8261 dm-master 10.1.1.3 8261/8291 linux/x86_64 Healthy|L /data/dm/dm-data/dm-master-8261/data /data/dm/dm-deploy/dm-master-8261
10.1.1.4:8262 dm-worker 10.1.1.4 8262 linux/x86_64 Bound /data/dm/dm-data/dm-worker-8262 /data/dm/dm-deploy/dm-worker-8262
10.1.1.2:3001 grafana 10.1.1.2 3001 linux/x86_64 Up - /data/dm/dm-deploy/grafana-3001
10.1.1.2:9091 prometheus 10.1.1.2 9091 linux/x86_64 Up /data/dm/dm-data/prometheus-8249/data /data/dm/dm-deploy/prometheus-8249
上述拓扑文件中仅包含1 master 节点和1 worker 节点。
TiDB-DM集群扩容
• DM高可用描述:当部署的 DM-worker 节点数超过上游 MySQL/MariaDB 节点数时,超出上游节点数的相关 DM-worker 节点默认将处于空闲状态。若某个 DM-worker 节点下线或与 DM-master leader 发生网络隔离,DM-master 能自动将与原 DM-worker 节点相关的数据迁移任务调度到其他空闲的 DM-worker 节点上(若原 DM-worker 节点为网络隔离状态,则其会自动停止相关的数据迁移任务);若无空闲的 DM-worker 节点可供调度,则原 DM-worker 相关的数据迁移任务将无法进行

  1. 配置DM集群扩容拓扑文件(扩容两个DM-master和DM-worker节点)。
    [tidb@BJTIDB-1 ~]$ vim scale-out.yaml
    ======================================================================
    master_servers:
  • host: 10.1.1.6
    name: master2
    port: 8261
    peer_port: 8291
    deploy_dir: /data/dm/dm-deploy/dm-master-8261
    data_dir: /data/dm/dm-data/dm-master-8261/data
    log_dir: /data/dm/dm-deploy/dm-master-8261/log
  • host: 10.1.1.2
    name: master3
    port: 8261
    peer_port: 8291
    deploy_dir: /data/dm/dm-deploy/dm-master-8261
    data_dir: /data/dm/dm-data/dm-master-8261/dvim
    log_dir: /data/dm/dm-deploy/dm-master-8261/log

worker_servers:

  • host: 10.1.1.7
    port: 8262
    deploy_dir: /data/dm/dm-deploy/dm-worker-8262
    log_dir: /data/dm/dm-deploy/dm-worker-8262/log
  • host: 10.1.1.8
    port: 8262
    deploy_dir: /data/dm/dm-deploy/dm-worker-8262
    log_dir: /data/dm/dm-deploy/dm-worker-8262/log
  1. 使用tiup执行如下命令进行DM节点扩容
    tiup dm scale-out xx-dm scale-out.yaml
  2. 查看扩容后的DM集群状态
    [tidb@BJTIDB-1 ~]$ tiup dm display xx-dm
    Starting component dm: /home/tidb/.tiup/components/dm/v1.2.5/tiup-dm display xx-dm
    Cluster type: dm
    Cluster name: xx-dm
    Cluster version: v2.0.0
    SSH type: builtin
    ID Role Host Ports OS/Arch Status Data Dir Deploy Dir

10.1.1.2:9095 alertmanager 10.1.1.2 9095/9096 linux/x86_64 Up /data/dm/dm-data/alertmanager-9095/data /data/dm/dm-deploy/alertmanager-9095
10.1.1.3:8261 dm-master 10.1.1.3 8261/8291 linux/x86_64 Healthy|L /data/dm/dm-data/dm-master-8261/data /data/dm/dm-deploy/dm-master-8261
10.1.1.6:8261 dm-master 10.1.1.6 8261/8291 linux/x86_64 Healthy /data/dm/dm-data/dm-master-8261/data /data/dm/dm-deploy/dm-master-8261
10.1.1.2:8261 dm-master 10.1.1.2 8261/8291 linux/x86_64 Healthy /data/dm/dm-data/dm-master-8261/data /data/dm/dm-deploy/dm-master-8261
10.1.1.4:8262 dm-worker 10.1.1.4 8262 linux/x86_64 Bound /data/dm/dm-data/dm-worker-8262 /data/dm/dm-deploy/dm-worker-8262
10.1.1.7:8262 dm-worker 10.1.1.7 8262 linux/x86_64 Free /data/dm/dm-data/dm-worker-8262 /data/dm/dm-deploy/dm-worker-8262
10.1.1.8:8262 dm-worker 10.1.1.8 8262 linux/x86_64 Free /data/dm/dm-data/dm-worker-8262 /data/dm/dm-deploy/dm-worker-8262
10.1.1.2:3001 grafana 10.1.1.2 3001 linux/x86_64 Up - /data/dm/dm-deploy/grafana-3001
10.1.1.2:9091 prometheus 10.1.1.2 9091 linux/x86_64 Up /data/dm/dm-data/prometheus-8249/data /data/dm/dm-deploy/prometheus-8249
DM监控部署
• 使用Prometheus+Alertmanager+python三个部分实现自定义报警。prometheus和alertmanager使用安装dm时自动的自带的监控软件。
• Alertmanager 发送通知有多种方式,其内部集成了邮箱、Slack、企业微信等方式,也提供了webhook的方式来扩展报警通知方式,网上也有大量例子实现对第三方软件的集成,如钉钉等。下面介绍通过Python自定义接口调用公司报警接口实现报警推送。
• 下面内容主要分为四块:
– prometheus报警规则配置
– alertmanager配置及部署
– 关联prometheus和alertmanager
– 配置报警通知方式
prometheus配置
• prometheus.yml属性配置文件说明,dm使用了安装时自带的prometheus配置文件,报警规则也使用默认的配置文件。
属性 描述
scrape_interval 样本采集周期,自带的默认15s采集一次
evaluation_interval 告警规则计算周期,自带的默认为15s计算一次
rule_files 指定告警规则的文件
scrape_configs job的配置项,里面可配多组job任务
job_name 任务名称,需要唯一性
static_configs job_name的配置选项,一般使用file_sd_configs 热加载配置
alertmanamger配置&部署
• alertmanager会定义一个基于标签匹配规则的路由树,用以接收到报警后根据不同的标签匹配不同的路由,来将报警发送给不同的receiver。如果定义一个路由route则需要接收并处理所有的报警,如果需要区分不同的报警发送给不同的receiver,则需要配置多个子级route来处理不同的报警,而根route此时必须能够接收处理所有的报警。
• 修改默认的配置文件alertmanager.yml
global:
resolve_timeout: 60m

The smarthost and SMTP sender used for mail notifications.

smtp_smarthost: ‘smtp.163.com:25
smtp_from: ‘monitoring@163.com’
smtp_auth_username: ‘monitoring@163.com’
smtp_auth_password: ‘1’
smtp_require_tls: false
route:
#根路由

A default receiver

receiver: “xx_dba”
#顶级路由配置的接收者(匹配不到子级路由,会使用根路由发送报警)
group_by: [‘instance’,‘alertname’]
#分组规则,如果满足group_by中包含的标签,则这些报警会合并为一个通知发给receiver
group_wait: 30s
#设置等待时间,在此等待时间内如果接收到多个报警,则会合并成一个通知发送给receiver
group_interval: 5m
#两次报警通知的时间间隔,如:5m,表示发送报警通知后,如果5分钟内再次接收到报警则不会发送通知
repeat_interval: 30m
#发送相同告警的时间间隔,如:30m,表示4小时内不会发送相同的报警
routes:
#子路由的接收者

  • match:
    #字符串匹配,匹配当前标签team的值为frontend的报警
    level: emergency
    receiver: xx_dba
  • match:
    level: critical
    receiver: xx_dba
  • match:
    level: warning
    receiver: xx_dba
    receivers:
    #定义所有接收者
  • name: ‘xx_dba’
    #接收者名称
    webhook_configs:
    #接收者为webhook类型
    • send_resolved: true
      url: ‘http://xxx/api/call_the_police
      #webhook的接收地址,这个地址是用python自定义的一个处理消息的接口,处理逻辑如下
      • 在重启alertmanager进程,使新的配置文件生效。
      自定义报警接口
      • 添加报警规则,由于POST数据需要有要求,简单实现一个数据转发脚本。使用python起了个数据转发的接口。
      • 使用webhook方式,alertmanager会给配置的地址发送一个http类型的post请求,参数为json字符串(字符串类型),如下python代码对接收的消息做过滤处理,再调用内部的报警接口将消息推送给值班人员。
      import alert
      def call_the_police(request):
      from include.common import gaia_push
      if request.method == “POST”:
      data = json.loads(request.body)
      ret_voice = DbaDuty.objects.get_now_duty() # 当前值班人员电话
      alist = [i for i in list(ret_voice)[0].values()]
      ret_voice_name = DbaDuty.objects.get_now_duty_name() # 当前值班人员电话
      alist_name = [i for i in list(ret_voice_name)[0].values()]
      ctime = datetime.datetime.now().strftime(’%Y-%m-%d %H:%M:%S’)
      try:
      alerts = data.get(“alerts”)
      for i in alerts:
      if i[“status”]==‘firing’:
      content = ‘\n【{}】\nlabels:\ncluster: {},\nalertname: {},\ninstance: {},\nlevel: {},’
      ‘\nannotations:\nsummary: {},’
      ‘\nvalue: {}\ntime:\nstartsAt: {},’.format(i[“status”],i[“labels”][“cluster”],i[“labels”][“alertname”],i[“labels”][“instance”],
      i[“labels”][“level”],i[“annotations”][“summary”],i[“annotations”][“value”],i[“startsAt”])
      if i[“labels”][“level”]==“warning”:
      res = alert.push_text_msg(content, [“dba”])
      else:
      res = alert.push_text_msg(content, alist_name)
      recipients = [{“mobile”: int(i)} for i in alist]
      ret_sms = sms_alert(content, recipients)
      voice_recipients = [
      {‘mobile’: i, ‘params’: {‘ctime’: ctime, ‘classify’: “TiDB”, ‘alertType’: “TiDB”}} for i in
      alist]
      result = alert_gaia_voice(voice_recipients)
      else:
      content = ‘\n已恢复\n【{}】\nlabels:\ncluster: {},\nalertname: {},\ninstance: {},\nlevel: {},’
      ‘\nannotations:\nsummary: {},’
      ‘\nvalue: {}\ntime:\nendsAt: {},’.format(i[“status”],i[“labels”][“cluster”], i[“labels”][“alertname”],
      i[“labels”][“instance”],
      i[“labels”][“level”], i[“annotations”][“summary”],
      i[“annotations”][“value”], i[“endsAt”])
      if i[“labels”][“level”]==“warning”:
      res = alert.push_text_msg(content, [“dba”])
      else:
      res = alert.push_text_msg(content, alist_name)
      recipients = [{“mobile”: int(i.phone)} for i in alist]
      ret_sms = sms_alert(content, recipients)

      except Exception as e:
          logger.info(e)
      

如下是一条报警信息:

报警配置总结
• alertmanager完全能够按照自己的目标定义灵活的通知和报警方式,尤其是对webhook的支持,简直灵活了。而且alertmanager还支持定义template来更清晰的彰显要通知的内容。但是没有发现alertmanager怎么配置热加载,后面还要再研究下怎么优化通知,避免告警轰炸和提高告警的准确性。