分享

面霸的八月:小米面试记(1)

 财商能力 2014-02-14

书接上回,今天叙述小米的面试经历。这里可能有一些技术理解和技术方案,欢迎讨论。另昨天共计收入7笔共95元,够我喝几杯咖啡了,谢谢所有捐钱的朋友。

如果你心疼我码字辛苦,有钱朋友钱场,没钱的请拉朋友来捧个钱场,捧场链接:https://me.alipay.com/chunshengster ,多少不限

小米:运维部

在小米是聊了两个部门的,首先是运维部门,在 @wilbur井源 的热情招待下,吃了顿大餐,抱歉的是我没有带足现金,所以付款时我无法“客气”,改天补请。

wilbur井源同两位同事与我四人边吃边聊,我简单介绍当前的网站的服务结构以及部分业务的技术设计,比如网站架构的分布情况,分布式文件系统fastDFS的使用状况、Redis和MySQL的一些部署结构和技术,其中尤其对监控这件事情我做了详细一些的说明(详见服务可用性监控的一些思考以及实践), 中间提到了关于主动监控(主动监控是指通过运维和业务部门指定监控的系统资源、接口、页面、日志等,主动发现问题,警报级别较高)、被控监控的概念(指通 过JSlib或客户端lib对于所有的操作尤其是网络接口的请求进行监控,对异常进行汇报,通过收集日志的方式进行可用性问题的发现)。当然,还有必不可 少的是对haproxy的运行和优化状况(参见Haproxy配置),MySQL的架构及优化方式(见MySQL架构及运维),Redis常见的性能问题(参见redis架构及运维问题),fastDFS同其他分布式存储MogileFS、TFS、lusterfs的在功能、运维成本上的横向比较,多IDC图片cache的部署以及性能优化(参见多idc图片Cache部署),Linux内核参数(参见Linux内核配置)和让我特别自豪的是关于网卡smp affinity/RPF/RFS的优化效果(参考3/4/5)的一些优化等。当然,这是正经的运维部门,我阐述了我对“运维”工作的理解:60%的分析整理工作加上40%的技能,分析整理能力是做好运维的基础

井源也询问了几个安全问题,我粗浅的理解是:从系统管理员(SA)的经历来讲,做好IT系统规划,合理区分服务器角色,通过iptables是能够阻止大多数接入层非法请求的;对于web业务的安全来讲,SQL注入、CRSF等攻击是因为对输入输入内容的过滤不严格导致的,在开发的过程中合理使用一些优秀框架或lib,也能够避免大多数漏洞的产生;有个比较有意思的话题是关于溢出的,现在我已经不会计算溢出地址了,在我当script boy的时候研究过一点,忘光光了,惭愧……

井源这边的效率很好,边吃边聊的气氛很放松,不过很多问题都停留在一些思路和效果数据上,没有勾勾画画的太多深入的探讨。

电商部

大约8点半左右到的电商部门,常规面试的第一轮都是技术,包括细节。面试官是位张姓的team leader。

在这轮面试的过程中,因为是在会议室,有笔有板,所以我边讲边写。大体上介绍了我对web服务架构的理解,我认为,web服务架构大体上离不开这样几个层面:接入层(负载均衡)、业务服务层、数据层,一般还会有不少的后台辅助程序进行同步、异步的处理各种不适合在业务层融合的服务单元。 数据层可以包括DB、Cache、File等,数据层还可能会有很多中间件或代理服务器用来做数据层的负载均衡或是HA,以及Sharding等。同面试 官详细介绍了当前服务的公司在每一层所采用的技术,分别是:haproxy、nginx+php、twemproxy+redis、 MySQL+RedisCache、Varnish+Squid+nginx+fastDFS。

haproxy的服务器配置是按照100w并发的目标进行配置和优化的,计划100w客户端连接,考虑每个客户端连接可能产生1个内部连接,按照每个连接消耗4k(此处修正为17K,haproxy的官方数据,见参考8,感谢 @GNUer 的修正)内存来算,大约8G(此处修正为32G)内存【这里的计算还需要再考虑,我担心haproxy的每个连接消耗17k内存是包含对内部服务器的连接】,实际上往往比这个数字要大。目前达到的最大连接数目测到过16w,在接入层的系统优化上分别有:网卡中断优化(参考3/4/5),linux 内核参数优化(linux sysctl.conf配置)。

值得一提的是,我们的haproxy服务器都是64G内存,实际上远远永不到这么多,图片服务的最外层cache,即Varnish,我们也是部署在haproxy服务器上的。

在最外层服务器上,我们每天大约5亿+(1-1.5亿+的动态请求、3-4亿+的图片请求)的请求量,共计使用7台64G的Dell R410,目前看负载还很低,从系统的各种资源上看,请求量翻倍应该是没有问题的。

在最外层的服务器配置上,有一个问题值得注意,即sysctl.conf的配置中,timestamp必须为0,这个在tcp协议的扩展标准中有提 到,否有nat环境的客户端连接有可能产生异常,异常的状况可以在netstat -s 的输出中看到。还需要注意的是timestamp=0的情况下,tw_reuse是不生效的。

要保证服务器能够接收大并发的连接请求是件不难的事情,但需要考虑一个细节,每接收一个请求,haproxy就需要至少分配一个系统的tcp端口请 求后面的业务服务器、cache服务器,系统一个ip地址可用的端口数最多为65535,一般还需要减去1024。值得考虑的是减 小 tw_bucket 的容量,让系统在tw_bucket满的状况下,对tw状态的连接进行丢弃,以达到快速回收的目的,tw的默认回收时间的2倍的 MSL。还有一个方式就是多配置几个ip。

还有一个问题,接入层的服务器往往会开启iptables,内核中nf的相关配置也是需要优化的,比如 nf_conntrack_max、nf_conntrack_tcp_timeout_established等。

在业务层的优化有nginx+php(fastcgi连接方式php-fpm.conf配置中的优化), 我的一个经验是,如果nginx同phpcgi运行在同一台服务器,采用unix socket的方式进行fastcgi协议的交互是效果最快的,比127.0.0.1的回环地址要快太多。我在08年优化过一台服务器(Dell 2960,16G内存),通过两个步骤,将一台服务器从900qps,优化到6000qps以上,其一是将fastcgi协议运行在unix socket上,其二是合理配置spawn-fcgi的进程数量。现在基本上phpcgi都是运行在php-fpm中的了,其进程池逻辑是我最赞赏的功能 之一。

如果nginx和php-fpm不在同一台服务器上,可以考虑使用fastcgi_keepalive的配置,实现nginx同fastcgi服务器持久连接,以提高效率。

nginx+php-fpm提供的运行状态非常有意义,nginx的status模块和php-fpm的status输出可以告诉我们nginx进 程的请求处理状况,php-fpm的status输出可以告诉我们php-fpm的进程池设置是否合理。我们目前对这两个数据通过nagios定期采集, 并绘制成图表,很有“观赏价值”。

php-fpm.conf的配置中还有几个参数对优化比较重要,其一是进程自动重启的条件pm.max_requests,其二是php-slow log的配置,slow log 是优化php代码的非常重要的信息。在我目前的环境中,php的慢执行日志是通过rsyslog进行传输并集中分析的,以此反向推进开发对php 代码的优化。

php的服务器在高并发的情况下,有可能因为服务器本身可提供的端口数量的限制,无法同redis服务器建立大量的连接,这时候可以在 sysctl.conf中配合timestamps=1 加上tw_reuse/tw_recycle的方式,进行端口快速回收,以便更好的向数据层建立 连接,接入层的haproxy是不可以这样的。

这一层还涉及到一个安全问题,就是php代码被修改并挂马的状况,我的解决方案是,将php-fpm的运行用户同php代码的属主设置成不同的用户,并且保证php-fpm的运行用户不能对php代码具有写的权限。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多