共计 4550 个字符,预计需要花费 12 分钟才能阅读完成。
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=3
HOST_1=xxx
HOST_2=xxx
HOST_3=xxx
ENDPOINTS=$HOST_1:2379,$HOST_2:2379,$HOST_3:2379
# 获取匹配字符串的 key
etcdctl --endpoints=$ENDPOINTS get --prefix "" --keys-only=true
_kv/default_env/m3db.node.namespaces
_sd.placement/default_env/m3db
# 删除 agg 的 placement
etcdctl --endpoints=$ENDPOINTS del /placement/namespace/m3db-cluster-name/m3aggregator
## 删除 namespace
etcdctl --endpoints=$ENDPOINTS del _kv/default_env/m3db.node.namespaces
etcdctl --endpoints=$ENDPOINTS del _sd.placement/default_env/m3db
m3db dump 火焰图
- 留神在高负载状况下 dump 的速度会很慢
第一步:申请 m3db:7201/debug/dump 接口,m3db 代码中内置好了生成 pprof 信息的 zip 接口
#!/usr/bin/env bash
input_host_file=$1
output_dir=$2
for 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$ ll
total 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
- 火焰图样例
正文完