高质量帖,一条条看完了,边看边整理了下觉得有用的 QA,供不喜欢爬楼的参考,感谢秦老师。
---
Q:怎么做到增加机器能线性增加性能的?
A:线性扩容有两种情况,一种是“无状态”服务,比如常见的 web 后端;另一种是“有状态服务”,比如 mysql 这种数据库。
对于无状态服务,一般只要解决了“服务发现”功能,在服务启动之后能够把请求量引到新服务上,就可以做到线性扩容。常见的服务发现包括 DNS 调度(通过域名解析到不同机器)、负载均衡调度(通过反向代理服务转发到不同机器)或者动态服务发现(比如 dubbo ),等等。
对于有状态服务,除了要解决服务发现问题之外,还要解决状态(数据)迁移问题,迁移又分两步:先是数据拆分,常见的都是用哈希或者一致性哈希把数据打散。然后是迁移,常见的办法有快照和日志两类迁移方式。也有一些数据库直接实现了开发无感知的状态迁移功能,比如 hbase。
---
Q:代码优化,从哪些方向入手
A:代码优化分为几个层次。
初期的优化主要集中在功能上,不写 bug。
然后是鲁棒性,在异常情况下不写 bug。
然后是性能,提高系统吞吐量,或者执行降低延迟。
然后是可维护性,在团队开发过程中降低其他人的理解难度,再做好一些,通过设计做到模块解耦,降低删除无用代码的难度。
然后是可扩展性,能够预测系统或者业务的发展方向,提前设计好锚点,让系统能够通过扩展而不是修改的方式增加功能。
再往后就是各自的境界了,我至今也还没参透……
---
Q:做「你关注的某某人评论了某某人」之类的和几度人际关系相关的复杂功能的时候有没有遇到哪些性能上可能的问题
A:这肯定是有性能挑战的,比如“你关注的人也在关注”、“你关注的人最近发的微博”等等,都可以理解是二度关系。主要挑战点是数据的扇出量会比较大,我关注了 1000 人,这 1000 人又每人关注了 1000 人,那就是要 100 万的数据做处理。解决办法要么是减少扇出(比如限制关注人数量),要么是离线算数据,在线取结果。
---
Q:视频存储和提供有什么难点嘛,常年 mysql 中 varchar 选手想了解下
A:视频存储和播放难点要分开说。
对于分布式文件系统来说,有几个难点。
一个是文件大带来的执行效率,比如用户上传一个 10G 的文件,要 1 秒之后立刻能够访问,需要做一些性能优化的策略
一个是可用性,在某台机器宕机之后不能影响用户数据,需要有数据迁移和冗余的策略。
一个是文件多带来的元信息膨胀,分布式文件系统都要保存每个 key 的元信息(比如存在哪台机器上),当文件超过几百亿之后也会带来元信息存取的压力。
而播放一方面是整体缓存架构和调度策略的选择,另一方面的难点主要是对于网络(在目前场景下,主要是 tcp 协议)的理解、对协议(比如 http/http over quic )的理解和策略的选择。
当然,在国内 isp 环境下,更多的还是与人斗,其乐无穷。
---
Q:分布式事务这块是怎么处理的呢?是由业务系统去做一致,幂等之类的保证吗?还是有统一的中间件或框架呢?
A:微博这边的一致性要求并不高,一般是通过幂等性和常规的乐观、悲观锁实现的,分布式事务(至少在我这里)用的不多。
---
Q:在系统或功能模块设计阶段是如何考虑系统的扩展性的呢?是快速原型,实现,上线,后续迭代升级,还是说会在一开始就做一些复杂的设计?在这方面是怎么作取舍呢?
A:设计阶段要考虑的首先是“系统哪些功能是必不可少并且需要快速验证的”,然后是“系统 2 年以内有可能会有什么变化”,觉着不好设计的原因还是设计少了,踩的坑不够多。经验多了,就没这类问题了。
---
Q:视频类的后端开发和其他图文为主的社区产品后端开发,架构、技术选型上有哪些不一样的地方
A:从整体的角度来抽象看,要做的东西其实差不多,都会有增删改查,然后内容理解+推荐;视频特殊一些的地方是有视频编解码。
具体技术选型来说的话,业务上的增删改查都差不多,但是视频存储都是对象存储服务而非关系型数据库;视频方向的内容理解更多的偏向深度学习的实现;视频编解码是一门独立的专业,不过由于太耗计算资源所以还要配合着调度系统一起实现。
---
Q:怎么做才能做到不同地区,用户播放视频都比较流畅?会用到类似 CDN 的部署架构?
A:如果往深了说,流畅是几方面的综合结果,包括视频体积、CDN 部署、播放调度、防劫持、播放调度、防劫持等等。
对于你说的不同地区来说,最重要的方面有两个:一个是 CDN 部署和调度情况,尽量让用户访问边缘节点;然后是防止劫持,一般流量被劫持后都不可避免的性能变差……
---
Q:应用服务器的数据库连接池应该设多大?看了一篇译文
jianshu.com/p/a8f653fc0c54 的观点是"连接数 = ((核心数 * 2) + 有效磁盘数)", 不知道实际一般是不是这样计算
A:我没太看懂你的问题,到底是数据库服务的连接池,还是应用服务连接数据库的连接池?文章里我简单扫了一眼,似乎是后者
不过无论哪个连接池,核心问题还是“同一时间内,需要同时请求的数量”,这个其实就是个数学公式,类似“这条路上每天要跑 1000 辆车,每辆车跑个来回要 10 分钟,那么路建多宽合适”。按我的经验,连接数多设一点不会有太多问题(除非设的数量太夸张把系统连接数耗尽了),而设少了,在系统负载变高的时候就会出现非常明显的排队现象,这对服务性能的影响更大一些。