暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

TSDB -- M3DB Prometheus远端存储方案

devops运维先行者 2020-01-07
262

开篇

本文承接前文 Prometheus 监控架构 -- 生产级别,其中主要介绍Prometheus的远端TSDB存储 -- M3DB,包括M3DB集群部署及原理。

介绍

M3于2015年发布,目前拥有超过66亿个时间序列。M3每秒聚合5亿个指标,并在全球范围内(使用M3DB)每秒持续存储2000万个度量指标,批量写入将每个指标持久保存到区域中的三个副本。它还允许工程师编写度量策略,告诉M3以更短或更长的保留时间(两天,一个月,六个月,一年,三年,五年等)以特定的粒度(一秒,十秒,一分钟,十分钟等)。这允许工程师和数据科学家使用与定义的存储策略匹配的度量标签(标签),在精细和粗粒度范围内智能地存储不同保留的时间序列。例如,工程师可以选择存储“应用程序”标记为“mobile_api”且“端点”标记为“注册”的所有度量标准,这些标记在10秒粒度下为30天,在一小时粒度下为5年。

M3特性

M3具有作为离散组件提供的多个功能,使其成为大规模时间序列数据的理想平台,主要包括四个组件 -- M3 Coordinator、M3DB、M3 Query、M3 Aggregator

  • 分布式时间序列数据库M3DB,它为时间序列数据和反向索引提供可伸缩的存储。
  • 辅助进程M3Coordinator,允许M3DB充当Prometheus的长期存储。
  • 分布式查询引擎M3Query,其对PromQL和Graphite的原生支持(即将推出M3QL)。
  • 聚合层M3Aggregator,作为专用的度量聚合器/下采样器运行,允许以不同的分辨率以各种保留方式存储度量。

M3DB特性

  • 分布式时间序列存储,单个节点使用WAL提交日志并独立保存每个分片的时间窗口
  • 建立在etcd之上的集群管理
  • 内置同步复制,具有可配置的持久性和读取一致性(一个,多数,全部等)
  • M3TSZ float64压缩灵感来自Gorilla TSZ压缩,可配置为无损或有损任意时间精度可配置,范围从秒到纳秒,可通过任意写入切换精度可配置的无序写入,当前限于已配置时间窗口的块大小

M3DB限制

  • 由于M3DB需求的性质,主要是为了减少摄取和存储数十亿个时间序列的成本并提供快速可伸缩的读取,因此目前存在一些限制,使M3DB不适合用作通用时间序列数据库。
  • M3DB旨在尽可能避免压缩,目前,M3DB仅在可变压缩时间序列窗口(默认配置为2小时)内执行压缩。因此,乱序写入仅限于单个压缩时间序列窗口的大小。因此,当前无法回填大量数据。
  • M3DB还针对float64值的存储和检索进行了优化,因此尚无法将其用作包含任意数据结构的通用时间序列数据库。

分布式架构

M3db共有三种角色类型:

  • Coordinator:m3coordinator用于协调群集中所有主机之间的读取和写入。这是一个轻量级的过程,不存储任何数据。该角色通常将与Prometheus实例一起运行,或者被嵌入到收集器代理中。
  • Storage Node:在这些主机上运行的m3dbnode进程是数据库的主力,它们存储数据,并提供读写功能。
  • Seed Node:首先,这些主机本身就是存储节点。除了该职责外,他们还运行嵌入式ETCD服务器。这是为了允许跨集群运行的各种M3DB进程以一致的方式推断集群的拓扑/配置。

存储引擎

压缩算法

主要压缩算法M3TSZ,是Gorilla paper算法的变体,根据UBER的数据特征,每个points压缩后达到1.45 bytes大小,压缩率很高。

内存架构

架构说明

  • 每个M3DB进程只有一个database
  • 每个database有多个namespace, 每个namespace有独立的名字和配置(根据数据保留和块代销)namespace相当于普通数据库中的表
  • 一个namespace包含多个shard, shards按照series ID的哈希值来分配数据
  • 一个shard包含多个series
  • 一个series包含多个blocks对象
block类型
  • fileset file:已写入磁盘,数据密封、压缩
  • In-memory cache:已在内存中缓存,还未写入磁盘,数据密封、压缩
  • active buffer:数据已压缩、未密封

集群部署

环境准备

  • 系统环境 Centos7.4 4c/16G
  • 172.16.7.170  node1
  • 172.16.7.171  node2
  • 172.16.7.172  node3
  • 172.16.10.12 coordinator
本文安装方式DockerK8S集群安装m3db-operator的可以参考官方Github m3db-operator

etcd集群部署

node1、node2、node3、coordinator操作

yum install etcd -y

附上etcd基础配置文件

    #etcd配置文件/etc/etcd/etcd.conf
    ETCD_DATA_DIR="/etcd-data"
    ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
    ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
    ETCD_NAME="node1" #依次为node2,node3,node4
    ETCD_INITIAL_ADVERTISE_PEER_URLS="http://node1:2380"
    ETCD_ADVERTISE_CLIENT_URLS="http://node1:2379"
    ETCD_INITIAL_CLUSTER="node1=http://node1:2380,node2=http://node2:2380,node3=http://node3:2380"
    ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
    ETCD_INITIAL_CLUSTER_STATE="new"

    依次启动etcd节点:systemctl start etcd

    查看节点:etcdctl member list

      43bb846a7344a01f: name=node2 peerURLs=http://node2:2380 clientURLs=http://node2:2379 isLeader=false
      58c7b83d06ee71dc: name=node3 peerURLs=http://node3:2380 clientURLs=http://node3:2379 isLeader=false
      a9aee06e6a14d468: name=node1 peerURLs=http://node1:2380 clientURLs=http://node1:2379 isLeader=true

      M3DB集群部署

      mkdir opt/m3db etcd-data/m3db/cache -p

        cat << EOF >/opt/m3db/m3dbnode.yml
        coordinator:
        listenAddress:
        type: "config"
        value: "0.0.0.0:7201" # 交互端口


        local:
        namespaces:
        - namespace: default # 数据要存入的表
        type: unaggregated # 数据类型
        retention: 720h # 数据保存时间


        logging:
        level: error


        metrics: # coordinator本身的metric
        scope:
        prefix: "coordinator"
        prometheus:
        handlerPath: metrics
        listenAddress: 0.0.0.0:7203 # until https://github.com/m3db/m3/issues/682 is resolved
        sanitization: prometheus
        samplingRate: 1.0
        extended: none


        limits:
        maxComputedDatapoints: 10000


        tagOptions:
        # Configuration setting for generating metric IDs from tags.
        idScheme: quoted # 这个必须


        db:
        logging:
        level: error


        metrics:
        prometheus:
        handlerPath: metrics
        sanitization: prometheus
        samplingRate: 1.0
        extended: detailed


        listenAddress: 0.0.0.0:9000
        clusterListenAddress: 0.0.0.0:9001
        httpNodeListenAddress: 0.0.0.0:9002
        httpClusterListenAddress: 0.0.0.0:9003
        debugListenAddress: 0.0.0.0:9004


        hostID: #采用此配置文件自定义hostname
        resolver: config
        value: node1 #hostname为 node1,其余节点依次为node2,node3,node4[coordinator]


        client:
        writeConsistencyLevel: majority # 写一致性级别
        readConsistencyLevel: unstrict_majority


        gcPercentage: 100


        writeNewSeriesAsync: true
        writeNewSeriesLimitPerSecond: 1048576
        writeNewSeriesBackoffDuration: 2ms


        bootstrap:
        bootstrappers: # 启动顺序
        - filesystem
        - commitlog
        - peers
        - uninitialized_topology
        commitlog:
        returnUnfulfilledForCorruptCommitLogFiles: false


        cache:
        series:
        policy: lru
        postingsList:
        size: 262144


        commitlog:
        flushMaxBytes: 524288
        flushEvery: 1s
        queue:
        calculationType: fixed
        size: 2097152


        fs:
        filePathPrefix: etcd-data/m3db # m3dbnode数据目录


        config:
        service:
        env: default_env
        zone: embedded
        service: m3db # 服务名。可以按照consul中的service进行理解
        cacheDir: etcd-data/m3db/cache
        etcdClusters:
        - zone: embedded
        endpoints:
        - node1:2379
        - node2:2379
        - node3:2379
        EOF

        参数解释:
        hostID: 官方模板为系统环境,如

          hostID:
          resolver: environment
          envVarName: M3DB_HOST_ID

          或者

              hostID:
            resolver: hostname

            本文采用config方式,读取配置参数。
            tagOptions: 官方强烈推荐quoted,因为这个跟prometheus结合最好,另外的还有prepend_meta、legacy
            config:  官方演示文档上会有seedNodes的配置参数,由于采用了外部etcd集群,这里将完全删除seedNodes的配置项。
            namespaces: 默认default namespace数据保存时间为48h
            cache: 内存缓存的算法和大小,首推lru算法,即Least Recently Used (LRU) Cache Policy,当缓存已满的时候首先剔除最近最少读取的块。另外还有none -- None Cache Policy,all -- All Cache Policy,recently_read -- Recently Read Cache Policy。
            bootstrap: 启动m3db节点时引导shard,M3DB支持5种不同的bootstrappers -- filesystem、commitlog、peers、uninitialized_topology、noop-all,默认为本文的引导顺序。

            启动

            docker run -d -v opt/m3db/m3dbnode.yml:/etc/m3dbnode/m3dbnode.yml -v etcd-data/m3db:/etcd-data/m3db -p 7201:7201 -p 7203:7203 -p 9000:9000 -p 9001:9001 -p 9002:9002 -p 9003:9003 -p 9004:9004 --name m3db quay.io/m3db/m3dbnode:latest

            集群初始化

            placement init

              curl -sSf -X POST localhost:7201/api/v1/placement/init -d '
              {
              "num_shards": 1024,
              "replication_factor": 3,
              "instances": [
              {
              "id": "node1",
              "isolation_group": "node1",
              "zone": "embedded",
              "weight": 100,
              "endpoint": "172.16.7.170:9000",
              "hostname": "172.16.7.170",
              "port": 9000
              },
              {
              "id": "node2",
              "isolation_group": "node2",
              "zone": "embedded",
              "weight": 100,
              "endpoint": "172.16.7.171:9000",
              "hostname": "172.16.7.171",
              "port": 9000
              },
              {
              "id": "node3",
              "isolation_group": "node3",
              "zone": "embedded",
              "weight": 100,
              "endpoint": "172.16.7.172:9000",
              "hostname": "172.16.7.172",
              "port": 9000
              },
              {
              "id": "node4",
              "isolation_group": "node4",
              "zone": "embedded",
              "weight": 99,
              "endpoint": "172.16.10.12:9000",
              "hostname": "172.16.10.12",
              "port": 9000
              }
              ]
              }'

              Replication Factor Recommendations

              Replica FactorQuorum SizeFailure Tolerance
              110
              220
              321
              431
              532
              642
              743

              建议运行奇数个副本。因为偶数RF N的仲裁大小为(N 2)+1,所以具有偶数复制因子N的任何集群都具有与RF = N-1的相同的容错能力。


              例如,本文有4个node节点,采用3个副本数,可允许1个副本出现问题,2个副本将导致数据异常。

              namespace init



                curl -X POST localhost:7201/api/v1/namespace -d '
                {
                "name": "default",
                "options": {
                "bootstrapEnabled": true,
                "flushEnabled": true,
                "writesToCommitLog": true,
                "cleanupEnabled": true,
                "snapshotEnabled": true,
                "repairEnabled": false,
                "retentionOptions": {
                "retentionPeriodDuration": "720h",
                "blockSizeDuration": "12h",
                "bufferFutureDuration": "1h",
                "bufferPastDuration": "1h",
                "blockDataExpiry": true,
                "blockDataExpiryAfterNotAccessPeriodDuration": "5m"
                },
                "indexOptions": {
                "enabled": true,
                "blockSizeDuration": "12h"
                }
                }
                }'

                参数解析:

                • bootstrapEnabled:默认为true,控制M3DB在启动时是否将尝试引导名称空间。
                • flushEnabled:默认为true,控制了M3DB一旦块变为不可变状态,是否将定期将块刷新到磁盘。
                • writesToCommitlog:默认为true,控制M3DB是否将在提交日志中包括对此名称空间的写入。
                • snapshotEnabled:默认为true,控制M3DB是否会定期写出此命名空间的快照文件,这些快照文件充当压缩的commitlog文件。
                • repairEnabled:默认为false,如果启用,则M3DB节点将尝试将其拥有的数据与对等节点的数据进行比较,并发出有关任何差异的度量。
                retentionOptions:
                • retentionPeriod:控制了M3DB将保留名称空间数据的持续时间。
                • blockSize:在调整M3DB名称空间的性能时,这是要考虑的最重要的值。更大的blockSizes将使用更多的内存,但可获得更高的压缩率。同样,较小的blockSize将使用较少的内存,但压缩效果较差。在测试中,每个时间序列包含约720个样本的块大小会产生良好的压缩效果。以下是基于分辨率的块大小建议:
                ResolutionBlock Size
                5s60m
                15s3h
                30s6h
                1m12h
                5m60h

                Prometheus remote Write/Read

                  remote_read:
                  - url: "http://172.16.7.172:7201/api/v1/prom/remote/read"
                  read_recent: true
                  remote_write:
                  - url: "http://172.16.10.12:7201/api/v1/prom/remote/write"
                  queue_config:
                  batch_send_deadline: 60s
                  capacity: 40000
                  max_backoff: 600ms
                  max_samples_per_send: 8000
                  max_shards: 10
                  min_backoff: 50ms
                  min_shards: 6
                  remote_timeout: 30s

                  Remote write/read的对象是M3 Coordinator,由于m3db集群资源有限,除了对m3db进行优化外,还需要对prometheus进行优化。这里将remote write进行优化,详细可参考官方文档。

                  结语

                  当prometheus采集的数据越来越大,查询效率越来越低时,本地存储已经满足不了需求,希望这篇文章可以帮助到你,更多TSDB,敬请期待···

                  参考链接

                  https://github.com/m3db/m3db-operator https://github.com/m3db/m3/blob/master/src/dbnode/config/m3dbnode-cluster-template.yml https://prometheus.io/docs/practices/remote_write/#max_backoff

                  历史文章

                  运维神器 -- ELK

                  Prometheus 监控架构  -- 生产级别

                  Traefik版本升级与生产使用

                  Let's encrypt 通配域名(二级, 三级)

                  福利


                  文章转载自devops运维先行者,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                  评论