当前位置: 首页 > 科技观察

多机房数万台服务器管理实践

时间:2023-03-14 01:13:59 科技观察

管理多个机房数万台服务器的实践完美的自动化工具。HULK平台的命令系统可以在批处理机上执行脚本,命令系统底层基于SaltStack开发。当然最大的问题是部署机器的机房多,机器数量多,部署SaltStack的Master会遇到问题。我们采用多层多机房Master架构。多级大师将使用Syndic。Syndic消息传输对网络的依赖比较大,但是公司内部的多机房网络比较复杂,Syndic丢消息的概率比较高。下面将介绍一些使用Syndic的“坑”以及改善报??文丢失的方法。SaltStack结构这是对Salt结构的总体介绍,方便初学者以后阅读。Master节点负责发布命令和管理以下机器。托管机器节点部署Minion来监听命令。SaltSyndic介绍,当Minion数量超过一定规模时,Master的性能就会成为瓶颈。这时候就会考虑部署多个节点的Master来解决性能问题,但是随之而来的是易用性的下降,命令的执行需要走到对应的Master节点。Syndic被添加到SaltStack0.9.0版本中。Syndic架构的出现正好解决了这个问题。Syndic是一个特殊的Minion。核心代码在minion.py中。Syndic和低级别的Master运行在同一台主机上。Syndic连接的Master是高级Master。优点通过Syndic,可以建立多层架构,所有命令都可以由一个高级别的Master来执行。这个Master叫做MasterOfMasters,架构比较灵活。由于Syndic只订阅MasterOfMasters的消息,文件服务等其他服务都需要配置在Syndic节点上,大大减轻了MasterOfMasters的压力。缺点Syndic上file_roots和pillar_roots的配置要和MasterOfMasters保持一致。MasterOfMasters仅与Syndic通信。结果,大师中的大师不知道下面有多少小兵;当命令在MasterOfMasters上执行时,在发送给Syndic的过程中,如果网络出现抖动,导致收不到消息或者延迟接收,MasterOfMasters没有任何感知,最终会导致整个任务的不完整返回结果。架构图问题Syndic在网络不可靠的情况下,消息传递的可靠性相对降低。如果Syndic没有收到消息,那么后面的Minions就不会收到这个任务。.官方建议是增加syndic_wait参数,但这只能缓解部分情况,在实际环境中效果并不明显。通过上面的介绍思考,Syndic其实就是一个Minion,那么Syndic是不是可以用其他方案代替呢?这里首先要解决的问题是ZeroMQ。Redis还支持Pub/Sub模式,可以采用主从架构部署在多个机房。RedisPub/Sub模式性能良好。测试首先测试ZeroMQ和Redis的Pub/Sub模式。结论是申诉测试是在同一机房的测试。同等网络条件下,ZeroMQ完成消息传输的速度比Redis快,但也有消息丢失的情况,测试结果不如Redis。是的,您可以尝试使用Redis而不是ZeroMQ。主要流程1.在MasterOfMasters上启动一个Subscribe流程,将数据发布到Redis专用的Channel。详细代码如下:self.opts['master_addr']=salt.utils.dns_check(self.opts['master'])//获取master的ip地址context=zmq.Context()master_pub='tcp://{0}:{1}'.format(self.opts['master_addr'],self.opts['master_publish_port'])ub_sock=context.socket(zmq.SUB)sub_sock=set_tcp_keepalive(sub_sock,opts=self.opts)sub_sock.connect(master_pub)sub_sock.setsockopt(zmq.SUBSCRIBE,b'')//开始订阅:pool=ConnectionPool(host=self.opts['redis_host'],port=self.opts['redis_port'],db=self.opts['redis_db'],password=self.opts['redis_pass'])#发送消息到puberPUBsockwhileTrue:message=sub_sock.recv_multipart()//从ZeroMQ订阅消息r=Redis(connection_pool=pool)r.publish("salttest",message)//将订阅的消息发布到Redis中的Channel,Channel名称为"salttest"2.在从Master节点开始Publish和Return处理消息(原Syndic节点),详细代码如下:发布:self.opts['master_addr']=salt.utils.dns_check(self.opts['master'])context=zmq.Context()pub_uri='tcp://{interface}:{publish_port}'.format(**self.opts)pub_sock=context.socket(zmq.PUB)pub_sock=set_tcp_keepalive(pub_sock,opts=self.opts)pub_sock.bind(pub_uri)尝试:conn_pool=client.ConnectionPool(host=self.opts['redis_host'],port=self.opts['redis_port'],db=self.opts['redis_db'],password=self.opts['redis_pass'])sub=client.PubSub(conn_pool)sub.subscribe('salttest')//订阅频道为“salttest”的消息formsginsub.listen():ifmsg['type']=='message'://判断消息类型data=eval(msg['data'])pub_sock.send_multipart(data)//通过ZeroMQ发布消息注意:返回码比较简单,所以这里省略3.在Master的配置文件中指定刚刚配置的端口(这里使用4515和4516,因为是在Master上启动的)。syndic_master:node1.example.comsyndic_master_port:4516syndic_master_publish_port:4515总结完之后可以发现这其实是一个使用RedisPub/Sub的SaltSyndic。这种模式已经使用了一段时间,消息丢失的情况已经大大减少了。