Gemstone在RailsConf上所展示的Maglev Demo展現(xiàn)了Gemstone的分布式VM技術(shù),它可以透明地跨越多個(gè)Gemstone VM以共享相同的對(duì)象內(nèi)存。
Terracotta是一項(xiàng)Java技術(shù),它也可以完成類似的功能。Fabio Kung已經(jīng)開(kāi)始了一些嘗試以將Terracotta應(yīng)用到JRuby上。過(guò)去他也嘗試過(guò)一些類似的項(xiàng)目。Gemstone還嘗試了在其基于Java的產(chǎn)品上支持JRuby,之前他們也嘗試過(guò)將Terracotta應(yīng)用到JRuby上,盡管沒(méi)有取得實(shí)質(zhì)性的突破。
我們采訪了Fabio Kung以了解該項(xiàng)目,他稱這個(gè)項(xiàng)目為“JMaglev”,我們想知道要想讓JRuby和Terracotta協(xié)同工作需要做哪些事情以及需要解決哪些問(wèn)題。
首先,F(xiàn)abio談到了他的實(shí)現(xiàn)以及他是如何對(duì)JRuby進(jìn)行了修改以讓其正常工作:
我使用了Terracotta POJO集群以便JRuby內(nèi)核可被集群中的所有節(jié)點(diǎn)所共享。事實(shí)上,每次運(yùn)行都會(huì)有一些全局變量,像下面這樣:
public class Ruby {及:
// ...
private GlobalVariables globalVariables = new GlobalVariables();
}
public class GlobalVariables {
// ...
private List values = new ArrayList();
}
Terracotta僅僅對(duì)這個(gè)全局變量列表進(jìn)行集群。對(duì)該列表的任何改變都會(huì)被復(fù)制到集群中的所有JRuby運(yùn)行時(shí)。這樣做的好處在于你可以將任何 ruby對(duì)象增加到該列表中,甚至連復(fù)雜的對(duì)象如regexps、hashes和procs都可以。所有的全局變量都會(huì)自動(dòng)被共享,同時(shí)由全局變量所引用 的任何對(duì)象都會(huì)被Terracotta加到集群中。
為了做到這一點(diǎn),我需要對(duì)JRuby進(jìn)行一些修補(bǔ),使其可以被“集群”。事實(shí)上,JRuby中的每個(gè)ruby對(duì)象都會(huì)維護(hù)一個(gè)ruby運(yùn)行時(shí)引用。由于共 享的對(duì)象會(huì)用在很多不同的運(yùn)行時(shí)中,所以JRuby必須得支持運(yùn)行時(shí)的增加及刪除。我可以解決這個(gè)問(wèn)題,但是每個(gè)JVM上只能有一個(gè)Ruby運(yùn)行時(shí)。在這 個(gè)地方仍然有一些尚未解決和需要討論的問(wèn)題,如:
——全局對(duì)象標(biāo)識(shí)符:在所有節(jié)點(diǎn)中object_id都應(yīng)該相同么?——共享的元類(metaclass):當(dāng)不同節(jié)點(diǎn)中的對(duì)象類、父類或者是包含的模塊發(fā)生變化時(shí)怎么辦?——在單個(gè)JVM上對(duì)多個(gè)運(yùn)行時(shí)的支持。
對(duì)于這些問(wèn)題我采取了簡(jiǎn)單的解決方法,但每種方法都需要一整篇博文才能說(shuō)明白:-)
Fabio解釋了他知道的一些針對(duì)JRuby和Terracotta的用例:
通過(guò)使用Terracotta的High Availability模式,我認(rèn)為“JMaglev”(或許需要起個(gè)更好的名字)絕對(duì)能成為一個(gè)很棒的memcached而無(wú)需侵入Ruby代碼。然 而還有很多事情需要做。這就是我將其開(kāi)放的原因所在,如果大家感興趣,都可以盡一份力:http://github.com/fabiokung/clustered-jruby/
很多服務(wù)器都可以配置在Terracotta中,其中一個(gè)服務(wù)器叫“主”服務(wù)器(或者叫活動(dòng)服務(wù)器),其他的處于備用模式。這很有意思,因?yàn)橐坏┗顒?dòng)服務(wù) 器崩潰,其他的就會(huì)自動(dòng)頂替上去。在Terracotta的企業(yè)版中甚至還有一種可用的模式,該模式可以開(kāi)啟多個(gè)活動(dòng)服務(wù)器,這與memcached所做 的事情差不多,但是memcached不會(huì)持久化對(duì)象。
Terracotta可作為一個(gè)分布式緩存,同時(shí)無(wú)需Java序列化:它僅僅復(fù)制改變的東西。你只需要將想從數(shù)據(jù)庫(kù)中取出的對(duì)象共享給集群中所有的節(jié)點(diǎn)即 可。通過(guò)使用JMaglev,你只需將他們放到全局變量中即可——$shared = Person.find(:all)。
其他可能的用例是在Rails應(yīng)用中的多個(gè)進(jìn)程和機(jī)器上共享HttpSession。如果將rails應(yīng)用部署到JRuby中,那么可以使用透明的集群對(duì)象來(lái)維護(hù)集群中所有節(jié)點(diǎn)所共享的HttpSession。
事實(shí)上,任何Terracotta用例都是JMaglev用例。坦誠(chéng)地說(shuō),就是因?yàn)檫@是可行的,我才這么做。這與Avy Briant的Maglev例子非常像:他說(shuō)可以使用SmallTalk VMs運(yùn)行Ruby代碼,然后Gemstone的那些家伙讓他證明這是可行的:-)
我希望那些比我更富創(chuàng)造力的人們能為“JMaglev”想出更多創(chuàng)造性的用例。
分布式的對(duì)象內(nèi)存僅僅是Gemstone/S(以及MagLev)諸多特性中的一個(gè);另一個(gè)重要特性是持久化。正如Gemstone的Monty Williams在最近的一個(gè)關(guān)于Rails的播客中所說(shuō),Gemstone/S支持對(duì)象內(nèi)存的持久化,這意味著我們無(wú)需ORM甚至是RDBMS來(lái)存儲(chǔ)數(shù)據(jù)。
當(dāng)被問(wèn)到“JMaglev”是否支持類似的功能時(shí),F(xiàn)abio說(shuō)到:
所有共享的ruby對(duì)象都位于Terracotta服務(wù)器中,而Terracotta服務(wù)器能自動(dòng)地持久化這些對(duì)象,即使他們不 是序列化的也可以。客戶端持有這些真正的、共享的對(duì)象的樁(stubs)。你只需將服務(wù)器配置成持久化模式即可。我還沒(méi)有測(cè)過(guò),但這需要在XML配置文件 中增加一行。
我認(rèn)為T(mén)erracotta可作為一個(gè)面向?qū)ο蟮臄?shù)據(jù)庫(kù)以持久化JRuby對(duì)象,但我覺(jué)得這不是目前最主要的目標(biāo)。Terracotta現(xiàn)在可以通過(guò)其 High Availability模式來(lái)持久化共享的對(duì)象,這存在于fail-safe-high-available部署中。http://www.terracotta.org/web/display/docs/Configuring+Terracotta+For+High+Availability。
Terracotta的站點(diǎn)上列出了很多Terracotta集成模塊(Terracotta Integration Modules,即TIM),其中一些面向的是流行的ORM解決方案。當(dāng)被問(wèn)到這是否有助于持久化時(shí),F(xiàn)abio說(shuō)到這些TIM的目的是不同的:
這些TIM并不涉及共享對(duì)象的自動(dòng)持久化。他們僅有助于Terracotta與這些ORM框架的協(xié)作。例如,hibernate TIM與持久化沒(méi)有任何關(guān)系。它僅僅是簡(jiǎn)化了Hibernate對(duì)集群的(分布式的)EhCache(以及其他)的使用而無(wú)需真正的分布式緩存,如 JBoss TreeCache和memcached。
Fabio展示了JRuby與Terracotta是如何協(xié)作的。要想嘗試一下,請(qǐng)參考Fabio在Github上的clustered-jruby倉(cāng)庫(kù),它提供了你所需要的所有內(nèi)容。
Ibatis技術(shù)文檔
Hibernate常見(jiàn)問(wèn)題總結(jié)