这几年来,我经常跟一些程序员、数据库管理员、系统管理员讨论一个问题:想要获得更好的可伸缩性(scalability),我们到底是应该把硬件升级为一台性能更强大的服务器还是应该买多台性能差一些但是可以组装起来协同工作的服务器集群。
系统的可伸缩性(scalability)可以定义为:当系统硬件升级之后,系统的吞吐量按比例增长的能力。比如,单台服务器可以对100个用户进行服务,那么升级为两台服务器之后,系统至少应该可以对200个用户进行服务。
垂直可伸缩性(Vertical scalability)就是对单个一台服务器添加更多的内存和CPU,也叫做纵向扩容(scale up)。纵向扩容适用在数据库层,因为数据库服务器需要:更大的共享内存空间、很多相互依赖的线程、紧耦合的内部互连接(Tightly-coupled internal interconnect)。
水平可伸缩性(Horizontal scalability)就是添加多台内存和CPU差不多的服务器,也叫横向扩容(scale out)。横向扩容更适合于web层,因为web层具有以下特点:不需要太大的共享内存空间、线程之间通常依赖性不大、多是松耦合的外部互连接(Loosely-coupled external interconnect,这是很重要的一点)、可能需要不同的操作系统做不同类型的服务器。
Scale Out 按字面意思是超过尺寸范围,而Scale Up则是按比例增高。即使用靠增加处理器来提升运算能力和增加独立服务器来增加运算能力。
对于服务器体系来说必须要考虑的一点就是可扩展性(Scalability)。除非业务永不增长,否则随着使用人数不断增多,服务器就一定会很快达到性能和并发极限。解决这个问题,通常只有两个办法:即 代表分布式计算的Scale out和以主机或机箱式为主的Scale up。
Scale Out(向外扩展):就是指企业可以根据需求增加不同的服务器应用,依靠多部服务器协同运算,借负载平衡及容错等功能来提高运算能力及可靠度。
Scale Up(向上扩展):指企业后端大型服务器以增加处理器等运算资源进行升级以获得对应用性能的要求。
在现今这两种技术已经没有明显的区别,各个提供商不仅提供用于分布式计算的Unix和Windows平台,还提供用于集中式计算的Unix和Windows平台。甚至传统的集中式计算大型机也正具有分布式计算的性质——如在IBM zSeries服务器上使用Linux和z/VM的虚拟性能,就是其中的证明。
但是更大更强的服务器同时也是更昂贵的,往往成本会大于部署大量相对便宜的服务器来实现性能的提升。而且服务器性能所能提高的程度也有一定的上限(分布式的部署相对来说性能提高的上限更高些)。所以一种呼声是应该使用向外扩展(Scale Out)来实现可扩展性,同时可以让使用者得以保留通过增加服务器以提升系统能力的后路。
但是在实现中也有很多困难需要解决:
首先,要想成功地实现向外扩展架构必须解决复杂的分布式计算问题(相对来说Scale Up方案不需要考虑这个问题),而这个问题的解决往往需要很复杂的技术和相对多的资金.大型站点如Google、Yahoo和Amazon.com,都自行研发大量相关技术。其次,Scale Out方案还需要对原先是用的软件进行大量的重写工作,以保证系统能在分布式服务器上运行(Scale Up方案则对现有软件几乎没有改动要求)。这一步往往是每个公司的开发人员的噩梦。一个不好会使开发人员的所有工作白费。再者,Scale Out方案始终面临着数据集中的问题,即拆分过的数据在服务器逻辑体系中仍然是各自相对集中的而非无限随意拆分。如果大量的逻辑放在数据库服务器一端,数据库服务器将会使得系统失去Scale out的能力和可能。因此,要保证Scale out的能力就必须保证数据库只处理实质性的数据提交和不可避免的数据查询,对于能够避免的数据查询和非实质性数据提交都应该想办法予以避免。而具体的策略和方案相对没有最优的方法。
在railstutorial中,作者为什么选择使用这个(代码list10.25):http://ruby.railstutorial.org/chapters/updating-showing-and-deleting-usersnamespace:dbdodesc"Filldatabasewithsampledata"task:populate=>:environmentdoRake::Task['db:reset'].invokeUser.create!(:name=>"ExampleUser",:email=>"example@railstutorial.org",:passwo
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
给定一个元素和一个数组,Ruby#index方法返回元素在数组中的位置。我使用二进制搜索实现了我自己的索引方法,期望我的方法会优于内置方法。令我惊讶的是,内置的在实验中的运行速度大约是我的三倍。有Rubyist知道原因吗? 最佳答案 内置#indexisnotabinarysearch,这只是一个简单的迭代搜索。但是,它是用C而不是Ruby实现的,因此自然可以快几个数量级。 关于Ruby#index方法VS二进制搜索,我们在StackOverflow上找到一个类似的问题:
随着ruby被引入为新的编程救世主,我想知道是否有人基于易用性、运行所需的资源、可用性和易定制性而有偏好。两者有更好的吗? 最佳答案 好吧,任何基于Rails的社交网络应用程序的比较都应该包括insoshi(http://portal.insoshi.com/)。话虽这么说,这三个都非常相似,区别在于实现细节。Lovd和Insoshi都是完整的Rails应用程序;它旨在供您将它们用作入门工具包,并使用您自己的自定义功能对其进行扩展。另一方面,CommunityEngine是一个Rails插件。这意味着您可以更轻松地向现有Rail
我看到有两种写作风格:deffind_nest(animal)returnunlessanimal.bird?GPS.find_nest(animal.do_crazy_stuff)end对比deffind_nest(animal)ifanimal.bird?GPS.find_nest(animal.do_crazy_stuff)endend哪个更正确/更可取/遵循最佳实践?还是无所谓? 最佳答案 根据Rubystyleguide,Preferaguardclausewhenyoucanassertinvaliddata.Aguar
您可能知道,从Rails2.2开始,Rails附带了一个简单的本地化和国际化后端。默认情况下,您可以将需要翻译的字符串存储在config文件夹中的本地化文件中。config/locales/en.ymlconfig/locales/it.yml但是Rails也提供了本地化模板和局部的能力。例如,MainController#index操作可以根据模板文件名和当前区域设置选择本地化模板。apps/views/main/index.it.html.erbapps/views/main/index.en.html.erb当您需要翻译单个字符串或短段落时,第一个功能很有用。当同一Action根
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭9年前。Improvethisquestion我目前正在使用guard来监视我的.coffee和.scss文件的变化并适本地编译它们。现在,gruntjs和yeoman提供了类似的功能。从guard转向gruntjs或yeoman的动机是什么?使用yeoman和gruntjs有什么好处,反之亦然?谢谢!
我读到最新版本的Ruby解释器(YARV)将由于字节码编译而有实质性的性能改进。我的问题是有人试过对JRuby运行这个吗?在Windows上执行时有什么明显的不同吗?此链接有一些很好的指标,但大多数是在Linux上运行的...http://antoniocangiano.com/2007/02/19/ruby-implementations-shootout-ruby-vs-yarv-vs-jruby-vs-gardens-point-ruby-net-vs-rubinius-vs-cardinal/提前致谢!托德 最佳答案 该fi
在联想中,我们通常做a:b(belongs_to:something)。当我们使用符号键创建散列时,我们通常会执行a:b。话虽如此,我的问题是这两种语法之间有什么区别。还有什么逻辑可以记住什么时候使用哪个约定? 最佳答案 这与约定无关,与语法有关。:something是Symbol.belongs_to:something是一种被发送到隐式self的方法,同时也省略了括号。我们可以将其写成如下所示:self.belongs_to(:something):something因此只是传递给方法belongs_to的参数。在Hash中,我
提前说明一下,尽管标题看起来与线程RSpecvsCucumber(RSpecstories)相似,但是我的问题根本不同。我理解测试用户故事和单独测试对象行为之间的区别。我的问题是,为什么Cucumber通常与RSpec结合使用来编写用户故事,而RSpec从1.1开始就具有用户故事功能?是不是因为RSpec的重点仍然是单个对象测试,而Cucumber自那以后一直在大力开发,重点放在用户故事上?上下文切换是一件痛苦的事情,而我们开发人员需要处理足够多的工具。我宁愿只使用RSpec,但如果Cucumber与RSpec有一些重要区别,请告诉我。 最佳答案