The Mirages

樱桃沟夹事

昨天说了nginx的几个问题,

由于我现在支持的主要是通用CDN,也就是小图片和CSS以及JS这些东西,并没有做大文件的cache。而问了我们视频部门他们也根本不用nginx作为cache使用,所以有些问题还是没考虑周到。 一个问题是之前发现的,在做tmpfs的时候,当你设置的cache大小为tmpfs的90%的时候,一旦要缓存的内容大于这个90%的时候,nginx会自己崩溃掉。这个我明天做个测试再重现一下,现在有点忘记原因了,好像是tmpfs会占用到实际的磁盘才导致的。 另外一个其实是upstream的问题,这个是一个新浪的老兄提的,基本现在是无解。问题是:比如平均一个文件10M,你在磁盘上存3000个文件,然后模拟多个客户端去访问,因为shm一开始是空的,所以都会去后端拽文件,我们放慢这个拽的过程,比如说网络不好吧 呵呵,那么第一个请求发现不在lookup失败,就会去upstream取数据,边取边向downsteam发,并且存在一个临时文件中,这时第二个请求来了也请求这个文件,因为第一个请求没有处理完,所以第二个请求找不到目标文件只好继续去后端拽,又生成临时文件,并发量大的时候,一个大文件会对应N多的临时文件,最终这些文件rename到一个目标文件,大大浪费了磁盘IO。这个rename是内核做的,nginx调完之后就返回了。这种问题往往会导致内部网络流量非常大,而实际却没有根本没有大。 当有多个连接来获取同一个文件的时候,squid中却没有跟nginx cache一样的问题。我们看看squid是怎么解决的吧。我们在squid有这样一个参数collapsed_forwarding on(http://wiki.squid-cache.org/Features/CollapsedForwarding),一旦设置了参数了,当发现有连接请求同一个文件的时候,squid会合并多个连接,但是它会以最慢速的那个连接去取,然后同步地传送给客户端。这样就不会重复请求后端了。但是squid也有问题,因为首先它是同步的。当用户请求的是动态的内容的话会导致客户端错误。而且当一个用户连接速度很快,一个用户连接速度很慢,那就会以最慢的速度进行获取和传输。所以在squid3.0以后取消了这个参数。 这个问题的解决办法暂时看起来只能在nginx cache前充一下热点的大文件。还好一般内网都是千兆连接,这个速度往往大于用户的连接速度。只有当文件特别大,并且热点文件特别多的情况下才会发生。而且nginx这种处理方式也有一定的好处。 nginx upstream流程我们可以参考http://bollaxu.javaeye.com/blog/900424http://bollaxu.javaeye.com/blog/900357这2篇文章。基本是由于nginx upstream为了防止锁所以进程间是不共享的。

在我这边现实环境中主要是有三个问题。 第一个问题是当cache过期的时候,nginx会把cache状态设置为updating,但是这个updating却没有设置一个超时,所以导致的情况当一个cache过期的时候好多nginx会连接到源站取数据,而如果源站并发量有限的话,会导致源站突发负载过高,而这个时候导致nginx一直处于updating过程中,如果导致源站挂掉的话,那完蛋了。当然我们也可以设置proxy_cache_use_stale updating;但是这样会导致cache的内容不准确。

解决的方法有2种,一个是我们现在更改nginx源码,使之可以updating设置有超时时间,这样不会导致长时间连接源站造成拥塞。另外一种就是nginx cache分层,分为父节点和子节点,只有父节点才会去源站更新,子节点只从父节点上更新。 第二个问题是upstream中server的状态,我们知道upstream中可以设置proxy_next_upstream当一个服务器挂掉后自动转到其它的服务器上,但是这里有个问题就是让用户访问的时候proxy会每次都会先访问下这个坏的服务器,连接不通了再转到其它服务器上,这每次都要测试会浪费大量的时间。我们需要得到的是proxy会独立一个线程去检查后端服务器,一旦发现后端服务器挂掉的话,那直接从upstream中剔除掉这个服务器就可。而等检测后端服务器又存活了再加进来。 这个现在有ngx_http_healthcheck_module这个第三方模块。具体可以参考http://wiki.nginx.org/HttpHealthcheckModule 第三个问题是nginx proxy连接nginx cache的时候居然使用的是http1.0的,而不是http1.1,就没法使用keepalive连接后端,导致我们小文件的cache服务器连接数过高,而没法进行复用链接。 这个暂时还没有解决,不过看到http://wiki.nginx.org/HttpUpstreamKeepaliveModule这个第三方模块,但是实际还没有测试过,没法做什么结论。 其实大家可以完全查看http://wiki.nginx.org/3rdPartyModules 来看看是否针对自己的应用,有些还是我们国人自己开发的,但是针对第三方模块还是要谨慎使用,上面的healthcheck模块还是经过我们自己的开发重新修改后并进行压力测试后再上线的。开源就是这点好啊。看来我要得学习学习C语言编程来,以后自己也改改增加增加功能啥的。

Mysql读写分离

首先我们必须知道为什么要分离。这个一般是由于以下原因导致的。

  1. 性能,单台数据库实在是撑不住了
  2. HA,防止单台数据库挂掉造成应用不可用
  3. 扩展,由于业务新增了新的需求

以上几种是我们常见的要进行分离的原因。其中做多的可能是第一和第二种。这个主要还是涉及到钱和服务器的数量上。一般业务都会在前端部署更多的服务器,而在最后端的数据库服务器往往比较少。但是对于好多web2.0 UGC这样的业务的网站还是有必要重视后端的速度和稳定性。   分离的多种方案

  1. query proxy,这个一般是由单独的服务器来进行的,由它负责这个sql语句路由到哪个服务器上。这种proxy的话最好还是要建立HA方式,不然这个proxy就是一个单点故障。这个在之前人人的系统中就是如此,虽然只是负责发起查询的时候建立真实mysql服务器和应用服务器连接,但是还是比较危险的。
  2. Load balance, 后面一堆服务器,通过轮寻的方式来访问mysql服务器。这个很多时候是通过内部DNS来实现。

  分离的多个原则

阅读全文 »

小时候就一个圆脑袋 5497042054_2365cbc2ae_z.jpg 干嘛你要看着我呀? 5497042066_a06d105bb6_z.jpg 我也喜欢长啸几声 5496458279_e7699d25f2_z.jpg 我们长大了哦 5496458297_85a6485050_z.jpg 我们就爱趴着 5497065290_baa66a1698_z.jpg 我也来点朦胧的 5497065310_dbb69397f3_z.jpg 有时候我也思考东西 5497077884_7709db9780_z.jpg 也有惆怅的时候 5497065300_6ab69e5831_z.jpg 这么多愁善感当然是女孩拉,但是我不喜欢这个造型 5497065296_ae22072506_z.jpg 有时候我也来点摇滚的风格 5497077896_ccb004ae32_z.jpg 我就是不喜欢穿衣服,那就意味着我要出门了 5497077906_c50a40ffa7_z.jpg ###########################################

  Best regards Timo Seven

翻译自2010年oreilly mysql user conference中《InnoDB Plugin: Performance Features and Benchmarks》一文 原作者:Jimmy Yang John Russell Calvin Sun InnoDB1.1的新特性

  1. 多个buffer pool实例
  2. 提升恢复性能
  3. 扩展的InnoDB更改buffering
  4. 支持Linux原生的AIO(异步IO)
  5. 多个回滚段
  6. 分拆flush list互斥
  7. 改进purge调度
  8. 改进log_sys互斥
  9. 性能schema支持

多个buffer pool实例

buffer pool互斥是为了保护很多在buffer pool中的数据结构: LRU, Flush List, Free List, Page Hash Table
buffer pool互斥是一个热门互斥(可能不是最热门的)。
在sysbench测试中,它能达到大约700k/s,花费大概50%的时间。
InnoDB性能schema同样可以证明:
5493764597_3c368fed2c_z.jpg

它的解决方法如下:
拆分一个buffer pool成为多个buffer pool实例。这种拆分的结果可以避免所有查询执行代码占用一个以上的buffer pool互斥,只有少数的查询代码会同时占用多个互斥。在16核的服务器上sysbench的读写测试可以提升10%,当然它也会提升只读的性能,在32核的CPU上提升的幅度更大。

使用 innodb_buffer_pool_instances=N,下面是测试结果
5493764599_d0fbcd2abb_z.jpg

阅读全文 »

跟你在一起也很长时间了。现在怎么觉得我们两的共同语言越来越少了,你喜欢的我就勉强跟着喜欢,而我喜欢的你却骂我脑子有毛病。 是阿,我是认识一个脑子有毛病的人,可惜她已经死了,跟电视里那个人一样的毛病–脑瘤。 我知道你的工作压力比我高许多,可也不能因为这样而生闷气啊,这样不光对自己身体不好,对于家人也不好。你以前不是什么事情都喜欢说出来啊,可为什么现在不说了,只是从表情上看出来不大高兴。我知道你的意思是想让我们大家猜哄着你,可你也是大人了啊,可不能跟小孩子一样。我希望的是以后有什么事情可以直接说出来,虽然我看过心理学,但还是不怎么懂你啊。看来我得理论和实践共同成长,也许能做到以后你一个小动作就能知道你想啥了,不过那样会不会觉得我恐怖了呢? 另外一个是穿衣和化妆。我是不反对你在这上面花时间的,我觉得这样挺好,但是你的衣服大多看着不好,感觉太随便了那种。我想对于你工作来说真不适合这样穿。应该更正式一点,你买的休闲西服上的也都不穿,要说配裤子,那我们就买去啊。女孩子还是少穿牛仔裤这样的较好,得淑女点。化妆倒还好啦,本来淡淡的妆就好了,最好是不用化就好,毕竟化妆品都是化学成分,对于皮肤总不会好到哪里去的。看看那些明星不化妆的那个脸,我相信这些都是化妆品给弄的。毁的越多就越化,越化越毁,越毁越化。 好了,虽然这样,我觉得我们家宝宝还是不错的。可能由于单位同事的关系,你对生活的物质需求越来越高,你从小就是吃你爸做的饭长大的,怎么现在就吃不习惯了呢,我都吃的挺习惯的。看来人跟人的差距还是大的。对于我来说外在的物质需求真的很简单,很无所谓。关键是有书看,有事情可做,有梦想,这就心里不再空虚了。我希望每天都能昨天一样,可以安静的写文档看会书,但是这样就让你觉得我不理你了。所以还是做早起的鸟吧,这些事情留在早上来做,请允许我通过1周的时间来调整吧。那样晚上就可以配着你,而且也不耽误学习,但是我现在怕起的太早会打搅到你。 关于兴趣吧,我觉得吹口琴挺好,虽然不会,但是我知道你其实会的,音乐对于开拓自己很有好处的,真羡慕小田子会那种高级乐器。我要会就好了。还有昨天说的折纸啥的,你太小看这些小玩意,这个我还真准备当作爱好来培养,智能电子那个东西要买很多外部设备,而折纸真是材料太简单了。小玩意玩出大花样,不是之前跟你说过之前有个老太太只会剪纸,结果美国人把她当文物一样移民到美国去了。生活中很多事情我们看着简单,但是其实还有很多深入挖掘的东西。你不懂计算机,但是你知道这个内部是多么的复杂,做一个像《愤怒的小鸟》这样的游戏需要多少人写多少代码吗? 这些都是你不可想象的。 好了,先就说这么多吧!

MySQL服务器的linux性能优化和扩展技巧

作者:Yoshinori Matsunbu

作者现在是DeNA公司的数据库和基础设施架构师。
之前在SUN公司工作。
他也是HandlerSocket的作者。
这个是MySQL的NoSQL插件。

本文是根据他的PPT整理而成的,如有不正确敬请指教。

本文有可以直接点击下载:linux性能优化技巧

本文主要的内容有如下:

阅读全文 »

对于常看PDF文档的人来说,批注是非常有用的功能。

而对于我这样经常看英文文档的,有时候旁边加个翻译什么也是常有的事情。最近发现xournal是个不错的pdf批注的工具。可以用很多工具进行批注。默认保存的格式是xoj。但是一旦我们批注完成想进行发布和保存的时候可以导出为pdf格式。 5470057896_e2391bdecc_z.jpg 在ubuntu直接sudo apt-get install xournal 安装就可以了。 也可以上项目首页:http://xournal.sourceforge.net/ 帮助文档在:http://xournal.sourceforge.net/manual.html

sohu系统工程师的面试题还是比较内容全面的。下面就是我之前进的时候的一些笔试题目,之后还有好多面试的,是一轮又一轮阿。应该说这些都是比较基础的题目,而不会考你一些源码啊,这其中还有一些开放的题目。比如15和16题基本可以根据自己的想法来写。

  1. GPLV2协议的主要内涵是什么?
  2. UNIX,Linux,BSD,Solaris,System V之间的关系是?
  3. Linux开机引导的步骤
  4. inode和VFS的涵义?  文件权限 4755的涵义?
  5. 64位和32位的主要差异。
  6. Linux内存管理的工作模式。
  7. DNS反向解析的工作过程。
  8. traceroute的工作原理。
  9. TCP3次握手过程。
  10. TCP滑动窗口原理。
  11. time_wait, fin_wait2的涵义。
  12. http1.1中keepalive1.1的涵义。
  13. apache的apxs和dso的关系。
  14. SQUID的cache置换基本工作原理。
  15. 大型web提供性能的方式。
  16. SCSI标准为什么被sas取代。
  17. RAID0,1,5,0+1涵义。

注:这个手册只是为了方便自己看而翻译,并不是官方的。其中省略了后面getting ext4 code的部分,官方手册请点https://ext4.wiki.kernel.org/index.php/Ext4_Howto

ext4-howto中文版

通用信息 ext4在Linux2.6.28作为了一个稳定版本的功能发布了,同时所有现代的发行版本都包含了它(有些还作为默认文件系统),所以你使用一个新的发行版本的话,也许你已经使用上了ext4,那就不需要改成ext4。

在生产环境中它是可以安全使用的,但是作为任何软件,它都是有bug的(在第一个稳定版本中都有可能被隐藏)。任何周知的严重的bug都会被迅速修复。如果你发现一个严重的bug,你可以联系ext4的开发者在ext4 mailing list(http://vger.kernel.org/vger-lists.html#linux-ext4)。他们通常也会上IRC(https://ext4.wiki.kernel.org/index.php/IRC)。 ext4的特点 兼容性 任何现有的ext3文件系统都可以用ext4重新mount,而不需要任何格式化改变。无论如何,我们都可以在只读模式下通过一串命令来升级ext3文件系统来利用ext4的一些特性。这就意味这你可以增加性能,存储限制和特性而无需重新format或者重新安装系统和软件环境,如果你在生产环境需要ext4的优势,你就可以升级你的文件系统。这个过程是安全的,并且对你的数据是没有风险的(当然,备份你的重要的数据是应该的,就算你没有升级文件系统也是应该的。但是这个升级在RHEL6中是没有售后服务的)。ext4只会对新的数据使用新的数据结构,而老的数据结构会继续保留,当需要时候也会进行对写它们。这就意味着,如果你升级到了ext4,那就就不能再退回到ext3了。 更大的文件系统和文件大小 现在,ext3支持最大16TB的文件系统大小和最大2TB的单个文件大小。ext4增加了48bit的block地址,所以它支持最大1EB的文件系统和最大16TB的单个文件大小。为什么是48bit而不是64bit呢?因为在让ext4支持64bit之前我们还有一些限制需要被修复,所以没有在ext4中被使用。ext4数据结构的设计已经在思想上确认了,所以未来ext4可能在一些点上会实现完整的64bit。1EB在那之前应该是足够的。 注意: 创建大于16TB的文件系统的代码已经在写这篇文章的时候有了。它将在未来会被发布。 1EB=1024PB 1PB=1024TB 1TB=1024GB 子目录扩展 在ext3中现在单个目录中最大的子目录数是32000个。ext4打破了这个限制,允许拥有无限制的子目录。 extents 传统的类Unix文件系统象ext3这样的都使用间接的block映射方式来保持每个block相对应的文件的数据的block的track。对于大文件这是低效的,特别是对大文件进行删除或者清空操作的时候,因为对每一个单一的block的入口都进行了映射,而大文件拥有很多block—>大量的映射,于是就有了缓慢的操作。现代文件系统使用了不同的方法叫作”extents“。一个extent本质上就是一串相邻的物理block。在本质上说“数据在后面n个block中”。比如,一个100MB的文件会被分配到单个那样大小的extent,来替代创建间接的25600个block映射(4KB每个block)。非常巨大的文件也会被分在多个extent中。extent提升了性能,也减少了磁盘碎片,所以extent促进了在磁盘上的保持连续layout。 多block分配 当ext3需要写数据到磁盘上,它的block分配器就会确定哪些空余的block可以被用作写入数据。但是ext3的block分配器在同一时间只能分配一个block。这就意味着如果系统需要写入100MB的数据,在写入的前一个点,它需要调用25600(100MB/4K)次block分配器。这样不仅是没有效率的,它不允许block分配器优化分配策略,因为它不知道有多少数据已经被分配掉的,它只知道单独的block是否被分配掉。ext4使用“multiblock allocator”(mballoc)在一次调用的时候就分配许多block,用来替代一次调用分配单独一个block,避免了一部分的负载压力。这种方法提升了性能,尤其在延迟分配和extent下会更有用。这个特性不影响磁盘的格式。而且ext4的block/inode分配器还有一些其他的提升,会在后面进行描述。 延迟分配 延迟分配(http://en.wikipedia.org/wiki/Allocate-on-flush)是一个性能特性(它不更改磁盘格式)在一些现代的文件系统中诸如XFS,ZFS,btrfs或者Reiserfs4等,它会尽可能延迟block的分配,相反的一些传统的文件系统(如ext3,ext2,Reiserfs3)都是尽可能快的进行分配block。比如当一个进程write(),文件系统的代码就会立刻根据数据将要分配的地方分配block,甚至数据当时还没有被在写到磁盘时它有时就会保存在cache内的数据。这种方法已经落后了。比如当一个进程连续的往一个文件里写入数据,连续不断的write()为数据分配block,但是它不知道文件是否持续增长。而延迟分配就在另一方面,当进行write()时它不会立刻分配block,事实上,它会一直延迟保存在cache中的文件的block的分配,直到它真的是要写入到磁盘上。这给了block分配器以机会来优化那些在老旧系统中所有没有的分配。延迟分配能跟先前两个提到的特性multiblock分配和extent下很好的运行,因为当文件最后写入到磁盘它需要分配到extents中,而这些extent已经通过multiblock分配器分配完成对应的block,这当中会有很大的工作负载。在一些工作负载中这样性能会更好,同时磁盘碎片也会大大改善。 快速fsck fsck是非常缓慢的操作,特别是第一步:检查文件系统中所有的inode。在ext4中,每一组inode表最后都会保存未使用的inode列表(为了安全还含有校验和),所以fsck就不需要检查那些inode。结果是完整的fsck的时间将会提升2到20倍,根据已使用的inode(http://kerneltrap.org/Linux/Improving_fsck_Speeds_in_Ext4)。当在fsck时候必须通告未使用inode的列表在不是ext4的时候。这就意味着当你必须运行fsck来获得未使用inode的列表时,只有下一次fsck运行的时候会更快(任何时候把ext3转成ext4必须先通过fsck)。还有个特性就是fsck加速“灵活的block组”–这个同样能加快文件系统操作。 日志校验 日志是磁盘使用率最高的部分,动了这个部分的block很有可能导致硬件故障。从有问题的日志中进行恢复只会导致更大的问题。ext4会校验这些日志数据来知道是否日志block是否已经失效还是有问题。日志校验还带来一个意外的好处:它把ext3中的2段提交变成了直接提交,在一些情况下对于文件系统操作加快了20%-故可靠性和性能同时都会提升。(注:日志校验提升性能的部分-异步日志记录现在已经被默认关闭,等将来它更可靠之后才会被默认开启) 无日志记录模式 日志记录通过不间断记录磁盘更改的日志来保证文件系统的完整性。当然,它会产生一些额外开销。一些人会有一些特殊的需求和工作需要关闭日志模式并牺牲完整性。在ext4中日志记录功能可以被关闭,能小小的提升性能。 在线磁盘整理 (这个功能已经开发完成,在未来的版本中会包含发布)。由于有延迟分配,extent,以及multiblock分配这些帮助了系统减少碎片,但是只要使用文件系统就会产生碎片。比如:你在一个目录下写3个文件接着写入到磁盘上。有一天你需要更新当中那个文件,使那个文件增加了1bit,然后没有足够的空间给它了。你不得不把多出的部分移动到通过查找的磁盘的其它地方,或者分配文件连续的其它地方,远离了原先的另外2个文件,当一个应用程序需要读取在这个目录下的所有文件就会通过查找来进行(一个文件管理器会对整个目录做一个缩略图)。另外,文件系统只关心确定的文件碎片类型,它不知道比如它必须保留所有相邻的启动相关的文件,因为它不知道哪些文件是启动相关的。为了解决这个问题,ext4将支持在线的磁盘碎片整理,同时e4defrag工具能够整理单个文件和整个文件系统。 inode相关的特性 更大的inode,纳秒级的时间戳,快速的扩展属性,inode预订。。。 更大的inode:ext3支持配置inode的大小(通过mkfs -I参数),但是默认的inode大小是128byte。ext4中将默认的变为256byte。这是为了迎合一些扩展的字段(象纳秒级的时间线或者inode版本),然后inode剩余的空间用作存储扩展属性。这导致访问这些属性更快,提升了那些用到这些扩展属性的应用程序的性能通过3-7次的一个因素。 inode预订存在于当一个目录被创建时都会预订一些inode,并期望在未来会被使用。这提升了性能,因为当一个文件在一个目录下被创建时它们会使用这些被预约的inode。因此文件被创建会删除会更有效率。 纳秒级的时间戳意味着inode信息象“modified time”将可以使用纳秒级别来代替ext3中的秒级别。 连续的预分配 这个特性,在最新的kernel版本中的ext4是可用的,它通过文件系统的glibc仿真实现,但是没有支持,它允许应用程序预分配磁盘空间:应用程序告诉文件系统预分配空间,然后文件系统会预分配必要的block和数据结构,但是这些都是没有数据在里面的直到将来应用需要写数据到里面。这就跟p2p应用程序会预分配自己接下来几个小时或几天的空间来用作下载,但是通过文件的一个通用API来实现会更有效率。这有许多种用途:首先避免应用程序(比如p2p应用程序)通过0来填充满一个文件是非常不经济的。第二会改善磁盘碎片情况由于block会在同时被连续的分配。第三确认应用程序将要需要的磁盘空间,这对于实时的应用程序是非常重要的,因为没有预分配文件系统就需要得到完整的重要操作。这个特性是可用的通过libc posix_fallocate()接口。 默认的隔离 这是一个提升文件系统完整性的一个选择,但是会牺牲一些性能(你可以通过”mount -o barrier=0”来关闭它,推荐你在进行压力测试的时候关闭它)。通过这篇LWN的文章(http://lwn.net/Articles/283161/):“文件系统代码必须在写提交日志记录之前先确认所有的事务信息已经产生在日志中了。仅仅根据正确的顺序写还是不够的;现在的驱动为了更好的性能都会包含大量的内部cache用来记录操作。所以文件系统必须在提交记录之前清楚地通知磁盘获得所有在存储上日志数据。如果提交的数据写别写入,那日志有可能是不完整的。内核的block I/O子系统通过使用隔离是能力解决这个问题的;在本质上,一个隔离就会禁止任何block的写入,直到所有隔离提交前的block都写入到存储上。通过使用隔离,文件系统可以确定在磁盘上数据结构在所有时候都仍旧一致的。” getting ext4 code 略…………

0%