Intel 10-GbE 网卡性能优化[翻译]

这是一篇翻译文档,原文请见:http://dak1n1.com/blog/7-performance-tuning-intel-10gbe

默认情况下,Linux网络被配置成最佳可用性状态,但不是最佳性能状态。对于一个10GbE的网卡来讲,这是尤其明显的。内核的 send/recv 缓冲区,tcp堆栈的内存分配策略和 数据包的队列都设置的太小,以至于它们不能工作在最佳的性能状态。下面所做的一些测试和优化,希望能够给你的网卡带来一定的性能提升。

在Intel ixgb的驱动文档中,描述了三个可以优化的策略。从性能优化的提升能力上进行排序如下:

1.在服务器和交换机之间允许大帧传输

2.用sysctl来优化内核配置

3.用setpci来优化网卡的PCI配置

需要明确的是,上述优化列表仅仅是一些建议。大多数优化工作是调整一些(个)配置,然后进行压力测试来检查优化是否生效。因此,大家得到的结果可能是多种多样的。

在开始任何压力测试前,我们往往需要禁止掉 irqbanlace 和 cpuspeed。这样做可以让我们获得最大的网络吞吐量以得到最好的压力测试结果。

service irqbalance stop

service cpuspeed stop

chkconfig irqbalance off

chkconfig cpuspeed off

(一)允许大帧数据传输

在linux系统中,配置大帧数据传输仅仅需要一条命令,或是在网卡的配置文件增加一行。

ifconfig eth2 mtu 9000 txqueuelen 1000 up

如果要让这个配置持久化,可以在网卡的配置文件中增加MTU的新值,将“eth2”换成你自己的网卡名字:

vim /etc/sysconfig/network-scripts/ifcfg-eth2

MTU=”9000″

(二)Linux内核 sysctl 配置

在linux系统中有很多重要的配置会影响网络的性能。下面的这些配置项来源于 2008 Red Hat峰会  Mark Wagner的精彩的演讲 (http://www.redhat.com/promo/summit/2008/downloads/pdf/Thursday/Mark_Wagner.pdf )

核心的内存配置:

    net.core.rmem_max –  max size of rx socket buffer

net.core.wmem_max – max size of tx socket buffer

net.core.rmem_default – default rx size of socket buffer

net.core.wmem_default – default tx size of socket buffer

net.core.optmem_max – maximum amount of option memory

net.core.netdev_max_backlog – how many unprocessed rx packets before kernel starts to drop them

下面是我修改后的 /etc/sysctl.conf 文件,可以把它添加到默认的配置后面:

 # — tuning — #

# Increase system file descriptor limit

fs.file-max = 65535

 

# Increase system IP port range to allow for more concurrent connections

net.ipv4.ip_local_port_range = 1024 65000

 

# — 10gbe tuning from Intel ixgb driver README — #

 

# turn off selective ACK and timestamps

net.ipv4.tcp_sack = 0

net.ipv4.tcp_timestamps = 0

 

# memory allocation min/pressure/max.

# read buffer, write buffer, and buffer space

net.ipv4.tcp_rmem = 10000000 10000000 10000000

net.ipv4.tcp_wmem = 10000000 10000000 10000000

net.ipv4.tcp_mem = 10000000 10000000 10000000

 

net.core.rmem_max = 524287

net.core.wmem_max = 524287

net.core.rmem_default = 524287

net.core.wmem_default = 524287

net.core.optmem_max = 524287

net.core.netdev_max_backlog = 300000

(三)PCI 总线优化

如果你考虑让你的优化工作进一步深入,还可以针对该网卡插入的PCI总线进行调整。首先,需要找到要调整的PCI总线地址,通过lspci命令获取:

[chloe@biru ~]$ lspci

07:00.0 Ethernet controller: Intel Corporation 82599EB 10-Gigabit SFI/SFP+ Network Connection (rev 01)

这里的07:00.0 就是PCI总线的地址。现在我们可以在 /proc/bus/pci/devices里面找到更多的信息:

[chloe@biru ~]$ grep 0700 /proc/bus/pci/devices

0700    808610fb        28       d590000c       0        ecc1    0   d58f800c  0  0      80000    0    20  0   4000   0    0        ixgbehttp://dak1n1.com/blog/7-performance-tuning-intel-10gbe

正如我们看到的这样,各种PCI设备的信息就显示出来了。不过,我们最关注的数据在第二列,808610fb。这是设备的供应商ID和设备ID的组合。供应商ID:8086,设备ID:10fb。我们可以使用这些值来优化PCI总线的MMRBC(Maximum Memory Read Byte Count)。

下面的命令可以提升MMRBC到 4k 的读,提升总线上对爆发增长的处理能力。

setpci -v -d 8086:10fb e6.b=2e

关于这条命令:

-d 选项指明网卡在PCI-X总线结构上的位置

e6.b 是 PCI-X 命令的寄存器地址

2e是要配置值

下面是这个寄存器的其他可用值(尽管上面已经列出了一个,2e,是Intel ixgbe文档中推荐的配置值)

MM  value in bytes

22  512 (default)

26  1024

2a  2048

2e  4096

 

测试:

测试往往是在每一项配置调整的时候都要进行的,不过,我这里为了简洁仅仅展示一下优化前和优化后的结果对比。使用的压力测试工具是 “iperf”和 “netperf”

下面是 10GbE 网卡在优化前可能的性能状态:

 [  3]  0.0-100.0 sec   54.7 GBytes  4.70 Gbits/sec

 

bytes  bytes   bytes    secs.    10^6bits/sec

87380 16384 16384    60.00    5012.24

优化后:

 [  3]  0.0-100.0 sec   115 GBytes  9.90 Gbits/sec

 

bytes  bytes   bytes    secs.    10^6bits/sec

10000000 10000000 10000000    30.01    9908.08

哇!优化后带来非常巨大的变化。这是我花了几个小时候在我的HDFS集群中所看到的最好的结论。无论你的应用程序是怎样的,这些优化都应该很适合你。

 

 

 

Intel 10-GbE 网卡性能优化[翻译]已关闭评论

三十之惑–第三部分(百度文库)

今天开始写百度文库的面试,百度文库的面试共经历了三轮,第一轮应该是高工,两位一起面。

两位高工开始很客气的介绍百度社区的组织架构,以及文库的位置,其实,就是说文库很重要,会很好的发展,当然,我相信。后面的就是技术部分了,大体上没有超出小米的范围,当然,更多的是关于架构方面的一些问题。悲催的是我一直没有问他们具体的职位,不同职位或是不同方向的回答侧重点是不一样的(我在考虑是否把这段经历补充在简历当中),当然,我也没有主动介绍太多关于带team开发的事情。

带队开发的事,大多数情况下带队开发leader(除非一线开发组长)做的开发工作太少,可能仅仅会参与项目规划(这差不多都是需求方和一线开发人员定的,leader只是得到一个结果或是压缩工期)、项目追踪、项目推进、项目风险预估和排除。我一直认为“leader要把自己看成是team中最不重要的那个”,让一线的同学拥有做决策的权利,同时参与一线才能知道项目的真实难处在哪里,往往我会自己安排一些小业务模块或是偶尔封装一些框架中使用的lib

有点跑题,回到面试环节,最后两位问了一个关于文库防数字公司抓取的问题,我个人认为这是个无解的问题。不过,我还是大体上思考了几个方案,供大家品评:

其基本逻辑无外乎:增加抓取难度,使其不能抓取;即便抓取了也不能用。

第一面基本上不记得还有其他的问题了,这大概用了1个半小时,不得不说百度的兄弟很客气。

第二面重复一些第一面中关于高可用监控的话题,也大概介绍了一些我做系统优化的环节。其中有个话题倒是被面试官质疑了一下,问题如下“我觉得你做了很多系统架构、优化方面的事情,但是这些事情都是很琐碎,看不出来有什么套路”,大概的意思是做系统优化有没有什么模式或是方法论吧。事实上我本考虑从网络、系统软/硬件、服务单元、代码的逻辑思路来说,但这基本上是“鬼子扫荡式”的排查方式,应该算是大路货。我更想说的是“按图索骥”的方法,所有环节都通过日志、trace的方式进行追踪,通过简单的数据分析的方式获取系统性能的瓶颈以及可能的问题所在。前一种适合“没事找点儿事做”的情况,而后一种,更适合线上业务随机状态下系统问题的发现和追踪。目的性和目标性极强的方式,适合我当时的情况。

二面还问了我一些关于带团队的问题,比如我是如何解决当初空降并让新老团队很好的工作的,我的回答是:第一原因就是幸运,每一位同学都非常善意;其次是大家对项目的共同认可;最后才是我做的一些努力:比如真实,不刻意去做什么一些特别的事情;对新老团队同样看待,工作分工协商解决;安排的事情首先是信任,尽可能充分的听取大家对事情的看法,尽可能的达成一致;请大家自己发现项目中的技术问题,推动形成技术项目进行解决并给予一定的时间;还有,我认为最重要的一点,技术团队的价值应该首先表现在技术环节上,无论是项目质量还是代码质量我认为对我当时的团队状况,一切从简单开始是最好的方式。并且,我用同样简单的方式成功劝服两位已经开始办离职手续的android工程师继续工作,这是当时公司仅有的两位android开发工程师。至少我的经历让我觉得这段管理旅程非常简单顺利。

二面的问题还有一些是比较苛刻的,比如上面提到的如果真的有人对项目不认可怎么办?比如分工协商不成功会如何?还有就是技术团队驱动的技术项目大家会不会愿意参加?林林总总的问题比较琐碎。我的理解是团队中特殊情况总是有的,不过,我非常认同那句可能是马云说的话:要么钱没给够,要么领导做的不够。是否在信任、认同感、承诺、互惠互利等方面做到足够。如果不因私心,往往是因为误会,不要等误会变得太大再沟通。并且,我觉得沟通的时候说话适当直接一些会更容易理解,即便是对对方的不满。猜测对方往往是造成误会的根源。

二面问了我这样的问题“感到做的最好的三件事和最差的三件事”,绞尽脑汁才想不出来凑够三件,不好意思在这里说了。

二面大概一个小时左右吧,轮到了三面,一位百度的高级经理。同这位面试官也沟通了一个小时以上,不过仅记得几个问题了。比如用的最多的百度产品,比如我说搜索还是常用的,比如贴吧也了解过一点,比如LBS地图(很少用百度的产品,最近觉得导航很不错)。最后面试官问我最想做的是什么,我回答是,应用和系统架构、运维方面的优化,我在这方面比较有经验。然后他继续问,“如果带团队开发是否可以?”,我觉得这方面要看团队的工作方式和项目管理方式如何。

百度的面试经历能记得的大体上就这么多,收到HR的评价是“比较有lamp平台的经验,但是方向不太match”(原话),然后推荐到贴吧那边了。

近半年直接带的team仅有运维和一个两人的php开发team,团队很小,所以不太费力气想太多的管理问题,这次求职我也还没有针对管理问题花太多时间进行总结,抽时间认真思考一下。

明天开始写一些我对未来工作的思考以及要求。

三十之惑–第三部分(百度文库)已关闭评论

三十之惑–面霸的八月(第二部分)

书接上回,今天叙述小米的面试经历。

这里可能有一些技术理解和技术方案,欢迎讨论。另昨天共计收入7笔共95元,够我喝几杯咖啡了,谢谢所有捐钱的朋友。

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

小米:

  1. 运维部

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

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

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

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

 

  1. 电商部

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

在这轮面试的过程中,因为是在会议室,有笔有板,所以我边讲边写。大体上介绍了我对web服务架构的理解,我认为,web服务架构大体上离不开这样几个层面:接入层(负载均衡)、业务服务层、数据层,一般还会有不少的后台辅助程序进行同步、异步的处理各种不适合在业务层融合的服务单元。数据层可以包括DBCacheFile等,数据层还可能会有很多中间件或代理服务器用来做数据层的负载均衡或是HA,以及Sharding等。同面试官详细介绍了当前服务的公司在每一层所采用的技术,分别是:haproxynginx+phptwemproxy+redisMySQL+RedisCacheVarnish+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亿+的图片请求)的请求量,共计使用764GDell 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_maxnf_conntrack_tcp_timeout_established等。

 

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

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

nginx+php-fpm提供的运行状态非常有意义,nginxstatus模块和php-fpmstatus输出可以告诉我们nginx进程的请求处理状况,php-fpmstatus输出可以告诉我们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代码具有写的权限。

 

数据层的情况里,MySQL主从结构以及MHA+keepalived的高可用配置,这个基本上是看文档应该就能够理解的。如果是5.6的新版MySQL,其高可用监控可能可以做的更简单,MySQL官方提供对应的工具,只是我还没有测试。对MHA的监控功能,我觉得亮点是MHA对切换过程中MySQL binlog的获取和执行,在最大程度上避免了数据丢失。但是其缺点也是有的,比如:监控进程在触发切换后就停止了,一旦触发,必须重新启动进程再继续监控。06年时我在sina做过一个叫Trust DMM的项目,通过 DNSMON加上自己写的插件,监控MySQL主从集群的可用性,可以实现,主库、主备自动切换(缺乏binlog处理的环节);从库是一组服务器,如果从库发生问题,可以自动下线。只是这套系统部署起来比较麻烦。这个项目曾经获得过sina的创新一等奖。

我还提到了我认为的DBA日常的工作至少应该包括:审查并执行上线SQL;定期检查MySQL慢日志并分析,将分析结果反馈到开发部门进行调整;定期审查数据库中索引的效率以及可用性,进行优化我反馈。现在做一个一般水平的DBA已经相当容易了,对percona的工具了解透彻,已经能够解决非常多的数据库问题了。

MySQL还有一个难缠的问题,numa架构下,大内存服务器内存使用效率的问题,numactl对策略进行调整,如果使用perconaMySQL版本,可以通过 memlock配置对MySQLInnodb引擎进行限制,禁止其使用swap

MySQL常见的架构里,还有一种主从存储引擎不一致的方式,即主库采用Innodb引擎,提高并发写入的能力,从库采用Myisam引擎,这种方式目前我们也在采用。这样做一是为了获取更好的读性能,另外是,Myisam引擎的是可以节省内存的。Myisam在索引数据内存读取,数据内容磁盘读取的状态下,已经可以比较高效的运行了,myisam_use_mmap的配置项,会让MySQLmyisamdata文件也mmap到内存中,这样做既高效,又可以使用mysiam引擎的特性。

数据库主库要避免一件事情发生,就是无条件删除和无条件修改,如“delete from table”以及”update table set xxx=yyyy”等无where条件语句,原则来讲是应该禁止执行的,这样的权限不应该开放给开发的同学,甚至DBA都不能无限制的操作。目前我的解决方案是 sql_safe_updates=1,但这配置是不能够写my.cnf中的,只能启动mysql后进入console进行配置。

 

当前我们还使用了Redis作为DB,基于主从架构,跨IDC。目前的问题是,复制连接断开后,Redis快照重传的问题,从库会在快照替换期间有短暂的性能抖动。 Redis2.8新版本psync的特性应该可以改善这个问题。我们还使用twemproxy,目前部署在每一台php服务器上,并监听unix socketphp使用phpredis的模块进行连接。有效减少三次握手的时间。temwproxy还有很多其他的优秀特性,通过一致性hashcache集群,可以有效的避免cache迁移问题。通过其对后端redis的健康监控,可以自动下线有故障的redis

 

还有针对多IDC的图片存储和Cache部署情况。目前我们自建的图片CDN承载网站每天约4亿的请求,带宽最高峰值约1.5G左右,其结构大体上是中心IDC存储图片原图+SQUID disk cache存储图片缩略图,在外地IDC使用两级缓存,分别为一层SQUID disk cache(两台,做HA),另一层为Varnish cache(最多四台),实际上,如果仅考虑work around的状态,squid cache层基本上也可以不要的。但是,目前这样的结构可以减少varnish回中心节点的请求,减少中心机房带宽的压力。这个结构还算简单,varnish在高并发请求下,有一些资源配置是需要注意的,比如NFILES / VARNISH_MAX_THREADS / nuke_limit 等。

 

沟通的技术问题还是非常多的,包括在井源那里提到监控框架的事情,也尤其提到了我对rsyslog的优化,优化后的rsyslog在可靠性方面是非常值得称赞的(优化思路见参考6

 

我有一些将电商三面的运维运维同学的问题综合到这里了,有些话重复的就不再描述。

值得一提的是二面是另一位开发负责人,一看就是个很有独立思考能力的同学,他问了我一个很有意思的问题,大体的意思是,在系统架构方面,有这样的几个层次,从下往上:使用开源、精通开源,优化并修改开源软件,创造开源软件。问我自己评价我是在哪一个层次的。我认真的思考了一下,我应该是在第二个层次,有些精通的,有些修改过的。

 

电商四面是时间最长的,至少有两个小时以上,结束的时候已经是夜里一点四十了,我觉得电商的老大是应该在支付宝里面给我捐一些钱才好的 ,不知道有没有小米的同学能够转告哈🙂。我们应该是谈到了非常多的事情,包括秒杀的解决方案,包括对持续集成和自动化测试的理解、对后台数据业务类型的开发中数据计算错误的理解,时不时能够得到“我们想的很一致”这样的评价。

那时已近半夜,记忆进入低效态,一些太琐碎的事情记不得了,重复的技术方案也不再赘述。下面简单描述一下我对秒杀的解决方案的理解:10w的数据,从010w,不能多卖。目前的问题是,每次到秒杀时分可能同时进入100w的请求/连接。如何破?

我的方案是:排除usersession等外部依赖服务的前提下,两台ha外面抗并发连接(后来想这个无所谓的,不如做成php的服务器),三台PHP服务器(不要使用任何框架,最朴素的纯粹PHP代码),两台Redis(最初说了一台)。具体优化状况如下:

  • haproxy优化能够支持百万并发连接,这个很容易了
  • nginx优化worker connections,优化nginx的并发支持能力和请求队列的接收能力
  • php-fpm优化listen.backlog,优化fastcgi请求队列的接收能力。
  • Redis 假如在秒杀的1分钟内,服务器不出现故障,优化redis的最大连接数
  • 优化所有服务器的网卡、sysctl参数

php的逻辑可以简单的理解为对redis的某一个key进行incr原子操作,如果返回的当前数值小于等于10w(两台redis的情况下应小于等于5w),则认为中签。【补充:后面也有提到使用队列进行缓冲或是通过gearman worker长连接redis进行取号的方式。但是我认为如果能够满足性能要求,架构越简单越好】

从我以前看到的数据来讲,redis的最好状态在8w qpsnginx+php08年时已经优化到6000 qps,目前的服务器设备(双核16cpu+64G内存)达到23wQps应该也是不难的事情(这个的最新数据我不知道)。上述配置至少应该能够在5s内完成10wredisincr操作。加上系统各系统对请求队列的支持,可以几乎做到不报错,短暂延迟。

如果考虑1redis请求量会很高,可以考虑分片,每台分5w

[补充]看到一些讨论,补充一下当时提到的业务处理的关键:1,不能卖超;2,如果已经买完,所有请求跳转到某个静态页。所以,php代码只需要到redis计数中去检查一下是否超过10w,如果超过,就跳到静态页面。

当然,这是在仅仅思考不到1分钟内给出的方案,从现在来看,haproxy是可以不要,nginx扛并发连接的能力也不错。所有的细节还需要通过压力测试进行验证。而实际情况加上对其他服务的依赖(我不知到还有哪些,抽丝剥茧去除干扰),方案也会更加复杂一些。据电商老大讲,实际情况是,秒杀的服务用了十几台服务器,秒杀的时候偶尔出现一些故障,小米做秒杀的同学,压力很大哦。

如果你提到要记录中签的用户的uid和中签号码,还是redis吧。

(突然wpslinux版崩溃了,只能恢复到这里,后面的部分内容是重写的,可能有点混乱)

针对刚才的问题,我在白板上画了个简单的架构图:haproxy+nginx/php+redishaproxynginx/php都是可线性扩展的,redis可以通过sharding来实现扩展。理论上讲,一个可扩展的架构是可以满足任何性能要求的,更何况如此简单的逻辑,单机性能已经可以做到非常高了。

电商王姓负责人在问我方案时问这个需求会有哪些难点?我看着白板笑笑:目前看,应该不存在难点。如果有问题,应该看日志和服务状态以及服务器状态。

 

第四面聊得很头机,对方几次想结束时都突然冒出来一个问题,每一个都会讨论比较久,比如后台的一些计算操作是否换成java更合适,因为java可以更严谨。我说这可能不是语言的问题,而是程序员习惯和素质的问题,如果想换,其实我倒是更愿意尝鲜,比如用go,还可能可以同时满足性能的问题。

还有突然聊到持续集成,我坦言,我对持续集成的理解停留在用工具实现自动测试和发布这样的层面上,没有实操经验。但我个人的一个粗浅的认知是:持续集成的前提是自动化测试,自动化测试的两个难点:1,自动化测试用例的设计;2,程序员对自动化测试的理解和心理反抗程度。我在目前单位有过短暂的尝试:专业的传统测试人员对测试用例进行设计,程序员接收到的需求应该包括正向逻辑的产品需求和测试用例的需求。开发工作完成的标记是:自己写的测试用例在自己的代码上完全通过,代表自己一项开发工作的完成。

说到这里,对方不禁双手伸出拇指!(哈哈哈哈)

或多或少也还有一些别的话题,我自认为那晚像演讲一样很精彩,只不过时间已过午夜,其他的一些细节不太记得了,如果想起或小米参加面试的同学有提起,我再补充了。

【补充】小米电商的四面还有问到队列的问题,问我了解多少。我对队列的理解大体上是这样:1,对于无法通过扩展性解决的问题,通过队列进行缓冲是非常好的机制,由于队列产品的技术特性,队列产品往往会更倾向于优先使用内存,队列本身的业务逻辑也会比较简单,因此,队列高效的性能,可以缓解数据库并发写的压力,事务性的队列还可以在一定程度上能够帮助业务逻辑更加可靠。

我了解的队列有redis队列、Q4M,还有一种高级的AMQP协议,支持AMQP协议的有ZeroQRabbitQ。我用过有redis队列,及其简单、高效,但是有个特点:队列中的元素取出来后,如果处理失败,数据是不会自动回归队列的;Q4M有个高级的特性,如果取出队列的程序发生异常(如崩溃),Q4M会自动把取出的元素放回队列。Rabbit我了解过一些,用python封装过一个lib自己玩,不过,现实生活中我还没有找到特别合适的场景用它。

整场小米的面试两个部门加起来共计约7个小时,这是我经历过的最长时间的面试了……小米的面试很辛苦,今天码字也很辛苦,现在已经是凌晨1点半了,如果你觉得上面的经过对你有所帮助或是有意思,就捧个钱场或人场吧: http://me.alipay.com/chunshengster

 

 

 

 

参考:

 

  1. Profiling: From single systems to data centers http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/ko//pubs/archive/36575.pdf
  2. X-Trace: A Pervasive Network Tracing Framework
    https://www.usenix.org/conference/nsdi-07/x-trace-pervasive-network-tracing-framework
  3. http://blog.chunshengster.me/2013/05/smp_irq_affinity.html
  4. http://weibo.com/1412805292/zvNrDsqtT
  5. http://weibo.com/2173311714/zw40tv3D2
  6. http://blog.chunshengster.me/2013/07/high_performance_rsyslogd.html
  7. http://www.wandoujia.com/blog/from-qa-to-ep
  8. http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#4-maxconn
498条评论

三十之惑–面霸的八月(第一部分)

三十之惑

                              —面霸的八月

题记:

三十几岁了,从sina大学肄业后,在外面漂泊,不好不坏。

      从好的角度讲,这几年自己的技术没有减退,偶尔也还能够略有深入,同时能够更多的接触到产品、运营、甚至营销,而我自己也能够在很多场景下,不紧不慌,还算从容。从坏的角度讲,每一项都没有达到自己想要的成就。

从坏的角度讲,09年底从sina离职后,至今已经结束了第三份工作。

此次离职实非我愿,具体细节不好也不愿再细说,概括来讲是我作为小公司的技术管理人员虽尽力但仍没有能够让老板理解我在某项目中的安排,反而产生了误解,以致后来越来越多的误解到其爆发,刻意为难。虽有后来的歉意,但间隙已生,且无合适的解决方案,遂,今日失业之现状。

如果你看此文时心有戚戚,请到这里:https://me.alipay.com/chunshengster

好吧,下面正题,首先是“万达”

正题:面试

万达:

万达的推荐工作是一位认识了6-7年的猎头朋友推荐的,小姑娘爽快、伶俐,不好拒绝。坦言讲,我本人对万达还不了解,外面的传言里也大多是不好的,我仅仅是去试试看,职位是web主任开发工程师的职位,听起来也挺“高端”的嘛,当然最后发现整个过程被当作了一个乐子。

到万达下午3点半,20分钟做完题目,一道数据库设计的题目,一道询问熟悉的HTTP协议头及其含义,一道大数据量(千万级别数据)的数据库技术方案,一道所谓的大数据计算,还有两道算法题,其中算法题中有我认为最可耻的“求最大公约数”。

笔试结束,同一位小朋友口头沟通,大约一个半小时,当然,花了这么多时间跟我口水比较多有关系,因为每次看到小朋友木讷的眼神我都忍不住“好为人师”的深入讲解下去。

当然,我对万达和猎头在面试环节安排的人不满意,并将此意见表达给猎头,我觉得面试的人的水平和能力远在我之下,甚至不能对技术问题进行有效沟通。朋友戏谑,我在万达只是找了个“乐子”,实非我意,抱歉。

万达的面试是在周一。周二,我赶了两场:京东旗下的“网银在线”和“小米”。

网银在线:

网银在线的面试流程应该是在沈姓VP的授意下刻意调整的,沈直言,他对我不是面试,正常面试不是这样的流程,为此我深感荣幸和感激。首先是跟沈沟通我现在的情况,以及可能的工作内容和方式。沈给我的主观的感受是,直白、深刻,当然,经历的不同也让我略感压力,压力在于我对其部分判断不能确定是否“武断”,比如,10人团队和30人团队的管理方式上的确存在差别,我并不觉得我现在30人的团队管理是“哥们义气”的方式,当然,我也当面承认,在这30人的管理经历里,我非常幸运的是未遇到突发的管理难题(30team的管理经历我将在后面单独描述)。

同沈沟通的另一个问题是应用运维的方式以及利害。我也是在这个过程中,了解到阿里应用运维在整个业务经营体系中所占的重要性,其承载了开发(coding)和系统环境(软硬件)中间的沟通以及优化的工作,这项工作中有对业务模块、逻辑深入了解的必要,最好有开发的经历,同样需要对系统软硬件的承载能力有所了解深入,对我这种粗浅的理解来讲,就是“为每一双特别的脚定制一双舒适的鞋子”,当然要对这双脚和鞋子都有足够的了解才行。而我的优势在于,在需求分析、产品开发、系统运维、优化上都还蛮有经验,这是做好业务运维的最好的基础。后来我想我从08年在sina博客时开始,就已经开始从事这样的工作了,只不过sina叫产品线架构师。

当然,我也有提到,我在最近这半年系统优化过程中所使用的方法(优化方法和思路后面单独描述),包括简单的对google某篇论文中提到如何通过监控解决线上代码运行效率这一问题的理解(见参考1),包含这篇论文引用的 x-strace见参考2) 的理解。我提到了,在LAMP环境中,这些方式和机制几乎是天然存在的。有个难题是,网银在线是java的平台,我基本上没有接触过。

网银在线的二面是当前的运维负责人(抱歉我没有问具体的title),问了一些还算简单的服务器技术,如我在微博上提到的,很给面子。

三面是人力资源,小姑娘言语犀利,我有一说一,坦然面对并坦言自己不足,直言在人生规划中急需解决的问题。但在最后一次的离职原因上,当时我的确没想明白,也没办法说明白,这个问题在所有面试的过程中,一直在困扰着我。

面试结束后,在京东的大Logo旁请京东的同学拍了一张照片。赶赴小米。

本来周二下午约了潘少宁在车库咖啡,但是网银在线的同学打电话过来说只有周二他们集中面试,并且VP在,无奈,只好委屈潘,把跟潘的会面改到了周三上午。

我在写此面经的同时,给自己留了不少作业,我决定把这些技术方案也都一并写出来,算作面经的一部分。下节预报:小米两个部门的面试和百度文库的面试。

从今天开始,已经正式进入失业阶段,有钱朋友钱场,没钱的请拉朋友来捧个钱场:https://me.alipay.com/chunshengster

另:感谢 @震耳欲聋的沉默 提供“面霸的八月”这个名字

参考:

  1. Profiling: From single systems to data centers http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/ko//pubs/archive/36575.pdf
  2. X-Trace: A Pervasive Network Tracing Framework
    https://www.usenix.org/conference/nsdi-07/x-trace-pervasive-network-tracing-framework
333条评论

关于Rsyslogd 的一些配置 (高性能、高可用 rsyslogd)

      最近公司的日志传输服务器因网间带宽被调整后出现了日志堵塞的情况,更为严重的是公司大量的业务日志也是通过 PHP 的 syslog接口传输的。这样,因为rsyslog的新版本默认不期望丢弃任何数据,而rsyslog中的日志又传输不出去,导致了业务在写日志的时候“被”堵塞住了。

       拿到rsyslog的配置后,发现仅有一些简单的关于传输逻辑的配置,而关于rsyslog进程、队列、传输效率的配置参数都采用默认,这种仅仅能够 work around 的配置在测试或运行初期是允许存在一段时间的,在系统、环境正常的时候能够运行。一旦出现异常,各种问题就全出来了。

       推荐的文档和我认为比较关键的配置请见下图:

rsyslog_config_opt      几点说明:

  1. 推荐仔细阅读 第一篇 关于 rsyslog queue的文档,细节几乎都在这篇文档里。
  2. 定义 $MainMsgQueueFilename 可以简单理解为队列入口无限大,$MainMsgQueueMaxDiskSpace来控制大小。
  3. 队列的堵塞可能的原因是各种其他原因导致的 MainMsg 满了,而默认配置下,rsyslog不主动丢弃消息。
  4. $QueueHighWatermark可以控制 MainMsgQueue 如何使用 disk作为队列存储,而不再是仅仅使用内存。
  5. $MainMsgQueueDiscardMark 和 $MainMsgQueueQueueDiscardSeverity 配合控制如何丢弃消息。
  6. 在我的 x220i ubuntu 环境下,可以看到几十G的队列文件(网络传输堵塞时以及进入的消息量过大时)、丢弃消息的通知,内存使用的状况。因这一切都不复杂,不再赘述。
  7. rsyslogd的RELP(http://www.librelp.com/)相关的内容暂未涉及。

补充:

  1. 附加另外两份参考: http://www.gerhards.net/download/LinuxKongress2010rsyslog.pdf      http://mperedim.wordpress.com/2010/01/21/rsyslog-evaluation/
  2. 2013-07-24 补充文档:

       刚好微博上 @zzyongx  也提供了一个 syslog-safer (https://github.com/zzyongx/syslog-safer) 软件,大家也可以试试。

 

6条评论

puppet模板的自定义数据结构

2013-06-21 15:41:23的屏幕截图 2013-06-21 15:41:00的屏幕截图

 

 

 

折腾了一下,pupet的模板语法真是强大,通过自定义数据结构来实现配置文件配置项扩展性,避免了硬编码在模板中的同种语义的不同变量名,看图:上面和下面的区别

 

 

 

2013-06-21 15:16:42的屏幕截图

puppet模板的自定义数据结构已关闭评论

SMP IRQ Affinity


感谢 @淘宝褚霸 等人的大量文档。各位SA,如果你的服务器cpu使用很不均衡,top 中si的用量很大,不妨试试这个脚本。
五一前优化服务器,把smp_affinity 和 rps/rfs的内容通通看了遍,花了两天时间写了个自动配置的脚本,在github上:http://t.cn/zTQ5HRW ,欢迎抓虫。

[补充]

SMP affinity and proper interrupt handling in Linux
http://www.alexonlinux.com/smp-affinity-and-proper-interrupt-handling-in-linux
文章提到  如果使用的内核中包含 CONFIG_HOTPLUG_CPU 选项为 On的情况下,网卡的中断就可以自己平衡了。

 

 

Scaling in the Linux Networking Stack: http://www.mjmwired.net/kernel/Documentation/networking/scaling.txt
SMP IRQ Affinity: https://cs.uwaterloo.ca/~brecht/servers/apic/SMP-affinity.txt
linux kernel 2.6.35中RFS特性详解: http://www.pagefault.info/?p=115
Linux 多核下绑定硬件中断到不同 CPU(IRQ Affinity): http://www.vpsee.com/2010/07/load-balancing-with-irq-smp-affinity/
计算 SMP IRQ Affinity : http://www.vpsee.com/2010/07/smp-irq-affinity/
Linux SMP IRQ Affinity: http://www.igigo.net/archives/231
Linux内核 RPS/RFS功能详细测试分析: http://www.igigo.net/archives/204
rfs: Receive Flow Steering : http://lwn.net/Articles/381955/
rps: Receive packet steering: http://lwn.net/Articles/361440/
Receive Packet Steering : http://lwn.net/Articles/331582/
Software receive packet steering : http://lwn.net/Articles/328339/
MYSQL数据库网卡软中断不平衡问题及解决方案 : http://blog.yufeng.info/archives/2037 SMP affinity and proper interrupt handling in Linux http://www.alexonlinux.com/smp-affinity-and-proper- interrupt-handling-in-linux
Why interrupt affinity with multiple cores is not such a good thing http://www.alexonlinux.com/why-interrupt-affinity- with-multiple-cores-is-not-such-a-good-thing
Multi-queue network interfaces with SMP on Linux https://greenhost.nl/2013/04/10/multi-queue-network-interfaces-with-smp-on-linux/

10条评论

经典存储架构 Haystack GFS TFS

经典论文翻译导读之《Finding a needle in Haystack: Facebook’s photo storage》   http://www.importnew.com/3292.html

优酷网视频存储架构   http://blog.csdn.net/starxu85/article/details/5673029

经典论文翻译导读之《Google File System》  http://www.importnew.com/3491.html

淘宝CDN、TFS的介绍:

http://www.infoq.com/cn/presentations/zws-taobao-image-store-cdn

http://tfs.taobao.org/index.html 

经典存储架构 Haystack GFS TFS已关闭评论

varnish 503 “ Could not get storage”的一个解决方案

五一高峰,临时帮同事调varnish 503错误,通过“varnishlog -d -c -m TxStatus:503”看到问题所在“ FetchError c Could not get storage”,通过 varnishadm 调整“param.set nuke_limit 512”,503问题立解。没有仔细研究过varnish的更多资料,临时记录。

几条用到的命令:

varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082

param.set nuke_limit 512

param.show nuke_limit

watch -n 5 ‘varnishlog -d -c -m TxStatus:503’

varnishncsa |awk ‘$9 ~ 50’

参考资料:

1,varnish源码,github

2,http://useranswer.com/answer/varnish-returning-503-fetcherror-could-not-get-storage/

3,https://www.varnish-cache.org/trac/ticket/1012

4,http://serverfault.com/questions/372584/varnish-returning-503-fetcherror-could-not-get-storage

5,https://www.varnish-cache.org/forum/topic/530

6,http://serverfault.com/questions/372046/how-much-storage-is-varnish-using

7,https://www.varnish-software.com/static/book/Tuning.html#storage-backends

8,https://github.com/varnish/Varnish-Cache/blob/master/bin/varnishd/cache/cache_fetch.c

varnish 503 “ Could not get storage”的一个解决方案已关闭评论

关于tcp_tw_recycle和tcp_timestamps 的误解

网上大量流传的 tcp_tw_recycle=1 并且tcp_timestamps=0 的优化建议真是害人不浅,连 HAproxy的example里都存在这样的错误:http://t.cn/zTo2IOQ ,传送门:http://t.cn/zOPRrSi http://t.cn/zTo2IOR

记得去年在kernel的文档里面发现过 tw_recyle的描述中提到 timestamps 必须等于1 recyle才会生效,但今年没找到那篇,如果哪位找到kernel的原文,麻烦请 @我 一下

关于tcp_tw_recycle和tcp_timestamps 的误解已关闭评论