代码空行太多会影响jvm_Twitter将更多代码转移到JVM,并将性能和封装作为主要驱动力...

代码空行太多会影响jvm

尽管它几乎可以肯定仍然是世界上最大的基于Ruby on Rails的网站,但Twitter逐渐将越来越多的堆栈转移到JVM。 更改的部分原因是JVM经常提到的优点(例如性能和可伸缩性),但也受到对更好地封装单个服务的需求以及其他体系结构问题的驱动。

去年,该公司宣布已在Scala中重写了其后端消息队列和Tweet存储,并且在2010年Spring,Twitter的搜索团队开始重写搜索引擎。 作为工作的一部分,Twitter将搜索存储从MySQL更改为实时版本的Lucene 。 最近,该团队宣布将用名为Blender的Java服务器替换用于搜索的Ruby on Rails前端。 此更改导致搜索延迟下降了3倍。

InfoQ与Twitter工程师Evan Weaver进行了交谈,以了解有关更改背景的更多信息。

Twitter建筑概述

通过查看Twitter的体系结构,可以得出的总体结论之一是,许多设计决策都非常实用。 因此,例如,Twitter的后端广泛使用MySQL和开源分布式数据库CassandraGizzard是其自己的用于创建分布式数据存储的开源框架,用于对MySQL进行分区。 Weaver告诉我们,“这主要用于高度结构化,非常高的SLA数据,因为它相对不灵活”。

所有运行时数据都可以从Gizzard / MySQL或Cassandra获得。 Twitter还广泛使用Hadoop中的 HDFS进行离线计算,并将使用Gizzard划分键值存储Redis的系统上线

我们在MySQL中拥有可以使用的现有模式,因此我们通过Gizzard对其进行了保留和分片,而不是转移到具有不同性能配置文件的系统中。 但是Cassandra灵活得多,我们在将其用于新事物方面拥有非常好的经验。

对于中间层,更灵活的数据问题(例如新产品功能,特别是时间序列数据),需要非常高的写入速度的事情(例如从Hadoop提供派生计算的服务),我们非常广泛地使用Cassandra 。

前端和后端服务之间的通信使用Facebook开发的Thrift作为RPC机制,并使用JSON over REST作为公共RPC,该RPC也用于Twitter自己的客户,包括新的Twitter网站。

语言选择

在语言选择中可以看到类似的实用方法。 Twitter上的一流语言是JavaScript,Ruby,Scala和Java。 他们也支持C,但很少在其中编写新服务。 通常,Weaver告诉我们,来自Ruby背景的开发人员倾向于在S​​cala中工作,而来自C或C ++背景的开发人员则选择Java。

对于搜索团队而言,由于他们在基于Java的Lucene上进行了大量工作,因此他们在编写Java代码方面拥有丰富的经验。 因此,与Scala或其他语言相比,使用Java进行开发更方便。

为了使开发人员能够选择最适合自己的语言,Twitter投入了大量精力来编写内部框架,这些框架封装了常见的问题。 例如, Finagle是一个库,用于以Java,Scala或任何JVM语言构建异步RPC服务器和客户端。 它是用Scala编写的,但也支持高度Java惯用的API。

随着后端代码被拉向JVM,前端客户端代码(与许多现代基于Web的应用程序相同)正逐渐越来越多地使用基于浏览器JavaScript。 结果,Ruby组件正在缩小。

我们最初是一家Rails商店,我相信我们是世界上最大的Rails站点,但是随着我们作为组织和服务的发展,性能和封装已变得至关重要。 我不会说Rails在任何方面都表现不佳,只是我们很快就淘汰了它。 因此,关于Rails的两件事使它不再适合我们的情况。

首先,Ruby运行时很慢,尤其是与JVM相比。 我们一直在努力使垃圾收集器获得合理的性能。

还有Rails所体现的LAMP模型,其中您具有一组层次,每个层次仅与上下两个层次对话,并且没有垂直封装,因此不能很好地服务于我们这样的大型组织。

由于我们一直专注于性能和封装,因此已根据需要解决了缓存,或在VM上出现的性能问题。

Twitter上的大多数请求现在都通过Rails,但是当我们构建新服务时,如果我们选择从头开始构建它们,为了实现更好的封装,我们会将它们移入JVM,因为对性能的关注超过了任何生产力。或这些语言可能具有的敏捷性下降。 因此,当我们重新构建Tweet存储时,我们在Gizzard中将其构建为同类服务,它公开了一个域接口,这是一个Scala系统,用于分区和管理未协调的MySQL节点。 这样就可以有效地消除ActiveRecord对核心Rails堆栈中的推文的使用。

与队列相同; 当出于性能原因要重建并重新封装它时,我们在JVM上编写了它。 因此,随着这类轻量级,面向服务的项目的进行,越来越多的关注正从核心Rails应用程序中剔除。

相反,当我们将渲染代码移入基于浏览器JavaScript时,我们将不再从Rails的用于构建网页的模板模型中受益。 因此,我们正在从两方面撤消关注点,并且在重写它们时,将它们以更快的堆栈重写是有意义的,因为性能对我们而言至关重要。 我们是世界上最大的网站之一,但与其他大型动态网站相比,我们的网站占用的硬件空间很小。

使硬件占用空间保持较小在成本方面具有优势,但也避免了一些次要的可扩展性问题,例如TCP堆栈的性能,这些问题可能会影响具有更大硬件需求的站点。

您可能会认为迁移到JVM很大程度上是出于对性能和可伸缩性的关注,但是实际上,现有的Twitter代码库表现良好。 这样一来,公司就不会被迫进行彻底的改写以使其继续发展。 而是,向JVM迁移的主要动力是提高开发人员的生产力,以及提高性能。

老实说,主要驱动因素是封装,因此我们可以更快地迭代公司。 具有单个的整体应用程序代码库不适合按团队快速移动。 因此,当我们决定封装某些东西时,由于性能方面的考虑,对于大多数系统而言,最好在JVM中重写它,而不是编写一个新的Ruby系统。

除此之外,由于我们非常依赖Ruby,因此我们在现有基础架构上投入了大量投资,并且对我们来说效果很好。

搜索:从Ruby到Java

从Ruby到基于Java的Blender服务器的过渡实际上是分两个阶段完成的。 首先是用搜索团队基于Lucene开发的实时反向索引(称为Earlybird)替换MySQL后端。 Earlybird将存储效率提高了一倍,并提供了添加用于搜索的相关性过滤的灵活性,从而有助于满足对搜索服务的快速增长的需求。 根据工程博客文章

2008年,Twitter搜索平均处理20 TPS(每秒推文)和200 QPS。 到2010年10月,当我们用Earlybird替换MySQL时,该系统平均可以处理1,000 TPS和12,000 QPS ...但是,我们仍然需要替换Ruby on Rails前端,后者只能同步调用Earlybird和经过数年的扩展和向Earlybird的过渡,该公司已积累了大量技术债务。

为了解决这个问题,团队开始开发Java Blender服务器。 Blender是一个基于Netty的Thrift和HTTP服务, Netty是一个用Java编写的高度可扩展的New I / O(NIO)客户端服务器库,可以开发各种协议服务器。 Netty允许Twitter创建完全异步的聚合服务,该服务可以聚合来自多个后端服务的结果,例如实时索引,热门推文和地理索引。 从工程博客:

Netty定义了一个称为Channel的密钥抽象,以封装与网络套接字的连接,该套接字提供一个接口来执行一组I / O操作,例如读,写,连接和绑定。 本质上,所有通道I / O操作都是异步的。

这意味着任何I / O调用都会立即返回一个ChannelFuture实例,该实例通知所请求的I / O操作成功,失败还是被取消。

当Netty服务器接受新连接时,它将创建一个新的通道管道来处理它。 通道管道不过是一系列通道处理程序,用于实现处理请求所需的业务逻辑。

然后将这些管道映射到一组后端服务,自动处理它们之间的传递依赖关系。 在整个工作流程过程中,I / O上没有线程繁忙等待,从而有效利用了CPU,并支持大量并发请求。 此外,可以并行处理对后端服务的许多请求,从而大大减少了延迟。

绩效提升

Twitter的搜索是世界上访问量最大的搜索引擎之一,每天服务超过10亿个查询。 搅拌机的影响是巨大的

推出Blender之后,我们的第95个百分位数的延迟从800毫秒减少了三倍,降至250毫秒,前端服务器上的CPU负载减少了一半。 现在,我们有能力为每台计算机提供10倍的请求数量。 这意味着我们可以用更少的服务器来支持相同数量的请求,从而降低前端服务成本。

静态打字作为生产力的福音

尽管通常将性能和可伸缩性称为使用基于JVM的语言的好处,但Twitter也在静态类型中发现了好处,至少对于其后端服务而言。 韦弗告诉我们

我想说,生产力提高中的一半纯粹是由于搜索Rails堆栈中累积的技术债务。 而且另一半是,由于搜索已进入面向服务的体系结构并公开了各种API,因此静态类型化对于在所有系统之间实施一致性提供了极大的便利。 您可以保证您的数据流或多或少可以正常工作,并专注于功能方面。 而对于诸如构建网页之类的事情,您并不想一直都在重新编译,而您实际上并不需要担心在某种边缘条件下您是否会得到一种意想不到的类型。 但是,当我们进入轻量级的面向服务的体系结构模型时,静态类型变成了真正的生产力收益。 Scala也为您提供了同样的东西。

快速迭代的能力显然对公司至关重要。 在搜索方面,该团队已在Twitter网站上添加了相关性过滤和个性化功能,以提高搜索结果的质量,并扩展了Earlybird的数据结构,以支持对推文中包含的实体(例如图像和视频)进行有效的查找。 他们正在为移动设备进行相关性过滤,并正在继续致力于改善搜索基础结构的可伸缩性及其结果的质量。

Ruby MRI与JRuby

尽管在许多情况下,Twitter仅仅从Ruby迁移到Java或Scala还是有意义的,但是在某些服务中,Ruby仍然是最佳选择。 Twitter目前基于Ruby MRI(也称为CRuby)1.8版,尽管它具有大量重写的垃圾收集器。 他们计划评估迁移到Ruby 1.9并重新实现自定义垃圾收集器所涉及的工作,以及迁移他们不打算将其重新封装到JRuby中的Rails代码所涉及的工作。

最大的问题是,迁移到JRuby会对性能产生影响,这取决于您所依赖的各种客户端的质量。 因此,例如,我们用于CRuby的内存缓存客户端非常快。 据我所知,JRuby客户端甚至还不及性能。 因此,即使JRuby本身的速度快一倍,转移到速度较慢的内存缓存客户端上也会破坏所有这些性能优势。

为了全面评估JRuby,Twitter必须重新编写其Thrift客户端,memcached客户端(可能还有他们的MySQL客户端等),然后他们才能告诉它是否真的对他们有好处。

这不是JRuby的错。 只是目前,周围的生态系统还很不成熟。 CRuby也是如此。 我们投入了很多投资,现在我们可以利用它,而对于JRuby,我们也必须这样做。

结论

在过去的几年中,Ruby on Rails和MySQL的结合在新兴公司中很受欢迎。 在许多情况下,这是一个不错的选择,它可使公司的工程师Swift尝试一些小的新想法,并查看其中的哪些在市场上很受青睐。 但是,在性能和可伸缩性方面以及库和工具链的相对成熟度方面,它确实带来了众所周知的成本。 此外,Twitter的经验表明,随着代码库的增长,Ruby on Rails堆栈可能会带来一些重大的架构挑战。

关于作者

@charleshumble在twitter上)是PRP i Consulting的CTO,全面负责公司内部使用的所有自定义软件的开发。 他在企业软件领域工作了大约15年,担任过开发人员,架构师和开发经理。 他与人共同创立了Conissaunce ,这是一家总部位于英国的企业计算咨询公司,专注于零售和金融服务行业,目前仍是该公司的董事。 他花了尽可能多的时间陪伴他的年轻家庭,并与Twofish一起写音乐。

翻译自: https://www.infoq.com/articles/twitter-java-use/?topicPageSponsorship=c1246725-b0a7-43a6-9ef9-68102c8d48e1

代码空行太多会影响jvm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值