热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

TOP100summit:【分享实录】爆炸式增长的斗鱼架构平台的演进

本篇文章内容来自2016年TOP100summit斗鱼数据平台部总监吴瑞城的案例分享。编辑:Cynthia吴瑞诚:斗鱼数据平台部总监曾先后就职于淘宝、一号店。从0到1搭建公司大数据

本篇文章内容来自2016年TOP100summit斗鱼数据平台部总监吴瑞城案例分享。

编辑:Cynthia


吴瑞诚斗鱼数据平台部总监

曾先后就职于淘宝、一号店。

0到1搭建公司大数据平台、平台规划和团队建设。

目前负责斗鱼实时/离线数据处理、个性推荐系统、BI&DW和搜索引擎。

背靠开源生态,应用短平快的方式,支撑起一个亿级用户的在线直播平台。

致力于数据平台产品化、智能化、云化。

对高可用高并发的大数据平台架构和SOA架构有深入的理解和实践。

导读:2016年是直播行业的元年,斗鱼在两年内发展成为拥有亿级用户和百万级主播的直播平台,快速增长的同时也为技术带来了高并发请求和海量数据的挑战。同时公司系统技术栈多、项目迭代周期快、系统规模呈爆炸式增长。在这种背景下,斗鱼网站的架构平台该如何进行优化,才能支撑起如此迅猛的业务发展?斗鱼的平台技术会在哪些方面持续革新?

本文详解斗鱼技术团队通过对斗鱼基础架构平台的不断改造与优化,形成当前能支撑千万级用户同时在线观看的架构平台。适用于希望了解直播平台基础架构、单体应用的服务化改造、直播平台在支撑大型赛事活动所做的准备。

一、问题的提出

 

斗鱼网站2014年上线至今,顺应直播行业趋势的发展,完成对交易系统、会员系统、统一登录系统、弹幕系统、任务系统的重构,并持续对架构进行优化,针对客户使用体验拆分系统、提高研发效率、强化系统稳定性和扩展性。优化主要针对以下三个方向:

● 偿还技术债--多语言技术栈交互,临时方案导致版本过多、逻辑错综复杂;

● 系统可扩展性--服务与服务、服务与资源之间解耦;

● 服务化--微服务、服务治理、容器化。

 

二、实践过程

2.1 斗鱼架构平台整体介绍

2015年初,斗鱼网站系统架构主要分为两大功能模块:Web站和移动端,这两大模块最初是从网站的单个工程中拆分出来的,是一个典型意义上的单体应用,也就是Martin Fowler指的monolithic application,这样的系统主要有以下问题:

● 各个业务模块错综复杂,代码复用率低,临时方案和功能开关多,导致代码可维护性较差;

● 功能开发效率较低,容易踩坑,容易伤士气;

● 网站健壮性较差。

 

斗鱼去年(2015年)系统架构如图1所示:

技术分享

图1:斗鱼2015年系统架构

这个阶段的系统会存在诸多瓶颈,随着网站用户量的激增,斗鱼全站的DAU超过2000万,整体架构的服务化改造刻不容缓。

在原应用层中,剥离业务逻辑,只负责应用的流量接入,具体的业务逻辑将由服务层承担;在服务层中,按照业务功能,完成会员系统、房间系统、交易系统、个性推荐服务、弹幕系统、礼物系统等多个功能单元服务改造。

这样就形成了当前的系统架构(图2):

技术分享

图二:斗鱼当前(2016.12)系统架构

 

在大型活动赛事时,每个功能单元的逻辑复杂度、承担的访问量差别巨大,为了能扛住活动期间的峰值,需要对各个功能单元进行容量预估和扩容,这样会直接验证服务化改造的效果。

2.2 斗鱼配置中心

整个服务化进程中,会需要多个核心的基础组件,先介绍一个核心组件——我们最先启动的配置中心。

在没有配置中心时的状态是这样:

● 配置散落在各工程中,盘根错节,配置改动成本大;

● Dev、Test、Stg、Prod多套配置;

● 资源环境安全隐患;

● 无法进行服务降级。

梳理出配置中心的痛点,列出配置中心的基本目标是:

● 统一维护配置,方便新增及更改配置;

● 多套环境配置隔离。

围绕这个目标,通过两个版本的迭代,实现了以下特性:

● 动态配置  ——自动拉取、手动更新、对象动态重构

● 高可用——MySQL主从、本地加密Snapshot

● 数据源——MySQL、Redis、MongoDB等

● 集群配置——Kafka、HBase、Zookeeper、ES等

● 配置项可继承

此外,对于中小公司,安全隐患不容乐观,所以出于安全策略的考量,还实现了:

● 配置中心秘钥安全认证

● 配置服务添加IP白名单

● 配置服务访问频率

在设计阶段,针对已开源的Diamond(淘宝)和Disconf(百度),主要从配置存储、推拉模型、配置读写、容灾模式、安全性、配置、数据模型、集群数据同步方面做了详细对比,对比发现两套开源系统涉及技术栈较多、二次开发成本较大,与现有系统集成的风险较大。

加之,配置中心并不复杂,风险可控,并且自研的优势还有人员培养,自身对系统全貌能做到足够熟悉,后续新增功能特性和日常维护比较得心应手。事实证明,自研的选择完全符合设计阶段的预期。

配置中心架构如3:

技术分享

图3:配置中心系统架构

整个配置中心主要分为四大部分:

● 配置中心UI:配置项内容维护、配置项权限管理、配置项逻辑关系(继承);

● 服务层:配置服务接口、安全认证、配置项持久化;

● 存储层:配置内存通过MySQL主从存储,中间有通过Redis实现缓存;

● 客户端:应用本地保存配置snapshot加密文件,提升安全性和可用性,通过配置项MD5比对判断是否更新,拉取配置后动态更新本地对象实例。

在应用代码中,只需以下代码即可集成配置中心:

PropertiesConfigClient configClient = new 

PropertiesConfigClient(

live/prod,    //配置组

project,      //配置所属工程

config-file,  //配置文件

refresh-interval); //更新频率
 configClient.getRequiredInt("data.query.page.size");//需使用配置项

当前,配置中心迭代中的版本主要是抽象资源类型,这样可以通过配置中心识别出服务依赖的资源,包括接口、缓存、存储等,并在此基础上做服务依赖的全监控。

对于配置项修改后的实时推送特性,拉取模式现阶段够用,暂时还没有改造需求。如果需要新增,可以集成Zookeeper,通过Zookeeper的事件推送机制,并配合改造配置中心客户端的接收模式即可实现。

2.3 斗鱼统一日志监控系统

有了配置中心,可以以此实现服务的开关和降级。但是在赛事活动期间,除了配置中心,还需要监控系统来识别系统状态。

为什么需要做统一日志监控系统?初衷包括:

● 技术语言多样、临时方案导致版本过多、逻辑错综复杂;

● 服务层级不多,但是量大,接口失败后如何快速定位;

● 开源组件二次开发能力弱;

● 需要短平快的实现方式。

梳理出了最关心的监控指标,主要包括:

● 接口访问量监控

● HTTP 500监控

● 接口响应时间监控

● 视频流监控

● 系统错误日志监控

● 资源层监控

● 服务器性能监控

梳理过程中,我们发现:

● 接口访问量监控、HTTP 500监控、接口响应时间监控、视频流监控可以通过Nginx或者Web Server的log取到;

● 系统错误日志监控能通过应用日志取到;

● 资源层监控和服务器性能监控可以通过Zabbix监控实现。

方案设计阶段,主要对比了以下两个方案:

● 日志分段处理方案:在日志本地按时间区间分段切分日志文件,通过rsync将分段日志汇总,解析并做聚合计算,结果导入MySQL或者Redis,日志内容导入HBase,供查询定位。

● ELK(Elastic Search+Logstash+Kibana)方案:通过Logstash(日志收集Agent)tail抽取方式收集日志,写到ES(Elastic Search,以下简称ES)集群,然后通过Kibana来查询日志。

参与方案设计的同事倾向日志分段处理方案,主要是对各个组件都较熟悉,每一步都可控。但是考虑到实时性得不到保证,并且开发成本高,所以决定搭测试环境小范围试用,最后发现ELK绝对神器。

当前监控系统架构图如4:

技术分享

图4:监控系统架构图

从架构图中可以看到关于统一日志监控系统相关的数据流,对于CPU敏感的日志宿主机,使用Rsyslog作为Agent来实现日志收集。并且,在Agent中精简任务,只做最简单的日志抽取。快速写入到Kafka集群中。日志数据从Kafka出来后有两路去向:一路是经由日志内容解析,按照ES的index mapping解析日志,然后写入ES集群;一路经过实时计算系统(基于Storm实现),做聚合计算,得到指定粒度Metric的值,同样写入ES,需要在Dashboard中展示的指标会写入Redis。

基于ELK,通过在基础中间件中改造AOP日志的格式,还实现了满足基本功能的全调用链监控,具体的AOP日志格式如5:

 

技术分享

5 AOP日志格式

这套日志格式主要是参考Google 的Dapper论文,关键是trace_id(全局唯一的方法调用ID,通常特定规则生成的UUID)和span_id(方法调用的层级ID),通过这两个ID串联起整个RPC调用链。在日志中记录RPC相关的所有方法调用信息,包括服务名;方法开始时间和结束时间,用以计算方法耗时;方便定位服务进程的host、pid和服务端口;定位问题时需要的入参。没有记录出参的主要原因是出参过大,并且通过入参中的业务字段,能定位是在哪一级出的问题,现阶段够用。

关于ELK的一些使用经验主要有:

● ELK vs. TSDB

日志系统最初Metric存储是使用的基于OpenTSDB实现的一套存储展现系统,后来在OpenTSDB的使用中碰到一些问题,例如HBase资源冲突、数据压缩、区间查询精度等问题,另一方面ES的使用足够省心,后来Metric存储也逐渐以ES为主。

● 日志内容的解析

最开始是在Agent中实现,tail抽取后逐条解析,这样会大大降低日志的抽取效率。接入Kafka中间层后,改由使用Logstash从Kafka中读取并解析,Logstash内部存在CPU效率低的问题,再改用Hangout(携程开源的Java版Logstash,主要是因为Logstash的CPU效率较低)。当前发现吞吐量仍然不理想,正在改用原生Java多线程和Spark Streaming两种方式来完成日志解析。

● Elastic Search日志集群使用

斗鱼现有6个ES集群、120个实例,物理机配置32C/128G/6T*12,日均日志量约10T,使用CMS的GC策略;堆大小使用官方推荐的32G,适当增加-Xmn大小;对于大物理机采用3实例同机部署;为提升写入吞吐量,读写分离(配置ES截取呢拓扑);尽量设置成不分词,即设置成not_analyzed;设置合理refresh时间间隔,index_refresh_interval;多集群通过搭建Proxy层来实现统一入口和权限控制。

2.4 大型赛事活动的运维保障

每次大型赛事活动的运维保障,就是一次平台架构的大考。斗鱼是怎样做赛事运维保障的呢?

首先,识别出最核心的服务。换言之就是要挑出那些不接受不可用的核心功能,主要包括:

● 直播视频——斗鱼内容输出的最核心功能;

● 直播间列表——进入直播视频的关键入口;

● 超管功能——保障内容监管的有效执行;

● 弹幕服务——其他行业不常见,但是是直播中主要互动形式。本质是消息推动,但不同点是需要将用户发布的弹幕内容广播给当前同一直播间的所有观众,量级放大N级,需要将流量分发,减轻机房网络带宽压力;

● 交易——这个无需解释。

其次,针对各个核心功能进行容量评估,评估出需要预留的资源规模,主要包括:

● CDN——下文会单独列出;

● 缓存——业务功能依赖的各级缓存,包括Nginx缓存、OpenResty的ngx.share.DICT、Redis/Memcached、进程内缓存,尽可能兜住用户请求,不穿透到MySQL;

● 资源隔离——尽量从物理上隔离;

● 降级——主要是各类开关,基于配置中心的网关开关、Web Server开关、接口开关、缓存开关等;

● 监控——监控赛事期间线上全站和赛事直播间的水位状态;

● 机房——机房网络状态、主从灾备机房网络状态;

● HTTPS——直播行业第一家实现全站HTTPS,保证终端用户体验。

第三,CDN是保障的关键支撑,主要包括静态文件CDN和视频流CDN,视频流是本文讨论的主要内容。主要包括以下准备内容:

● 接入多家CDN厂商,通过统一入口调度,可以针对不同网络状况实现流量切换;

● 需要预备多条推拉流线路,保障主播推流和用户拉流可用;

● 建立CDN-SLA,建立包括视频卡顿率、首屏时间、视频延迟等监控指标的CDN质量评估体系;

● CDN厂商同步所有赛事信息,开通赛事热线,做好相应值班安排。

 

三、效果评价和总结

 

● 经过一年多架构改造,斗鱼拥有能支撑起千万级用户同时在线观看的能力;

● ELK的版本更新快,需要及时跟进官方大版本,并根据业务特点,不断进行优化和调整。随着熟悉程度的不断加深,会考虑更多的二次开发方案,提升日志系统的整体吞吐能力和性能;

● 持续跟进开源社区优秀组件的发展,例如Flink、Spark Streaming、Elastic Stack等,因地制宜引入合适技术框架提升系统承载能力;

● 现阶段系统服务化的能力仍不健全,在服务治理、服务容量预估、服务扩容方向还有很长的路要走,服务化会持续推进,朝着控制技术债雪球、提升系统可扩展性、系统服务化的方向,持续发力。

更多TOP100案例信息及日程请前往[官网]查阅。包含产品、团队、架构、运维、大数据、人工智能等多个技术专场,4天时间集中分享2017年最值得学习的100个研发案例实践。本平台共送出10张开幕式单天免费体验票,数量有限,先到先得

TOP100summit:【分享实录】爆炸式增长的斗鱼架构平台的演进


推荐阅读
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 单点登录原理及实现方案详解
    本文详细介绍了单点登录的原理及实现方案,其中包括共享Session的方式,以及基于Redis的Session共享方案。同时,还分享了作者在应用环境中所遇到的问题和经验,希望对读者有所帮助。 ... [详细]
  • 2018年人工智能大数据的爆发,学Java还是Python?
    本文介绍了2018年人工智能大数据的爆发以及学习Java和Python的相关知识。在人工智能和大数据时代,Java和Python这两门编程语言都很优秀且火爆。选择学习哪门语言要根据个人兴趣爱好来决定。Python是一门拥有简洁语法的高级编程语言,容易上手。其特色之一是强制使用空白符作为语句缩进,使得新手可以快速上手。目前,Python在人工智能领域有着广泛的应用。如果对Java、Python或大数据感兴趣,欢迎加入qq群458345782。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 解决VS写C#项目导入MySQL数据源报错“You have a usable connection already”问题的正确方法
    本文介绍了在VS写C#项目导入MySQL数据源时出现报错“You have a usable connection already”的问题,并给出了正确的解决方法。详细描述了问题的出现情况和报错信息,并提供了解决该问题的步骤和注意事项。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • 本文介绍了Java的集合及其实现类,包括数据结构、抽象类和具体实现类的关系,详细介绍了List接口及其实现类ArrayList的基本操作和特点。文章通过提供相关参考文档和链接,帮助读者更好地理解和使用Java的集合类。 ... [详细]
  • 众筹商城与传统商城的区别及php众筹网站的程序源码
    本文介绍了众筹商城与传统商城的区别,包括所售产品和玩法不同以及运营方式不同。同时还提到了php众筹网站的程序源码和方维众筹的安装和环境问题。 ... [详细]
author-avatar
奶油。
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有