当前位置: 首页 > 后端技术 > Python

开源项目:prome_shard:consulwatch+动态分片实现Prometheus采集端高可用

时间:2023-03-26 12:45:31 Python

架构图开源项目地址:项目地址:https://github.com/ning1875/prome_shard项目描述Prometheus采集终端单点问题采集类型采集机器级指标采集k8s基础监控指标采集部署vm服务指标采集lb背后的业务pod中部署的指标采集各种中间件指标,如kafka、zkclickhouse等,面对如此复杂的采集类型,一般采用批量采集。Prometheus履行职责,sd发现问题。面对不同的采集源,都有对应的服务发现类型,比如k8s_sd,我们修改Prometheus代码,适应不同类型的服务发现,比如lb后面挂了一些指标,需要感知通过lb的服务发现对后端服务器进行变更,但问题是每个采集器都是单点的,修改适配不同的发现源。当然也可以不假思索的启动多个相同的收集器来收集同一组作业,配合remote_write来弥补单点问题,但是会带来额外的成本。不同发现源的缺点总结prometheus版本不能统一。有各种配置文件需要定义各种采集源或sd方法。本项目介绍使用一组收集器在consul中注册服务器,通过python反射运行定时任务,通过服务树Targets池等外部接口获取,一致性hash分发到后端,统一通过file_sd到生效后,consul会检测每组collector实例,当节点发生变化(宕机或扩容)时会触发targetsrebalance,达到HA架构描述解析配置文件的目的同步注册服务给consul,让消费者异步监听watch结果变化watch每个服务trigger/get_service生成hashring并定时获取targetcolumn根据hashring为每个节点生成专属文件通过ansible发送sd_result文件并重新加载已有的prometheus方法配置文件定义了方法名和对应的实例列表,并定义对应的方法get_targets中的sd。本质说明:都可以转成file_sd,只需要给consul相应的target结构watch问题golang可以在golang中使用很容易做到,详见我的文章开源项目:dynamic-sharding:SolvethepushgatewayHA问题。这个项目在python中有点复杂,需要改成阻塞查询defblock_get_health(self,service_name,service_hash_map,dq):index=NonewhileTrue:try:index,d=self.consul.health.service(service_name,passing=True,index=index)ifd:data=dnew_nodes=[]forx在数据中:address=x.get("Service").get("Address")ifaddress:new_nodes.append(address)old_nodes=service_hash_map[service_name].nodesifset(old_nodes)!=set(new_nodes):logging.info("[new_num:{}old_num:{}][new_nodes:{}old_nodes:{}]".format(len(new_nodes),len(old_nodes),",".join(new_nodes),",".join(old_nodes),))new_ring=ConsistentHashRing(100,new_nodes)service_hash_map[service_name]=new_ringdq.appendleft(str(service_name))#dq.put(str(service_name))M_SERVICE_CHANGES.labels(service_name=service_name,old_nodes=len(old_nodes),new_nodes=len(new_nodes)).set(len(new_nodes))exceptExceptionase:logging.error("[watch_error,service:{},error:{}]".format(service_name,e))time.sleep(5)continuecollector单点/固定的分片的问题,不管是单点分片还是固定分片,都不哈。只要某个shard的collector挂了,就会使用consul_watch_service方法生成loss对应的数据,并根据返回的healthyinstance生成一个一致的hashring。分片到健康节点的目标分配可以使用方法gitclonehttps://github.com/ning1875/prome_shard添加配置并在config.yaml中填写consul地址并填写作业。需要同步get_targets.pyget_targets.py是prome_shard发现使用收集targetspool的方法需要实现GetTarget方法。方法名需要和config.yaml中的一致。比如config.yaml中有一个名为scrape_prome_ecs_inf的job,那么GetTarget中就需要定义方法@classmethoddefscrape_prome_ecs_inf(cls):该方法的返回值为找到的目标列表,形式为[{"labels":{"group":"SGT","env":"prod","service":"scrape_prome","region":"ap-southeast-3","scrape_type":"vm"},"targets":["1.1.1.1:9090"]}]prome_shard根据返回的目标为配置中定义的节点分配一致的哈希值水池