到春节,新工作就完整四个月了,磨合的也差不多了,情况也了解的差不多了,需要做计划了,当然不是为了计划而计划,也不是为了产品数据而计划,而是从一个程序员的角度去考虑。
面临的复杂性在于,自己的水平和认知还处于一个可提升的阶段,很多考虑不全面,但正因为如此,才要去想,虽然过程很痛苦。
计划应该是务实的,可实践的,否则就是自欺欺人的。如果不去做计划,后面遇到问题的时候就会手足无措,然后会发现每个月都在“思考”,会非常的焦虑,理论上应该多点时间去搞实践,过度的思考其实也不是好事。
做计划很难,产品数据目标当然是参考的一个方面,但不管数据是多少,稳定性、性能这些技术指标必须去考虑,因为这是工作职责,也很开心有这样一个机会去实践,唯一忐忑的就是这几年有点荒废了(写书和英语水平提升除外),对新技术了解的不多,所以要抓紧时间去补充。
下面从多个角度去阐述我的想法,本周看了一些专栏和书籍,不可能完全消化,但希望80%的方向是对的。
容量规划和性能、可用性、架构都有关系,容量由性能指标、数据指标、峰值指标等决定,但容量和性能不是一码事,容量规划评估基础设施规模是基于当前架构、性能;而性能是基于目前的架构进行调优。
容量规划的重要性在于让你从另外一个角度了解系统,容量规划的前提是测量,有的时候领导说DAU要上涨十倍,系统能支撑吗?这其实就是容量规划的问题,需要评估出单机的峰值支撑能力、数据库的峰值qps、数据库的存储容量增长率。
容量规划的难点在于环境是快速变化的,比如优化了一条简单的sql查询,数据库支撑能力可能就提升了好多,那么此时此刻的容量规划没有太大的意义,所以说容量规划也需要结合经验、统计、分析、预测等多个环节。
容量规划也是和成本有关的,你要申请机器,就要用数据说服别人,而不能一句“dau上涨了好多,需要扩容”,这样很难让人信服,同时基础设施成本规模要是能减少20%,那说明工作做的不错,虽然别人无法意识到,有的时候想想一个月的短信费用都抵得上一台ECS一年的费用了。
落实到具体,今年的工作要长期统计MySQL、MongoDB、Elasticsearch、Redis这四大存储系统的规模,比如说MySQL单盘容量已经快满了,怎么办?是不是要提前准备?
另外就是评估这四大存储系统的qps支撑能力,尤其要模拟出峰值支撑能力,在此基础上考虑架构是否要优化、是否要扩充存储。
对于web应用,主要是php-fpm,目前看受限于程序应用逻辑,单机并发数不大,今年希望找一些工具模拟真实的请求,如果横向扩展达到瓶颈了,需要考虑别的解决方案。
从成本上来说,七牛的CDN费用占大头,这是今年需要重点考虑的,一方面是策略问题,另外一方面也是规则问题,最重要的是视频和图片编码、压缩问题,有一定的复杂度。
容量规划每个月应该有个报表,及早预警,及早发现问题。
架构分系统架构和应用架构。
从系统架构的角度看,我们目前服务很简单,这个在以前周记说的很多了,其实就是通过阿里云的SLB支持同区域多可用区级别的横向扩展和故障转移,因为公司域名要变更,所以SLB的部署暂时还没有上线,这是过年后非常重要的一个推进工作,具体包括,web服务器的安装部署测试(软件使用什么版本,需要什么软件和配置);域名的梳理(已经基本做完);SLB七层的配置;七牛云CDN地址的切换(目前看是最麻烦的,因为程序很多地方写死了,需要可配置化)。
QA、开发环境和线上环境的剥离,这个在昨天文章中也提到了,我个人有个习惯,喜欢在Linxu终端干活,其实挺危险的。
系统结构虽然简单,但不代表无效,从目前的规模、能力,我觉得完全没有必要看Docker这样的技术,至少优先级不高。
架构本质上就是负载均衡、横向扩展,对于web集群很好实施,记住几个原则,一台新的web服务器多久能够生效,配置如何快速同步到各台web服务器,web服务器如何做到无状态以及保持一致性,说上去很简单,其实实际操作也不容易,比如一台机器挂了,这台机器上的cron是否由其他服务器接管,所以这一块还有很多可学的。
对于负载均衡,充分利用SLB,但其实Nginx的七层和四层更加灵活,所以以后针对一些特殊应用(比如聊天)可能也要单独部署,上周也提到了Nginx的强大之处,今年要好好琢磨琢磨,成为一个善于应用Nginx的开发者,目前想到Nginx+Lua作为高性能接口、WebSocket代理、Nginx Cache、Nginx限流、各种七层规则应用。
从运维的角度看,Nginx的升级、PHP的升级可能也是今年的重点,现在有很好的机会学习运维知识,我可能比运维更懂开发,比开发更懂运维。
除了Web集群,接下去就是存储集群了,也就是MySql、MongoDB、Elasticsearch、Redis,Redis是部署在阿里云的,假设不用考虑它的运维问题,其他三个都是在ECS单独安装和维护的,为什么不部署在阿里云?最重要的是成本,另外托管了不代表就万事大全了,必须了解它,如果一切顺利,希望明年能够将MySQL托管。关于这四大存储系统,后面再说。
从系统架构上考虑,有的时候觉得设计方案就是完美的,但真有一台服务器挂了,或者存储挂了,系统能够做到无缝迁移?今年希望通过实际的演练验证部署是没有问题的。
应用架构其实比系统架构复杂,需要了解业务、理解业务、超越业务,而且有历史积累的问题,很难一步到位。
先说四大存储系统的使用,从 db-engines.com 上可以看到MySql、MongoDB、Elasticsearch、Redis这四大排名分别是2、5、7、8,所以选型它们没有太大的问题。
MySQL肯定是最熟悉的,但现在的应用模型越来越复杂了,如果纯粹靠MySQL来支撑,目前看是不现实了,所以今年一定要多使用其他三种存储软件,当然稳健原则是前提,比如说有托底的MySQL解决方案。
MongoDB生态相对小一点,所以说更易使用,它的优势在于它的文档模型非常灵活,schema 设计灵活,支持聚合查询(可以做很多数据分析运算),也支持索引,更关键的是通过shard和副本集支持大容量的数据存储和负载均衡。
Redis已经托管在阿里云了,它的数据模型简化了开发工作复杂度,而且性能还非常高,真的是利器,缓存、队列、存储都可以使用,如果数据量不大,可以使用它,如果数据量大,则使用MongoDB,专门买了一本《Redis使用手册》,推荐大家读一读。
而 Elasticsearch 生态非常大,应用场景更大,最重要的当然是做搜索;其次可以做日志分析、性能分析,应用和系统产生的日志是否可以放进去?监控程序的运行情况?还可以进行大数据分析,比如聚合分析;内容相关性推荐(推荐算法?);beats和logstatsh作为数据同步工具,也有很多的应用场景;而kibana进行可视化学习,进行机器学习。
ELK全家桶生态有的时候会把人搞晕,现在新技术、新工具、新业务、新解决方案越来越多、同质的服务也层出不穷,合理的选择技术和应用技术也同样重要。
从开发语言上来说,主要使用PHP,框架是Yaf(其实只是一个骨架),客观上说代码的耦合度很高,很难拆解出来,关联性太大了,这其实是核心存在的问题,影响性能和后续的开发、维护,谁也不敢轻易动;Python也使用了一些,主要是来自于Github上的一些服务;在今年想着是否能使用一些Go,这是团队的一个小目标。
由于代码以PHP为主,代码规范、开发标准(如何使用队列、如何使用缓存、如何记录日志…)、文档化、先技术方案后编码,这种软实力,需要和大家一起学习,比如今天我看了一些PHP Awesome,很多可以借鉴,对于小团队来说,不是制约或者死标准,而是每个人共同提高,这是正确的方式,任何事情要考虑大家的情绪、主动性、换位思考、尊重。
PHP技术栈还有很多方面,比如基于Git的代码分发系统、异步框架(Swoole、Workerman)、日志系统、消息队列(php-resque)都需要去研究的,不能自造轮子,也造不过别人,希望以后每周我都能研究一个,遇到合适的,就用在业务上。
接下去说说业务,包括四大块:API、Admin、Service、H5,部署的代码目前是独立的,无法复用。
API是最重要的服务,存在的问题就是版本兼容太多了,春节以后很重要的事情就是删除老版本兼容代码;另外结构性不好,上面也提到了,耦合度太高,模块化做的不好,如何改造?还没想明白,放到后面再说。
Admin服务更不好,使用的代码库和API完全不兼容,而且为了满足各种需求,查询非常慢,这个一方面受限于MySQL,另外做了太多的产品运营需求,现在首要的是就是砍功能,对于技术人员来说,一个优秀的产品运营不仅会提需求,还要后续有跟踪,觉得没用了就要告之,这是对开发人员最大的尊重,也是换位思考。将来我们的代码异步化越来越多,解决方案越来越多,Admin代码如何复用代码库是非常大的一个考验;同时Admin开发人员应该是最了解业务的,要将服务流程串起来。
Service是我入职后,了解最多的,也初步有了一些模型,以前应用架构什么操作都在API同步完成,所见即所得,不会导致数据差异性问题,而使用了队列则可能会出现应用上的一些问题(所谓的延迟、数据一致性、队列丢失),换句话说Service上的代码更加的重要了。在今年,首先要画一张图,将所有的Service服务串联起来,做到心中有数;其次是选用一个好的消息队列处理框架(php-resque?自己研发?);然后针对队列任务需要有监控,有日志可排查可恢复、队列部署无状态化;队列代码编写标准化。
H5包括H5应用、小程序、APP内嵌页,因为各种问题,JS调用的接口目前无法直接调用API服务,所以只能由H5 PHP程序curl调用API接口(相当于代理),从性能角度和可维护角度看肯定非常不好。年前要想一想,核心就是不管是H5、APP内嵌页和API代码部署在一块(只是虚拟主机不一样);其次是只部署页面,没有接口调用;最后JS能够直接调用API接口。
这四大块非常关键,如何优化?
稳定性其实比性能和架构更重要,单机qps超过峰值了、数据库down了、代码bug了,出了问题及时解决还好,解决不了就更麻烦了,给人影响也非常不好,所以稳定性只能自己负责,同时也要坚持自己的原则,如果目前的技术方案不能解决产品需求,那么坚决不做,至少暂时不做。
从系统的角度看,对于Linux服务器、Nginx、PHP-FPM的监控目前已经有Zabbix支持了,但自己知道对于Zabbix的掌握仅仅可能只有10%,刚入职的时候想着还用下Prometheus,现在还是专注于Zabbix的使用,毕竟解决实际问题更重要。
对于MySQL的监控也有了,但具体的指标还要细化,接下去还会细说,后面也可以通过Zabbix监控其他的三大存储系统,甚至应用日志也可以纳入Zabbix的监控,各个方面做到及时和准确报警。
也要想一些解决方案,实施全链路的应用和系统监控检查、故障和Bug分析通道,这方面是否可以结合Elasticsearch全家桶解决?
不管是架构、容量规划、稳定性,都需要找一些工具,有了工具就事半功倍了。
思考几个问题,Web服务器集群某台机器down了影响什么?整个可用区集群down了影响什么?七牛down了影响什么?存储系统down了影响什么?遇到高峰了限流方案是什么?有人攻击了影响什么?安全策略足够安全吗?某个外部服务down了影响什么?
是否有迁移方案?紧急预案处理?是否影响核心服务?核心服务是什么?目前也只能有个大体框架,系统层面的还好说,应用层面的就更复杂了,也反映出全链路监控和日志系统的重要性了。
重点说下存储系统的稳定性,因为Web服务down了,扩容或者等待一段时间就好了,而数据被破坏了,则万劫不复。
MySQL是最重要的,官方文档已经看了15%了,非常的开心,体系也很庞大,过年后核心实施的就是扩容一个实例(安装服务、初始化数据库、权限配置、主从同步配置、参数配置);另外将QA的数据也迁移过来(定期整理表,让存储小一点);是否在单机再部署一个实例(还没考虑好)?数据库调优策略(包括Zabbix监控策略);数据库最大qps;主从倒挂;最核心的问题就是后面存储量大了,怎么扩容?可能还要停机;数据库备份和恢复策略;360 Atlas 数据库中间件的进一步研究。
Redis集群托管在阿里云,了解下它的运维机制就可以了,只能相信它,出问题带来的影响?太大了。
另外Mysql、Elasticsearch、MongoDB是部署在一起的,如何分开存储互不影响是需要考虑的。如果要使用Elasticsearch和MongdDB,对它们的运维和集群管理一定要了然于胸,这是今年我的重点。
存储系统的扩容、维护其实本质上差不多,重要的是实战,数据不丢失。
和容量规划一样,性能也要可度量,从更广的视角就是接口的响应时间,但还有更多的方面,现在缺乏度量工具,只是简单的日志分析。性能越好,Web服务器的并发能力就越大。存储系统使用的好,查询必然快,性能肯定也越好,都是相辅相成的。
从存储系统的角度看,就是不能依赖MySQL,需要其他的解决方案,重点要使用MongdDB和Redis。
从整个链路看,需要客户都和服务器端的配合,减轻服务器端的并发数,对于我来说,不懂Andriod和IOS开发,但要学会抓包,不然总得问人,关于这一块是重点要学习的。
虽然渲染优化是客户端重点考虑的,但也需要关注,因为性能是从用户感知的,不仅仅是代码感知的。
从软件开发架构上看,异步化、解耦、模块化、依赖反转原则,这些都是可以采纳的。
策略上,就是要了解业务,尽力满足业务需求,也要勇于拒绝业务需求,因为性能和稳定性是我要负责的,我得为自己负责。
这周三发现某个最核心的函数居然调用了一个很耗时的操作(但本质上没有太大的用),说明对代码了解不够。也就是具体到PHP,怎么做?
目前的想法,分模块梳理和优化:
用户信息优化(个人信息、配置信息、Session信息、粉丝数、关注数、收藏数、积分、点赞数)缓存还是Redis存储?
单篇文章优化(信息体、文章属性、评论数、收藏数、点赞数、Card形式),缓存?
首页Feed流优化,关注Feed优化。
IM优化、系统消息优化、各种未读数优化。
评论系统优化。
这应该囊括了80%核心的功能,然后分模块去改造,由于关联性实在太大,时间和风险都较大。重点就是异步化、Cache化、非关系存储化、pull改为push。
新技术的重要性不言而语,因为传统解决方案已经无法支撑了,策略就是拿来主义,使用第三方Sass服务;善于使用工具;在核心的技术解决方案上要更加细化;技术选型上不能太广也不能太窄。
大数据,其实一直搞不明白大数据、数据挖掘、机器学习、AI之间的关系,因为我确实不懂,感觉总有很多的数学知识在里面,这周看了一些资料,有了概念上的理解。
数据仓库其实就是数据存储,可以将产品、技术数据入库存储;然后使用算法数据搜索、分析;接下去数据挖掘,比如用户画像、用户之间的关系,挖掘出更多有价值的东西,也可以理解为数据推荐算法;机器学习就是将数据搜集起来统计规律,从而预测可能发生的事情;而人工智能就是基于机器学习,让机器具备人的行为。
从技术栈考虑,早期是Hadoop的天下,HDFS作为分布式数据存储,MapReduce是计算框架,Hive是一个类Sql的查询接口(内部转换为MapReduce任务);后面出现了Spark和Spark SQL,它们类似于Hadoop的MapReduce和Hive,不管是Hadoop还是Spark都是离线任务引擎,就是分析今天以前的数据;后来出现了流式处理框架,就是分析实时数据,代表的软件有Strom、Flink、Spark Streaming;最后基于数据挖掘和机器学习有Mlib、TensorFlow,也要了解各种各样的算法。
我们有很多数据,行为日志、产品数据、应用程序日志,经过处理后可以分析程序的性能、系统的可用性、用户的行为习惯、产品数据指标。对于我们如何下手呢?
在以前的两家公司,大数据团队负责搭建数据据平台,但和业务无关,本质上和购买阿里云服务没有太大的差异。现在我们购买的神策系统,属于Sass平台,拿来即用,价格好像也不贵,昨天还花了一点时间了解他们的技术栈,应该属于一个离线的分析平台,离数据挖掘、推荐引擎还远的很,但确实是一个使用大数据的切入点。
另外上面也说了ELK全家桶和大数据也非常紧密,也可以做一些了解。
长链接,以前接触的都是HTTP短了解,开发效率高,但现在很多应用可能要使用长连接技术了,一方面是推送消息及时、另外减少连接数,在IM场景用的较多,目前想的解决方案可能就是Long-Polling、Web Sockets、HTTP/2等技术,在今年先从简单的解决方案实施起来,可以用在IM或消息未读数服务中,可能也要相应的学一些框架(比如Socket.IO、Swoole);
未来是音视频的天下,第一要掌握一些数据编码技术,比如将来视频编码、压缩,在七牛云上的存储优化,上周在做音频审核项目的时候,也使用了百度的一个AI音频接口,了解了一些FFmpeg知识;而对于音视频点对点聊天、群聊、直播,可能要使用WebRTC技术,周四咨询了以前同事,可以使用腾讯云或声网的服务。
也就是对于音视频技术,要学会选型,自己开发太难了,这是今年要做的一个事情。
反垃圾技术,如果遇到恶意攻击怎么办?系统和应用安全策略也很重要,我上周买的一个ECS就天天发短信说被人做矿机了;反垃圾策略是什么。
这篇周记其实还是很粗糙,很多没想明白,但还是写出来,憋着太难受了,后面再逐步完善。
很多同事也关注了我的公众号,很多话也没法说了,但必须表明态度。
珍惜机会、低调做事、不浮夸、诚实、不怕得罪人,这是基本的原则、我也知道自己的缺陷,所以没有必要遮遮掩掩害怕人知道。
说说产品技术团队,对于后端团队,我95%很满意,态度和专业技能方面很不错,对我也很支持,我不会逼或者要求什么,而是合作、商量的态度;前端团队,非常的专业,虽然和他们没有那么亲近(可能真的是年龄关系),但在平时的沟通以及群的回复看得出很敬业,只要能协商的通大家还是很支持的,唯一的小要求就是希望减少服务器端的运算,让用户的手机去运算。
产品团队很不错,两个女生,承接了所有的需求,反应能力都很快,最近她们也换位思考了,不会说什么时候能完成,而是会问有没有什么好的解决方案,对服务器有没有压力,能说出这些说明并不固执,而是替别人着想了。
工作这面多了技术人员还是很内敛的,不会表达自己的情绪,就是默默干活,这样有时候会让自己很被动,所以我发现有的时候必须要说话。