为什么用*? 为什么不用*?


  离开RoR有一段时间了,本来不想提些负面的东西,不过JE猎头(机器人?还是感谢下)给我发过几次工作信息,所以我还是来表明下态度,说点感受吧。
  我做过一段时间RoR,感觉小项目还是可以的,一旦项目发展到一定规模,RoR的各种优势都会变得不明显。
  我现在所在的公司网站大概每天3亿PV,服务器加起来也有上千台,同时在线人数接近60万,各种数据每秒访问量都上万,所以不是任何数据库能负载的,即使 是把数据库分库分表(这种情况下用RoR的ActiveRecord也不方便)。目前是按业务划分把各种业务逻辑和cache用C++写中间件,前台 PHP用socket来调用(WebService?太慢),我所知道的一些国内同等访问量的网站也都是使用类似的方式。
  不使用ActiveRecord的RoR项目是什么样的? 这个我还没仔细想过。我使用过1.1.6和之前的版本,对于网站的分层目录支持似乎都不是很好,而大型网站通常都会有很多层分级目录,这样是不是 ActionPack又得考虑要不要再用?看看还剩下什么?ActionWebService?目前很少用到WebService,所以基本上RoR对于 我目前所在的项目来说已经没什么有意义的东西了。
  网站做到一定规模,要解决的东西都是很繁琐的,结果会有一大批人来做,每个人做的都是些非常简单的部分,唯一的要求就是在同样的功能下如何加快效率,服务器毕竟不可以无限增加,而且服务器越多维护成本也越高,cache/HA同步成本也越高。
  前段时间公司请了些人来做敏捷培训,结果是培训完了,根本没什么效果,人家的例子和我们的相差太大。公司让我做RoR培训, 我也推掉了,目前我还看不到公司里使用RoR的合适场合。所以最近关注的都是并发、分布方面的东西。
  为什么用RoR?理由也很简单,在中小型网站项目上,它还是可以用来快速开发原型。我去年用RoR做过一个小项目,大部分时间花在数据库建模、网站逻辑、后台工作自动化、JS脚本等。
  RE: 其实到了全球排名前10之内的网站规模,不管用RoR,PHP,Java,还是Perl,C++都会面临同样的问题,编程语言的差异反而不存在了。你的题目也可以改成"为什么用Java,为什么不用Java?"或者"为什么用PHP,为什么不用PHP?"
  RE: 主要不是说语言,而是框架,java里面可能是hibernate + struts + velocity,面对拆库拆表的情况,hibernate怕也会力不从心,最后可能也只有struts+velocity还能发挥点作用,为了简单还不 如jsp算了,这跟我上面所说的RoR的情况相似。我以前看到许多知名的大网站都用PHP,感觉不能理解,后来想通了,规模上去了,什么ORM都用不上 了,逻辑放前台也不方便,就会形成一些中间层,每个只负责单一业务逻辑,这样前台只需要一个处理显示逻辑的东西,PHP/JSP好像很合适,不过PHP更 得开发人员青睐,修改了放上去就能看到效果(RoR好像也要development模式才行?)。 
  RE: ALL
  (Twitter遇到的麻烦: http://blog.csdn.net/dhansson/archive/2007/05/24/1 623837.aspx)Twitter是一个很令人惊叹的成功故事。我很有幸能和开发团队谈过他们富有挑战性的开发经历。那个时候,他们需要在只有很少缓存的16块芯片情况下,巧妙的处理超过11000次每秒的访问请求。
  Rails让开发的过程变成一个开心的过程,但是当你需要经历所有其他开发环境同样的扩容过程时,这个对比会显得很突兀。或许这是一个自然的反应来为这个反差找一个替罪羊,而无论这个替罪羊(Rails)是多么的自然。
  当你在使用开源软件,发现有些要求是这个软件无法达到的时候,这就是你给开源软件作回报的大好机会。与其坐在原地等待某些厂家来解决你的问题,使用开源软件会给你独特的机会,来做自己命运的主人。与其作这个社区的旁观者,不如作一个参与者。对于用高级编程语言(比如说Ruby)实现的程序框架Rails,以上的话尤其贴切,因为作贡献的门槛非常的低。
  很赞同
  特别是最后一句
  作为一个每日访问量上亿、数千台服务器的巨头网站
  应该表现出自己对于技术社群的贡献
  而不是等着那些从来没有机会做那么大的网站的开源贡献者们来帮忙解决只有你那么大的网站才会遇到的问题
  前几天听了个课程,讲的是公司经营发展的,一般公司前2年是快速成长期,技术通常还不上档次,也比较散。之后5年是规范期,大概到这个5年的末期各个产品才会规范成熟。目前我们刚刚过完前2年,技术上才刚刚从db/php的2层架构往db/midware/php的3层上转型。国外公司也许技术上比较好一些,经过2年就有拿得出手的产品(比如rails)去开源,国内恐怕还差得很远。 
  大网站技术是分散的,通常每一个部分的技术层次都非常低,除了方案整个可以拿来讨论以外,讨论每一个部分的技术都会让人觉得没有含金量,想想 C++调用数据库并缓存数据有什么技术含量?前台PHP通过socket访问C++中间层有什么技术含量?通常一样中间层项目时间紧的话在现有项目上改一天就能完成,至少我觉得这样的事找应届生一样能做,唯一长点见识的就是整个系统架构的把握和大型网站整体负载的一些数据,公司倒觉得应届生理解架构并发现风险的能力差了,而这正是公司想要的。只有把网站架构拿来讨论才是有意义的,不过把整个网站的架构拿出来讨论那不是掀了自己的底嘛。 
  我并没有参与过大型高并发高负载网站的建设,不过对楼主的一些观点存在疑问,请教一下:
  各种数据每秒访问量都上万,所以不是任何数据库能负载的,即使是把数据库分库分表(这种情况下用RoR的ActiveRecord也不方便)。目前是按业 务划分把各种业务逻辑和cache用C++写中间件,前台PHP用socket来调用(WebService?太慢),我所知道的一些国内同等访问量的网 站也都是使用类似的方式。
  疑问:
  因为数据库压力采用分库分表的话,我理解中的Hibernate/JPA应该可以应付这样的场景,保持多个sessionFactory,根据合适的策略选择相应 的sessionFactory 。虽然我没使用过rails,但是 ActiveRecord同时连接多个数据库应该是一个很合理的需求。
  如果 rails应用到几个大型高并发高负载项目里面,会碰到具体的应对高并发高负载而设计的系统架构所带来的问题,伴随这些具体问题的解决,rails似乎也不能成为架构高性能网站的阻碍哦。比如楼主提到的分库分表,多级目录的问题。
  以前用hibernate主要是做一些表的映射、关联,更深层的应用就没有了,所以也没什么经验,拿个具体的情况来分析一下吧。
  目前主要数据库是mysql,由于数据库存储限制:
  1、通常会把用户名和密码放一个库(负载相对较少,但也要依赖cache)。
  2、用户基本资料拆开多台DB按用户名或ID hash,用户扩展信息也拆开多台。
  3、用户积分因为太敏感,甚至使用了oracle来保证效率和稳定性(事实证明它比mysql慢。。它的C++绑定也更不稳定)。
  4、用户发帖是保存在文件的,数据库只保存文件链接发帖人等简单信息。
  5、用户之间的消息是放数据库的,当然也是按用户名hash到多台,这时候要查询我给别人的消息和别人给我的消息,就得从2个表里面查,因为你给别人的消息是按别人的用户名hash到某一台上,别人给你的是按你的用户名hash的,所以增加一条消息就得往2个库各写一条。
  以上列举了一部分应用,当然由于库拆得比较散,基本上每个库都会有冗余字段。
  上面这种情况下,能不能分析一下hibernate和ActiveRecord用得比较舒服的部分?
  我在用rails的时候,ActiveRecord对于多数据库支持并不好,即使是有这样的方案也是非方的技巧。分表情况下表之间的关联基本上没法做,如果没有关联,ActiveRecord的意义只是帮我们生成SQL?
  多级目录不是最大的问题,也不是阻碍性能的问题,俺只想找个最后的理由把RoR不适用这个项目说得更充分些。。。
  谢谢你能够提供更多的信息来参与讨论, 针对你提到的2),这样的情况下,按照我的理解,现有的java的orm框架无法针对不同库的表作映射。 activeRecord应该也没有考虑到这种情况。
  不知道你们作出的分库的依据是什么,我觉得更合理的分库依据应该根据负载压力和模块独立性来分离,比如你提到的消息发送应该是统一的模块,按照用户名hash到不同的库的话,对于业务层开发带来一定的复杂度。
  分表的话,java的orm有些策略可以绕着解决,比如用继承策略来解决。但是也是比较别扭。 不过,我更想了解的是你们作出的分表的依据是什么?
  这样的情况下,模型的关联映射在现有的orm框架下确实太牵强了,即使用了,收到的效果也是很小的,模型也会随之退化到单实体+基本类型外键的维护上来,如果让我选择的话,基本上也是选择spring的jdbcTemplate了。
  如果觉得java orm是促进开发效率的一个基本前提的话,那么在系统架构选择上,特别是数据库架构设计上,可能还要更慎重一些,因为不同于数据库底层开发,orm对于数据库的要求会有一些苛刻。为了最大化获得模型映射的效果,有一些建议不知道是否合理:
  在考虑访问压力的情况下,尽量按照耦合紧密的原则分库,使得某一个库的表关联能够作充分的模型映射,而对于少数的外库关联仍然需要做手工的维护,不过已经简化到最小。
  因为数据量大而分表的话,可以采用多态映射关联来做和多表的关联。 
  基本上分库主要原因都是和容量或性能有关,上亿用户,每个用户只保存一个用户名和密码,也有好几G的数据。
  为了登录部分效率考虑,用户名和密码拆到一个库中,因为这部分读取并不是特别频繁,所以目前用主备方式,备的目的是主挂掉至少不会让用户无法登录,顶多无法注册而已。
  用户的基本资料字段是固定的,但容量有些大,访问也比较频繁。之前用户没有中间层,所以拆库来提高效率。现在有中间层,拆库的意义也变了,领导不希望任何一台机器故障影响到所有用户,影响部分用户还是勉强可接受的。实际上随着用户的不断增加,即便是使用中间层也会有压力,毕竟中间层只是帮数据库挡了读取的压力,而读写比例通常情况下是10:1左右。
  用户扩展信息,这个是一对多的,一个用户可自定义不同的字段,通常是用户有修改时更新一下,读取压力并不大,同样是因为中间把把读取压力都挡掉了,但容量非常大。
  当然也考虑过如果有中间层,是不是数据库不用拆得这么细,目前也做过一些合并工作,不过意义并不大,因为所有数据库容量加起来以T计,不管是备份还是扩容甚至修复硬件故障都会影响用户很长时间,现在拆得这么细,通常一个点的故障只会影响一部分用户的一部分功能。目前硬件故障还是会经常有的,比如某国外品牌的服务器故障率非常高。扩容也是经常会有的,文件每天上传量就超过2T,每月都增加存储。数据库差不多每3月-6月都要重新拆分一次,因为容量。 
  楼主的做法和我当时在网易的做法非常相似,不过我们当时就是JDBC,拆表的方法我用Hibernate实现过,不过拆库就比较麻烦了,如果不涉及事务还好。
  ebay也是拆库拆表的方式,在应用级处理之间的关联关系,我想越是大型的系统,在应用级处理的方式越原始,不能用框架,或是需要自己写框架处理。
  还有一点,我认为整体网站应该拆分为非常细小的应用,一个应用只处理一样事情,应用之间的调用可以用HTTP、Socket,不建议Webservice,效率较低。
  还是我一开始说的,99.99%的中小网站永远不会变成大型网站。所以"如何开发中小网站"的知识不能应用于大型网站,并不是一个严重的问题。
  另一方面,大型网站会遇到一些特殊的问题。这些问题也许别人也会遇到,但只有他们有足够的钱来解决。出于社会责任感,他们应该把这些解决方案贡献给开源社区。
  具体到这个案例,就是楼主应该说"我告诉你们如何用Ruby(甚至Rails)处理复杂的数据库",而不是问"Ruby on Rails应该如何处理这些复杂的数据库"。这才是一个大型网站,一个受到最多用户关注的组织,一个拥有最强技术力量和最多资金的组织应该有的态度。 
  说到底,开发大型网站和中小型网站的方法可能大不一样,这就带来一个问题,有比较丰富的中小型网站经验的架构师不一定能胜任大型网站,反过来应该也成立,把大型网站的方法弄到中小网站上,会不会造成开发周期长?中间是不是有个鸿沟?
  事情都是这样的,谁能一开始想那么远呢?先拣手头的合适的工具上手再说,以后再慢慢改慢慢优化。即使到最后把以前的都推翻了也是核算的。
  顺便说,如果富客户越来越流行,以后连eruby/jsp/php这些动态页面显示层大概也没用了,就只剩中间件+静态页面+富客户。。。
  我也是这么想的,富客户+中间件,静态页面都没必要了,呵呵。
  那这种中间件,用Rails是再合适没有了,Rails已经提供了完善的REST和XML输出支持,什么Flex啊,Ext-js啊,都合作良好,你唯一要做的,就是把ActiveRecord改成ActiveCICS或者ActiveTuxteo或者ActiveSocket...
  这也是合理的。目前我们用C++写中间件,都是自定义协议格式。如果直接提供给客户端,协议上还得包装成XML或其它,一些安全方面的逻辑还是要有一层,因为这些C++中间件基本上都是内网使用,不考虑安全性,也没办法考虑,它的功能相当于自己实现高性能cache的数据库,每一个调用相当于一个存储过程。 
  通常银行系统对于稳定性、逻辑原子性的要求比较高,性能要求相对较低,我在网银上转帐通常一次操作要十几秒,但在网站系统上这是不可接受的。网站通常对于性能和稳定性要求比较同,操作原子性都排到后面了,有时候甚至是异步写,比如用户发个帖子加5分,我只要保证他马上能看到帖子,马上能刷新他cache里的分数,什么时候加到数据库里面作永久存档都不重要。这种需求的差异带来的数据库设计差异也是比较大的。
  你的第一个方法,对于一个用户多条记录的,比如论坛发帖是可以的,不过通常论坛是按最后回复来排序,分开是否不合适?这种方式对于支付系统还是可以考虑的。
  第二个方法,我前面简单描述过,通常不能把一个用户所有信息放在一起,因为有时候某些表负载会比较高,不希望一些不重要的系统影响到登录、积分这些严重影响用户体验的。全部放在一起,可能就会分出更多的相同结构的数据库服务器,维护也是比较麻烦的。另外有些相互关联的比如某用户的好友,某用户是谁的好友这2个反向关系,其它一些我发出的邮件和我收到的邮件,每添加一条记录都是要写2个不同表的。
  公司有产品部门,他们会分析哪些东西对用户是最敏感的,页面元素甚至一个小链接一个小图标对用户的影响,所有的系统架构基本上都要考虑他们的分析结果,通常他们的意见都是和用户非常贴近的。 
  如果不采用你们目前的做法,而是把用户分在不同的库中,"这些系统在某些时候可能处于极高负载之下"还会发生吗?异步操作还有必要吗?
  不同的用户只会对不同的服务器产生压力,根本不会出现处理不过来的高峰,10台不行,就20台,100台,10000台...,因为水平扩展总是可能,而且近乎于无限制。
  但如果是按照分用户属性的方法,毕竟属性是有限的,不可能无限分解的,所以,会存在一个上限。
  另外,从程序改动来说,分用户的方法,会使得过渡相当平滑,对于业务层来说,编程模式同一个数据库没有任何区别,除了在从一台服务器升级到两台,需要改变一段代码外,后续增加的服务器可以通过配置来完成,完全不需要改变任何代码。 但如果是分属性的方法,业务层是否还能做到透明呢? 
  Link:
  为什么用RoR?为什么不用RoR? http://www.javaeye.com/topic/94774?page=3
  解决海量数据的新思路 分布式数据库: http://www.javaeye.com/topic/212046
  SOHU这几年一些门户级别的程序系统(C/C++开发) : http://dynamiclu.javaeye.com/blog/484766

你可能感兴趣的:(为什么用*? 为什么不用*?)