m3db资源开销问题:无需用ssd,也没必要做raid

失常状况下m3db 对io要求不高

  • 因为和prometheus一样设计时采纳了mmap等技术,所以没必要采纳ssd
  • 和open-falcon/夜莺等采纳rrd不同,rrd 单指标单文件,很耗io

cpu和内存开销

  • 写峰很危险,起因很简略

    • 一条新的数据写入的时候,须要申请block,索引等一系列内存,随同着cpu开销
    • 然而如果没有新的数据,只是一直的写入点,那么只波及到点的append追加,则开销较小
    • 所以在突发的写峰对于tsdb来说就是危险,比方auto_scaling
    • 最现实的状况就是100w条数据,都是安稳的没有变动的继续追加点写入
    • 然而在容器中不事实,因为每次pod滚动都波及 id等惟一值的变动
  • 读峰也很危险,起因如下

    • m3db默认内置lru会缓存查问的block等,这个为了一个典型的场景
    • 就是一个dashboard查出来后点刷新工夫,除了工夫其余查问tag没变动,这种lru能应酬的很好
    • 然而对于高基数的查问来说,lru的意义就不大了
    • 而且会波及到读取放大的问题,假如1w基数须要100M内存,则100w基数须要10G内存

m3db bootstrap速度问题

  • 在节点oom或其余起因导致的重启中,bootstrap速度决定了节点多久能提供服务
  • bootstrap速度和namespace 数量正相干,和数据量大小正相干
  • 而且会优先提供写服务,防止长时间不能写入数据造成断点
  • 而且再重启时 会有大量读盘操作,根本能把io打满(因为须要将磁盘中的局部数据缓存到内存中)

聚合阐明

不要间接在m3coordinator 中开启聚合

  • 咱们晓得间接在m3coordinator中配置 type: aggregated的namespace是能够间接开启聚合的
  • 然而官网文档 说的很分明了
The M3 Coordinator also performs this role but is not cluster aware.This means metrics will not get aggregated properly if you send metrics in round robin fashion to multiple M3 Coordinators for the same metrics ingestion source (e.g. Prometheus server).
  • 因为数据依照轮询模式打过去到m3coordinator上,导致同一个指标的不同时刻数据可能呈现在多个m3coordinator上,聚合进去的后果就是错的

利用m3aggregator 做downsample

  • 与M3DB类似m3aggregator,默认状况下反对集群和复制。
  • 这意味着度量规范已正确路由到负责聚合每个度量规范的一个或多个实例
  • 并且m3aggregator能够配置多个正本,以使聚合没有单点故障。

降采样原理

  • m3agg依据配置的 resolution计算后推给 m3coordinator 回写m3db
  • 如下配置咱们能够降采样的保留监控数据:留神 上面距离和粒度都是依据grafana查问工夫算的step推算出的

    • default表:不聚合保留30小时
    • agg1表:5m为粒度保留96小时,即4天
    • agg2表:20m为粒度保留360小时,即15天
    • agg3表:60m为粒度保留360小时,即3个月
      - namespace: default        type: unaggregated        retention: 30h      - namespace: agg1        type: aggregated        retention: 96h        resolution: 5m      - namespace: agg2        type: aggregated        retention: 360h        resolution: 20m      - namespace: agg3        type: aggregated        retention: 2160h        resolution: 60m

降采样后多张表数据merge

  • 数据在每张表中都会存在
  • 根据不同的保留精度,agg会聚合写入后果
  • 多张表查问的时候,每个时间段以最准确的为准,也就是说会merge
  • 如果在查问端少配置了几张表,那么就是缺数据

利用聚合打到降采样的目标

  • 缩小存储需要
  • 对于工夫久的数据,以原始点寄存其实意义很小,因为查问的时候都会以较粗的精度出图,比方 15天范畴内可能就是1个小时一个点了

对于query的limit限度 ,这些限度都治标不治本,因为要看限度在多深的中央设置的

  • 举个例子:查问须要5次内存申请,只有在第4层能力断定这个query是否打到下限,那么只是省了最初一次内存申请
  • 这样就演变成了:每次都在很深的中央才限制住了,资源总是在节约
  • 如果能在第一层就限制住,如布隆过滤器间接通知不存在,那么则能够防止前面几次资源开销

m3db limit

  • 能够设置在一个回溯窗口内lookback 最大读取的工夫序列数据的总量maxRecentlyQueriedSeriesBlocks
  • 这个配置代表在3秒内最多容许 21w的block查问(7w来自于m3db监控图中的block数据)
  • maxOutstandingReadRequests 代表并发读申请数
  • maxRecentlyQueriedSeriesDiskRead能够设置读盘的限度
db:  limits:    maxRecentlyQueriedSeriesBlocks:      value: 700000      lookback: 3s    maxOutstandingWriteRequests: 0    maxOutstandingReadRequests: 0

爱护m3db的正确姿态,是在后面prometheus查问的时候 辨认并拦挡高基数查问

m3db 读写一致性

  • 在db高负载状况下,能够配置m3coordinator 读一致性为one 即readConsistencyLevel: one,升高后端压力
clusters:# Fill-out the following and un-comment before using, and# make sure indent by two spaces is applied.  - namespaces:      - namespace: default        type: unaggregated        retention: 30h    client:      config:        service:          env: default_env          zone: embedded          service: m3db          cacheDir: /var/lib/m3kv          etcdClusters:            - zone: embedded              endpoints:                - xxx1:2379                - xxx2:2379                - xxx3:2379      writeConsistencyLevel: majority      readConsistencyLevel: one

etcd操作

# 执行etcd host变量ETCDCTL_API=3HOST_1=xxxHOST_2=xxxHOST_3=xxxENDPOINTS=$HOST_1:2379,$HOST_2:2379,$HOST_3:2379# 获取匹配字符串的keyetcdctl --endpoints=$ENDPOINTS get  --prefix  "" --keys-only=true _kv/default_env/m3db.node.namespaces_sd.placement/default_env/m3db# 删除agg的placementetcdctl --endpoints=$ENDPOINTS del    /placement/namespace/m3db-cluster-name/m3aggregator## 删除namespaceetcdctl --endpoints=$ENDPOINTS del _kv/default_env/m3db.node.namespacesetcdctl --endpoints=$ENDPOINTS del _sd.placement/default_env/m3db

m3db dump火焰图

  • 留神在高负载状况下dump的速度会很慢
第一步:申请m3db:7201/debug/dump接口,m3db代码中内置好了生成pprof信息的zip接口
#!/usr/bin/env bashinput_host_file=$1output_dir=$2for i in `cat $1`;do    curl -s $i:7201/debug/dump >${output_dir}/${i}_`date "+%Y_%m_%d_%H_%M_%S"`.zip &done    
第二步:解压zip文件,查看goroutine 执行状况
  • 解压zip文件,能够失去cpu、heap、goroutine三个prof文件 和m3db的一些元信息
root@k8s-local-test-02:~/pprof$ lltotal 4060-rw-r--r-- 1 root root    3473 Dec 31  1979 cpu.prof-rw-r--r-- 1 root root 3953973 Dec 31  1979 goroutine.prof-rw-r--r-- 1 root root  178938 Dec 31  1979 heap.prof-rw-r--r-- 1 root root      40 Dec 31  1979 host.json-rw-r--r-- 1 root root     592 Dec 31  1979 namespace.json-rw-r--r-- 1 root root    5523 Dec 31  1979 placement-m3db.json
grep goroutine goroutine.prof  | awk -F '[' '/goroutine \d*/{print "[" $2}' |sort | uniq -c | sort -k1nr | head -20# 能够看到哪些goroutine最多# 再依据具体的信息分析程序问题  16800 [select]:   9422 [chan receive, 40355 minutes]:   1911 [select, 2 minutes]:    631 [runnable]:    509 [IO wait]:     90 [chan receive, 40341 minutes]:     76 [chan receive]:     72 [semacquire]:     25 [select, 291 minutes]:     23 [sleep]:     17 [chan receive, 7205 minutes]:     17 [chan receive, 7402 minutes]:     14 [select, 4 minutes]:     12 [chan receive, 6120 minutes]:     10 [chan receive, 5577 minutes]:      5 [select, 165 minutes]:      4 [chan receive, 5176 minutes]:      4 [select, 40355 minutes]:      3 [chan receive, 7404 minutes]:      2 [IO wait, 40355 minutes]:
第三步: 利用火焰图剖析工具分析程序内存和cpu性能
  • 装置 graphviz工具
yum -y install graphviz
  • 依据prof文件生成svg图片,用浏览器关上svg图片即可查看
go tool pprof -svg cpu.prof > cpu.svg
  • 依据prof文件构建http拜访查看
go tool pprof -http=localhost:8088 cpu.prof 
  • 火焰图样例