如何设计一个麻雀般的微型分布式架构?

2023-11-18

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~

本文由mariolu 发表于云+社区专栏

序言(初衷)

设计该系统初衷是基于描绘业务(或机器集群)存储模型,分析代理缓存服务器磁盘存储与回源率的关系。系统意义是在腾讯云成本优化过程中,量化指导机房设备扩容。前半部分是介绍背景,对CDN缓存模型做一些理论思考。后半部分会实际操作搭建一个微型但是五脏俱全的分布式通用系统架构,最后赋予该系统一些跟背景相关的功能,解决成本优化中遇到的实际问题。

缓存服务器存储模型架构(背景):

img图1 存储模型

腾讯CDN的线上路由是用户à分布于各地区各运营商的OC->SOC->SMid->源站。各个层级节点部署的都是缓存服务器。来自用户的部分请求流量命中服务器,另一部分产生回源流量。

随着业务带宽自然增长,用户端带宽增长,假设业务回源率不变的情况下,磁盘缓存淘汰更新(淘汰)速率变快,表现为以下业务瓶颈(iowait变高、回源带宽变高,由于磁盘空间大小受限的缓存淘汰导致回源率变高)。

为了说明这个原理。我们假设两个极端:一个是设备磁盘容量无限大,业务过来的流量缓存只受源站缓存规则受限。只要缓存没过期,磁盘可以无限缓存,回源流量只需要首次访问的流量,所以这个回源量(率)只跟业务特性(重复率)有关系。另一个极端是磁盘极限小(归零),那么无论业务设置缓存是否过期,客户端访问量都是1比1的回源量。假设业务平均的缓存周期是1个小时。那么这1个小时的首次缓存带宽(同一cache key的多次访问,我们认为是一次)将是这个硬盘的所需要的空间。这个大小是合理的,可以保证磁盘足够容纳业务的量。假设这个量达不到,或者本来达到了,但是由于业务自然增长了,1个小时内地首次缓存带宽变多,硬盘空间也不够用。

设备扩容是个解决办法。但是压测系统在这之前,没有客观数据证明需要扩容多大设备。或者扩容多少设备没有进行灰度验证,设备到位拍脑袋直接线上部署机器。我们在实验机器进行线上日志的重放,模拟出存储模拟曲线,来指导线上机房合理的设备存储。这就是建设重放日志系统的意义。

麻雀虽小,五脏俱全的重放日志模型(总览)

这一章,我们定义了下列模块:

模拟日志服务器:下载线上某个机房的一段时间周期的访问日志。一个日志存放10分钟访问记录。机房有几台机器就下载几份日志。日志服务器同时提供任务分片信息的查询服务。假设我们需要重放任务id为pig_120t的任务切片。下图既为任务切片详情。

img图2 日志服务器的日志分片文件

任务控制器:启动任务或者结束任务总开关。任务分配均匀分配给具体的肉鸡和代理服务器。插入任务到Task Pool中,收集服务端的实时总流量、回源流量、总请求次数和回源次数数据并插入到回源率结果数据表。

肉鸡:轮询Task Pool的任务表。如果有任务,则按照任务明细(时间、线上机房ip)向日志服务器请求下载该分片的日志。重放请求到指定的代理服务器。

代理服务端:提供实时回源数据查询服务。并且安装nws缓存服务器等组件,该机器等同于线上机房的软件模块。

实时展示界面:可随时查看实时回源率和一些任务异常状态信息。

图3为客户端和服务端的互动图。图4是任务控制端在任务进行中和其他模块的联动过程。

img图3 肉鸡和代理服务端的架构

img图4 控制端的任务联动过程

分布式系统特点

日志重放模型核心是一个高性能压测系统,但是需要添加一些逻辑:日志下载、日志分析重构、结果数据收集、数据上报展示。分布式系统核心是:是否做到了可拓展、可恢复、简易搭建、容错、自动化。以下内容会一一展开。

先说说高性能:在一个通用模型中。我们模拟线上日志,这个系统要做到高效、因为我们的重放日志速度要比线上的qps还要快。机器的重放速度决定了分析结果的速度。同时更快的速度,所需要的肉鸡资源更少。笔者在python各个url请求库和golang中,最终敲定使用了golang实现肉鸡。golang做到了和原生c+epoll一样快的速度,但是代码实现容易多了。理论上我们对一台做过代理端性能瓶颈分析。线上日志比模拟日志更复杂,qps适度下降是必然的。Golang这个客户端达到预期目标。

可扩展:在我们可能会随时增加模拟机器集群的肉鸡数量,或者更多的闲置代理服务器资源加入压测任务。所以系统在可用机器数据表随时加入新的机器。

img图5 系统的动态可扩展

可恢复:分布式系统不同于单机模式。不能避免可能有各种故障,有时候系统部分节点出错了,我们更倾向于不用这个节点,而不是继续使用未处理完成的结果。即非0即1,无中间状态。还有分布式系统网络传输延迟不可控。所以压测系统设计了一套容错机制:包括心跳检测失败,自动在数据表剔除肉鸡服务端。接口异常容错。超时过期未完成任务去除。crontab定时拉取退出进程等。

简易搭建:使用ajs接口,和批处理安装脚本。自动化部署肉鸡和服务端。配置dns解析ip(日志服务器,任务池、回源率结果所在的数据库ip),tcp time_wait状态的复用,千万别忘了还有一些系统限制放开(放开ulimit fd limit,这里设置100000,永久设置需要编辑/etc/security/limits.conf)。如果肉鸡有依赖程序运行库需要同时下载。在肉鸡机器下载肉鸡客户端和配置、在服务端机器下载服务端和配置,下载定时拉起程序脚本,并添加到crontab定时执行。以上都用批处理脚本自动执行。

一些设计范式的思考

Single-productor and Multi-consumer

在肉鸡客户端的设计中:读日志文件一行一条记录,添加到消息管道,然后多个执行worker从消息管道取url,执行模拟请求。消息管道传送的是一条待执行的日志url。IO消耗型程序指的是如果consumer执行访问日志并瞬间完成结果,但是productor需要对日志进行复杂的字符串处理(例如正则之类的),那么它下次取不到数据,就会被管道block住。另外一种是CPU消耗型程序,如果日志url已经预先处理好了,productor只是简单的copy数据给消息管道。而consumer访问url,经过不可预知的网络延迟。那么多个consumer(因为是包括网络访问时间,consumer个数设计超过cpu核数,比如2倍)同时访问,读端速度慢于写端数度。在对一个日志文件进行实验,我们发现处理18w条记录日志的时间是0.3s,而执行完这些url的访问任务则需要3分钟。那么很显然这是一个CPU消耗性进程。如果是IO消耗型的程序。Golang有种叫fan out的消息模型。我们可以这样设计:多个读端去读取多个chan list的chan,一个写端写一个chan。Fanout则将写端的chan,循环写到chan list的chan中。

Map-reduce

我们有时会做一个地理位置一个运营商的机房日志分析。一个机房包含数台机器ip。合理的调度多个肉鸡客户端并行访问日志,可以更快速得到合并回源率数据。

并行机制,经典的map-reduce,日志文件按机房机器ip纬度切片分发任务,启动N个肉鸡同时并行访问,等最后一台肉鸡完成任务时,归并各个肉鸡数据按成功请求数量、成功请求流量、失败请求数量、失败请求流量等方式做统计。同时用于和线上日志做校样。这里的mapper就是肉鸡,产生的数据表,我们按照关注的类型去提取就是reducer。

简化的map-reducer(不基于分布式文件系统),map和reduce中间的数据传递用数据表实现。每个mapper产生的日志数据先放在本地,然后再上报给数据表。但是数据表大小的限制,我们只能上传头部访问url。所以如果用这个办法实现,数据是不完整的,或者不完全正确的数据。因为也许两台肉鸡合并的头部数据正好就包括了某肉鸡未上传的日志(该日志因为没有到达单机肉鸡访问量top的标准)。

那么如何解决这个问题呢,根本原因在于汇总数据所在的文件系统是本地的,不是分布式的(hadoop的hdfs大概就是基于这种需求发明的把)。如果是状态码纬度,这种思路是没问题的,因为http状态码总量就那么少。那么如果是url纬度,比如说某机房给单肉鸡的单次任务在10分钟的url总数据量达到18万条。只看日志重复数>100的肉鸡数据。这样误差最大值是100*肉鸡数,所以对于10台肉鸡的机房,只要是综合合并结果>1000。都是可信任的。如果是域名纬度,少数头部客户流量占比大多数带宽。 这也就是所谓的hot-key,少数的hot-key占据了大多数比例的流量。所以域名纬度时,这个时候可以把关注点缩放在指定域名的url列表。如果本地上报给数据表的数据量太大,url也可以考虑进行短地址压缩。当然如果不想弯道超车的话,需要硬解决这个问题,那可能得需要hdfs这种分布式文件系统。

Stream-Processing

我们进行日志客户端系统,需要向日志服务器下载此次任务所需要的日志(一般是一个机器10分钟的访问日志)。首先本地日志会去任务服务器查询重放任务。接着去日志服务器下载。如果该模拟集群是在DC网络组建,那么下载一个10分钟(约150M左右的文件)日志几乎在1两秒内搞定,但是如果这个分布式系统是组建于OC网络,那么OC网络的肉鸡服务器要去DC(考虑机房可靠性,日志服务器架设在DC网络)下载,经过nat转化内网到外网,下载则需要10s左右。如果为了等待日志服务器下载完,也是一笔时间开销。

在分布式系统中,所谓的stream-processing,和batch processing不同的是,数据是无边界的。你不知道什么时候日志下载完。而batch processing的前后流程关系,好比生产流水线的工序,前一道完成,后一道才开始,对于后一道是完全知道前一道的输出结果有多少。

所谓的流式处理则需要在前一道部分输出结果到达时,启动后一道工序,前一道工序继续输出,后一道则需要做出处理事件响应。后一道需要频繁调度程序。

消息系统(message broker):前一道的部分输出,输入给消息系统。消息系统检测到是完整的一条日志,则可以产生后一道工序的输入。这里我们会碰到一个问题。下载日志的速度(10s)会远远快于执行重放这些日志的速度(3min)。按照一个消息系统可能的动作是:无buffer则丢弃,按照队列缓存住,执行流控同步后一道工序和前一道工序的匹配速度。这里我们选择了按照队列缓存住这个方案。当然在一个严谨的分布式数据库设计,message broker是一个能考率到数据丢失的节点。Broker会把完整数据发给后道工序,同时会把buffer数据缓存到硬盘备份,以防程序core dump。如果对于慢速前道工序,可以进行综合方案配置,丢弃或者流控。这里消息broker不同于数据库,他的中间未处理数据是暂时存储,处理过的消息要清除存储。

总结

当然:现实中的生产线的分布式系统会远比这个复杂,但是本文实现的从0到1的迷你麻雀分布式系统有一定的实践意义。它不是一蹴而就的,不断地版本迭代。当然该系统也完成了作者的kpi-存储模型分析,在中途遇到问题时,进行的设计思考和改良,在此总结分享给大家。

问答
文字识别在格式上有什么要求?
相关阅读
原来你是这样的http2
我是怎么一步步用go找出压测性能瓶颈
HTTP/2之服务器推送(Server Push)最佳实践
【每日课程推荐】机器学习实战!快速入门在线广告业务及CTR相应知识

此文已由作者授权腾讯云+社区发布,更多原文请点击

搜索关注公众号「云加社区」,第一时间获取技术干货,关注后回复1024 送你一份技术课程大礼包!

海量技术实践经验,尽在云加社区

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何设计一个麻雀般的微型分布式架构? 的相关文章

  • Unity-后期处理效果之Bloom

    Unity 后期处理效果之Bloom 什么是Bloom Bloom属性 什么是Bloom Bloom是一种游戏常见的一种屏幕效果叫做高光溢出 是一种光学效果 其中来自明亮来源 如闪光 的光表现为泄露到周围对象中 通俗来说就是这种特效可以模拟
  • Visual Studio Code 插件

    Visual Studio Code 插件安装 插件安装 Script插件 Vue插件 插件安装 首页点击 工具和语言 如下图 接下来 在输入框中输入想要安装的插件的名字 点击 install 即可进行安装 Script插件 1 Eslin

随机推荐

  • C++中cout和cerr的区别?

    之前一直在用 但就是没在意两者到底有啥却别 今天又想到这个问题 总结下吧 以下的内容均是本人从网上查阅资料看来整理的 暂时还没有查阅官方资料 不保证准确 欢迎讨论 其实大家平常常会用的主要有三个 cout cerr clog 首先简单介绍下
  • http协议的状态码:404等常见网页错误代码

    http协议的状态码 一 1xx 临时响应 表示临时响应并需要请求者继续执行操作的状态码 100 继续 请求者应当继续提出请求 服务器返回此代码表示已收到请求的第一部分 正在等待其余部分 101 切换协议 请求者已要求服务器切换协议 服务器
  • 滴滴夜莺:从监控告警系统向运维平台演化

    简述 滴滴夜莺 Nightingale 是一款经过大规模生产环境验证的 分布式高性能的运维监控系统 基于Open Falcon 结合滴滴内部的最佳实践 在性能 可维护性 易用性方面做了大量的改进 支撑了滴滴内部数十亿监控指标 覆盖了从系统
  • 惊呆了!女儿拿着小天才电话手表,问我Android启动流程!

    首先 new一个女儿 var mDdaughter new 女儿 6岁 漂亮可爱 健康乖巧 最喜欢玩小天才电话手表和她的爸爸 好了 女儿有了 有一天 女儿问我 爸爸爸爸 你说我玩的这个小天才电话手表怎么这么厉害 随便点一下这个小图片 这个应
  • Manifest合并失败几种原因以及解决方法

    今天遇到了一个报错 Error Execution failed for task app processDebugManifest gt Manifest merger failed with multiple errors see lo
  • c语言合并两个单链表LA和LB,把两个递增的单链表La,Lb,合并成一个递减的单链表Lc...

    原文题是严蔚敏同志的数据结构习题中第二章线性表中提出的问题 原问如下 2 24 假设有两个按元素值递增有序排列的线性表A和B 均以单链表作存储结构 请编写算法将A表与B表归并成一个按元素值递减有序 即非递增有序 允许表中含有值相同的元表 排
  • 基于Vue + vuex + Antd-design-vue实现天气App

    simple weather github 地址 github com WqhForGitHu 效果图 PC端 移动设备端 技术框架 该应用是基于 Vue vuex 实现的 页面的 UI 则是使用了 Antd design vue 库来完成
  • Android 版本统一管理

    前言 因为现在项目都比较模块化 组件化 要用到的model比较多 一个model就有一个build gradle文件 里面都有compileSdkVersion或buildToolsVersion等可能出现版本不一致导致编译出现错误 所以要
  • thinkphp5学习路程 三 数据库操作

    首先我用的是php中文网提供的php工具箱 phpmyadmin管理mysql 在此之前最好对sql语句有所了解 会简单的增删改查等 在里面创建数据库和一张表如下 随后你需要打开数据库的配置文件 目录为 application databa
  • Python OpenCV中的图像阈值处理

    1 前言 上一篇介绍了用C 如何对一幅图像进行阈值处理 本篇接着用python来做同样的事情 图像阈值处理是很多高级算法的底层逻辑之一 比如在做图形检测 轮廓识别时 常常会先对图像进行阈值处理 然后再进行具体的检测或识别 因此很有必要掌握图
  • 指针作函数返回值

    include
  • 指向数组的引用 const char(&p)[a]

    指向数组的引用 const char p a 问题起源 如何在函数内 也能获取数组的大小信息 如果是定义一个数组a后 使用如下方法即可获取大小信息 cout lt lt sizeof a sizeof a 0 但是如果作为一个参数传入到一个
  • 最新酒桌小游戏喝酒小程序源码_带流量主源码下载

    2022最新酒桌小游戏喝酒小程序源码 带流量主 喝酒神器3 6 我修改增加了广告位 根据文档直接替换即可 原版本没有广告位 直接上传源码到开发者端即可 通过后改广告代码 然后关闭广告展示提交 通过后打开即可 下载地址 最新酒桌小游戏喝酒小程
  • 在linux系统下安装配置apache服务器

    我所用的是centos linux系统 但apache的服务在linux系统都大同小异 像ubuntu redhat等等 now let us go 如有问题 欢迎直邮 zhe jiang he hp com lt 何哲江 gt 1 获取软
  • Edge浏览器没有让我失望! 今天终于可以在win10中模拟IE内核进行前端测试了!

    前言 ietest现在是不是不好用了 Edge浏览器仿真是不是不见了 如图 如果我们在前端开发javascript遇见一些老旧的语法标准 想要测试一下都难 想想都抓狂 不过不用担心 经过这几天的资料查阅 我还是找到了一个解决办法来模拟旧版I
  • Set集合中的SortedSet接口下的实现类TreeSet

    放入TreeSet集合中的元素必须实现Comparable接口 不然会报错 因为这个集合中的元素会自动按元素的大小顺序排序 所以不是实现比较的接口就会出现ClassCastException 还要注意一点的是Set集合中的元素是不可重读的
  • ctfshow web入门刷题3

    web15 看提示找到邮箱 然后尝试登入后台 url admin 尝试点击忘记密码然后提示输入城市 尝试用qq搜索qq号 发现城市为西安 得到后台密码 登入得到flag WEB16 题目提示php探针 所以url tz php打开探针然后搜
  • 当你穿越到道诡异仙的世界,如何利用密码学知识区分幻想和现实?

    题解 牛群的能量 题目考察的知识点动态规划题目解答方法的文字分析用 f i 代表以第 i个数结尾的 和最大子群能量值之和 设数组的长度为n 则本题的答案时从0到n 1这n个f 题解 牛牛的名字游戏 题目考察的知识点字符串题目解答方法的文字分
  • TensorFlow在MNIST中的应用-循环神经网络RNN

    参考 1 TensorFlow技术解析与实战 2 https www cnblogs com hellcat p 7401706 html 3 http www jianshu com p 3dbeb3ab9aa3 用TensorFlow搭
  • 如何设计一个麻雀般的微型分布式架构?

    欢迎大家前往腾讯云 社区 获取更多腾讯海量技术实践干货哦 本文由mariolu 发表于云 社区专栏 序言 初衷 设计该系统初衷是基于描绘业务 或机器集群 存储模型 分析代理缓存服务器磁盘存储与回源率的关系 系统意义是在腾讯云成本优化过程中