<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

         摘要: 首先先介紹一款知名的網(wǎng)站壓力測(cè)試工具:webbench.Webbench能測(cè)試處在相同硬件上,不同服務(wù)的性能以及不同硬件上同一個(gè)服務(wù)的運(yùn)行狀況。webbench的標(biāo)準(zhǔn)測(cè)試可以向我們展示服務(wù)器的兩項(xiàng)內(nèi)容:每分鐘相應(yīng)請(qǐng)求數(shù)和每秒鐘傳輸數(shù)據(jù)量。webbench不但能具有便準(zhǔn)靜態(tài)頁(yè)面的測(cè)試能力,還能對(duì)動(dòng)態(tài)頁(yè)面(ASP,PHP,JAVA,CGI)進(jìn) 行測(cè)試的能力。還有就是他支持對(duì)含有SSL的安全網(wǎng)站例如電子...  閱讀全文
    posted @ 2015-03-17 09:59 小馬歌 閱讀(308) | 評(píng)論 (0)編輯 收藏
     
    from: http://nll.im/post/tomcat-apr.html

    操作系統(tǒng):Centos6.3
    Tomcat:7.0.42
    JDK:1.6.0_45
    配置:8G,4核.

    最近tomcat負(fù)載比較高,默認(rèn)的配置和bio的處理方式已經(jīng)無(wú)力支撐.據(jù)說(shuō)APR能提升50%~60%的性能,所以嘗試下APR優(yōu)化.
    APR介紹:

    Tomcat可以使用APR來(lái)提供超強(qiáng)的可伸縮性和性能,更好地集成本地服務(wù)器技術(shù)。  APR(Apache Portable Runtime)是一個(gè)高可移植庫(kù),它是Apache HTTP Server 2.x的核心。  APR有很多用途,包括訪問(wèn)高級(jí)IO功能(例如sendfile,epoll和OpenSSL),OS級(jí)別功能(隨機(jī)數(shù)生成,系統(tǒng)狀態(tài)等等),本地進(jìn)程管理(共享內(nèi)存,NT管道和UNIX sockets)。這些功能可以使Tomcat作為一個(gè)通常的前臺(tái)WEB服務(wù)器,能更好地和其它本地web技術(shù)集成,總體上讓Java更有效率作為一個(gè)高性能web服務(wù)器平臺(tái)而不是簡(jiǎn)單作為后臺(tái)容器。  在產(chǎn)品環(huán)境中,特別是直接使用Tomcat做WEB服務(wù)器的時(shí)候,應(yīng)該使用Tomcat Native來(lái)提高其性能。

    1. 服務(wù)器安裝GCC

    客戶服務(wù)器連不上外網(wǎng),服務(wù)器也沒(méi)有g(shù)cc,所以先使用代理連接外網(wǎng),修改/etc/yum.conf,加入代理配置:

    proxy=http://10.103.0.46:808

    如果需要驗(yàn)證加入用戶名密碼:

    proxy_username=代理服務(wù)器用戶名 proxy_password=代理服務(wù)器密碼 

    yum使用163的Centos源:參考http://mirrors.163.com/.help/centos.html
    先備份

    mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 

    然后下載CentOS6 放入到/etc/yum.repos.d/(操作前請(qǐng)做好相應(yīng)備份)

    運(yùn)行以下命令生成緩存:

    yum clean all yum makecache 

    然后安裝gcc:

    yum -y install gcc 

    2. 安裝APR

    http://apr.apache.org/download.cgi下載apr,apr-util,apr-iconv. 因?yàn)榉?wù)器沒(méi)有配置全局的http代理,只是yum代理,所以下載之后傳到服務(wù)器即可.

    傳輸完安裝apr:

    tar zxvf apr-1.5.1.tar.gz cd apr-1.5.1 ./configure --prefix=/usr/local/apr make make install 

    安裝apr-iconv:

    tar zxvf apr-iconv-1.2.1.tar.gz cd apr-iconv-1.2.1 ./configure --prefix=/usr/local/apr-iconv --with-apr=/usr/local/apr make make install 

    安裝apr-util:

    tar zxvf apr-util-1.5.3.tar.gz cd apr-util-1.5.3 ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr --with-apr-iconv=/usr/local/apr-iconv/bin/apriconv make   make install 

    安裝tomcat-native:首先到tomcat/bin目錄下,找到對(duì)應(yīng)的tar文件.

    tar zxvf tomcat-native.tar.gz cd tomcat-native-1.1.27-src/jni/native/ ./configure --with-apr=/usr/local/apr --with-java-home=/usr/lib/jdk1.6.0_45 make make install 

    安裝完成之后 會(huì)出現(xiàn)如下提示信息

    Libraries have been installed in: /usr/local/apr/lib 

    添加環(huán)境變量: vi /etc/profile在文件末尾處添加下面的變量

    export LD_LIBRARY_PATH=/usr/local/apr/lib 

    然后執(zhí)行下面命令,使環(huán)境變量即時(shí)生效

    source /etc/profile 

    以下為完整安裝腳本:

    #setup apr tar zxvf apr-1.5.1.tar.gz cd apr-1.5.1 ./configure --prefix=/usr/local/apr make && make install cd ../ #setup apr-iconv tar zxvf apr-iconv-1.2.1.tar.gz cd apr-iconv-1.2.1/ ./configure --prefix=/usr/local/apr-iconv --with-apr=/usr/local/apr make && make install cd ../ #setup apr-util tar zxvf apr-util-1.5.3.tar.gz cd apr-util-1.5.3 ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr --with-apr-iconv=/usr/local/apr-iconv/bin/apriconv make && make install #setup tomcat-native cd /app/apache-tomcat-7.0.42/bin tar zxvf tomcat-native.tar.gz cd tomcat-native-1.1.27-src/jni/native ./configure --with-apr=/usr/local/apr --with-java-home=/usr/lib/jdk1.6.0_45 make && make install cd / #LD_LIBRARY_PATH echo -e 'export LD_LIBRARY_PATH=/usr/local/apr/lib' >> /etc/profile export LD_LIBRARY_PATH=/usr/local/apr/lib source /etc/profile 

    3. 配置Tomcat

    修改tomcat配置conf/server.xml:

    <!--The connectors can use a shared executor, you can define one or more named thread pools-->     <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"         maxThreads="800" minSpareThreads="400"/>        <!-- A "Connector" represents an endpoint by which requests are received          and responses are returned. Documentation at :          Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)          Java AJP  Connector: /docs/config/ajp.html          APR (HTTP/AJP) Connector: /docs/apr.html          Define a non-SSL HTTP/1.1 Connector on port 8080     -->     <Connector port="80" executor="tomcatThreadPool" protocol="org.apache.coyote.http11.Http11AprProtocol"                connectionTimeout="20000"                redirectPort="8443" enableLookups="false" acceptCount="1000"/> 

    修改為Http11AprProtocol 協(xié)議.

    之后啟動(dòng)tomcat即可.

    遇到問(wèn)題:

    SEVERE: Failed to initialize the SSLEngine. org.apache.tomcat.jni.Error: 70023: This function has not been implemented on this platform 

    請(qǐng)關(guān)閉SSL偵聽(tīng),除非你有使用SSL,修改conf/server.xml

    <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="off" /> 

    壓測(cè)結(jié)果:

    webbench -c 4000 -t 30 http://10.103.10.140/workbench/index.jsp Webbench - Simple Web Benchmark 1.5 Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.  Benchmarking: GET http://10.103.10.140/workbench/index.jsp 4000 clients, running 30 sec.  Speed=484340 pages/min, 2441573 bytes/sec. Requests: 242170 susceed, 0 failed. 

    參考:

    http://www.chepoo.com/tomcat-performance-three-times-is-not-a-dream.html

    http://rhomobi.com/topics/36

    https://gitsea.com/2013/07/02/tomcat-%E5%B9%B6%E5%8F%91%E4%BC%98%E5%8C%96/

    http://pengranxiang.iteye.com/blog/1128905

    http://tomcat.apache.org/tomcat-7.0-doc/apr.html#Linux

    http://www.cnblogs.com/wanghaosoft/archive/2013/02/04/2892099.html

    posted @ 2015-03-16 18:59 小馬歌 閱讀(342) | 評(píng)論 (0)編輯 收藏
     

    本文轉(zhuǎn)載自xum2008的博客,主要介紹13款現(xiàn)有的開(kāi)源搜索引擎,你可以將它們用在你的項(xiàng)目中以實(shí)現(xiàn)檢索功能。 


    1.  Lucene 

    Lucene的開(kāi)發(fā)語(yǔ)言是Java,也是Java家族中最為出名的一個(gè)開(kāi)源搜索引擎,在Java世界中已經(jīng)是標(biāo)準(zhǔn)的全文檢索程序,它提供了完整的查詢引擎和索引引擎,沒(méi)有中文分詞引擎,需要自己去實(shí)現(xiàn),因此用Lucene去做一個(gè)搜素引擎需要自己去架構(gòu).另外它不支持實(shí)時(shí)搜索,但linkedin和twitter有分別對(duì)Lucene改進(jìn)的實(shí)時(shí)搜素. 其中Lucene有一個(gè)C++移植版本叫CLucene,CLucene因?yàn)槭褂肅++編寫(xiě),所以理論上要比lucene快. 

    官方主頁(yè):http://lucene.apache.org/ 

    CLucene官方主頁(yè):http://sourceforge.net/projects/clucene/ 

    2.  Sphinx 

    Sphinx是一個(gè)用C++語(yǔ)言寫(xiě)的開(kāi)源搜索引擎,也是現(xiàn)在比較主流的搜索引擎之一,在建立索引的事件方面比Lucene快50%,但是索引文件比Lucene要大一倍,因此Sphinx在索引的建立方面是空間換取事件的策略,在檢索速度上,和lucene相差不大,但檢索精準(zhǔn)度方面Lucene要優(yōu)于Sphinx,另外在加入中文分詞引擎難度方面,Lucene要優(yōu)于Sphinx.其中Sphinx支持實(shí)時(shí)搜索,使用起來(lái)比較簡(jiǎn)單方便. 

    官方主頁(yè):http://sphinxsearch.com/about/sphinx/ 

    3.  Xapian 

    Xapian是一個(gè)用C++編寫(xiě)的全文檢索程序,它的api和檢索原理和lucene在很多方面都很相似,算是填補(bǔ)了lucene在C++中的一個(gè)空缺. 

    官方主頁(yè):http://xapian.org/ 

    4.  Nutch 

    Nutch是一個(gè)用java實(shí)現(xiàn)的開(kāi)源的web搜索引擎,包括爬蟲(chóng)crawler,索引引擎,查詢引擎. 其中Nutch是基于Lucene的,Lucene為Nutch提供了文本索引和搜索的API. 

    對(duì)于應(yīng)該使用Lucene還是使用Nutch,應(yīng)該是如果你不需要抓取數(shù)據(jù)的話,應(yīng)該使用Lucene,最常見(jiàn)的應(yīng)用是:你有數(shù)據(jù)源,需要為這些數(shù)據(jù)提供一個(gè)搜索頁(yè)面,在這種情況下,最好的方式是直接從數(shù)據(jù)庫(kù)中取出數(shù)據(jù),并用Lucene API建立索引. 

    官方主頁(yè):http://nutch.apache.org/ 

    5.  DataparkSearch 

    DataparkSearch是一個(gè)用C語(yǔ)言實(shí)現(xiàn)的開(kāi)源的搜索引擎. 其中網(wǎng)頁(yè)排序是采用神經(jīng)網(wǎng)絡(luò)模型.  其中支持HTTP,HTTPS,F(xiàn)TP,NNTP等下載網(wǎng)頁(yè).包括索引引擎,檢索引擎和中文分詞引擎(這個(gè)也是唯一的一個(gè)開(kāi)源的搜索引擎里有中文分詞引擎).能個(gè)性化定制搜索結(jié)果,擁有完整的日志記錄. 

    官方主頁(yè):http://www.dataparksearch.org/ 

    6.  Zettair 

    Zettair是根據(jù)Justin Zobel的研究成果為基礎(chǔ)的全文檢索實(shí)驗(yàn)系統(tǒng).它是用C語(yǔ)言實(shí)現(xiàn)的. 其中Justin Zobel在全文檢索領(lǐng)域很有名氣,是業(yè)界第一個(gè)系統(tǒng)提出倒排序索引差分壓縮算法的人,倒排列表的壓縮大大提高了檢索和加載的性能,同時(shí)空間膨脹率也縮小到相當(dāng)優(yōu)秀的水平. 由于Zettair是源于學(xué)術(shù)界,代碼是由RMIT University的搜索引擎組織寫(xiě)的,因此它的代碼簡(jiǎn)潔精煉,算法高效,是學(xué)習(xí)倒排索引經(jīng)典算法的非常好的實(shí)例. 其中支持linux,windows,mac os等系統(tǒng). 

    官方主頁(yè):http://www.seg.rmit.edu.au/zettair/about.html 

    7.  Indri 

    Indri是一個(gè)用C語(yǔ)言和C++語(yǔ)言寫(xiě)的全文檢索引擎系統(tǒng),是由University of Massachusetts和Carnegie Mellon University合作推出的一個(gè)開(kāi)源項(xiàng)目. 特點(diǎn)是跨平臺(tái),API接口支持Java,PHP,C++. 

    官方主頁(yè):http://www.lemurproject.org/indri/ 

    8.  Terrier 

    Terrier是由School of Computing Science,Universityof Glasgow用java開(kāi)發(fā)的一個(gè)全文檢索系統(tǒng). 

    官方主頁(yè):http://terrier.org/ 

    9.  Galago 

    Galago是一個(gè)用java語(yǔ)言寫(xiě)的關(guān)于文本搜索的工具集. 其中包括索引引擎和查詢引擎,還包括一個(gè)叫TupleFlow的分布式計(jì)算框架(和google的MapReduce很像).這個(gè)檢索系統(tǒng)支持很多Indri查詢語(yǔ)言. 

    官方主頁(yè):http://www.galagosearch.org/ 

    10.  Zebra 

    Zebra是一個(gè)用C語(yǔ)言實(shí)現(xiàn)的檢索程序,特點(diǎn)是對(duì)大數(shù)據(jù)的支持,支持EMAIL,XML,MARC等格式的數(shù)據(jù). 

    官方主頁(yè):https://www.indexdata.com/zebra 

    11.  Solr 

    Solr是一個(gè)用java開(kāi)發(fā)的獨(dú)立的企業(yè)級(jí)搜索應(yīng)用服務(wù)器,它提供了類似于Web-service的API接口,它是基于Lucene的全文檢索服務(wù)器,也算是Lucene的一個(gè)變種,很多一線互聯(lián)網(wǎng)公司都在使用Solr,也算是一種成熟的解決方案. 

    官方主頁(yè):http://lucene.apache.org/solr/ 

    12.  Elasticsearch 

    Elasticsearch是一個(gè)采用java語(yǔ)言開(kāi)發(fā)的,基于Lucene構(gòu)造的開(kāi)源,分布式的搜索引擎. 設(shè)計(jì)用于云計(jì)算中,能夠達(dá)到實(shí)時(shí)搜索,穩(wěn)定可靠. Elasticsearch的數(shù)據(jù)模型是JSON. 

    官方主頁(yè):http://www.elasticsearch.org/ 

    13.  Whoosh 

    Whoosh是一個(gè)用純python寫(xiě)的開(kāi)源搜索引擎. 

    官方主頁(yè):https://bitbucket.org/mchaput/whoosh/wiki/Home  

    1. 增加一個(gè),SolrCloud是基于Solr和Zookeeper的分布式搜索方案,是正在開(kāi)發(fā)中的Solr4.0的核心組件之一,它的主要思想是使用Zookeeper作為集群的配置信息中心。它有幾個(gè)特色功能:1)集中式的配置信息 2)自動(dòng)容錯(cuò) 3)近實(shí)時(shí)搜索 4)查詢時(shí)自動(dòng)負(fù)載均衡
    posted @ 2015-03-16 18:37 小馬歌 閱讀(377) | 評(píng)論 (0)編輯 收藏
     
    from:http://songwie.com/articlelist/21

    mysql數(shù)據(jù)庫(kù)切分

    前言

    通過(guò)MySQLReplication功能所實(shí)現(xiàn)的擴(kuò)展總是會(huì)受到數(shù)據(jù)庫(kù)大小的限制,一旦數(shù)據(jù)庫(kù)過(guò)于龐大,尤其是當(dāng)寫(xiě)入過(guò)于頻繁,很難由一臺(tái)主機(jī)支撐的時(shí)候,我們還是會(huì)面臨到擴(kuò)展瓶頸。這時(shí)候,我們就必須許找其他技術(shù)手段來(lái)解決這個(gè)瓶頸,那就是我們這一章所要介紹惡的數(shù)據(jù)切分技術(shù)。

     

    何謂數(shù)據(jù)切分

    可能很多讀者朋友在網(wǎng)上或者雜志上面都已經(jīng)多次見(jiàn)到關(guān)于數(shù)據(jù)切分的相關(guān)文章了,只不過(guò)在有些文章中稱之為數(shù)據(jù)的Sharding。其實(shí)不管是稱之為數(shù)據(jù)的Sharding還是數(shù)據(jù)的切分,其概念都是一樣的。簡(jiǎn)單來(lái)說(shuō),就是指通過(guò)某種特定的條件,將我們存放在同一個(gè)數(shù)據(jù)庫(kù)中的數(shù)據(jù)分散存放到多個(gè)數(shù)據(jù)庫(kù)(主機(jī))上面,以達(dá)到分散單臺(tái)設(shè)備負(fù)載的效果。數(shù)據(jù)的切分同時(shí)還可以提高系統(tǒng)的總體可用性,因?yàn)閱闻_(tái)設(shè)備Crash之后,只有總體數(shù)據(jù)的某部分不可用,而不是所有的數(shù)據(jù)。

    數(shù)據(jù)的切分(Sharding)根據(jù)其切分規(guī)則的類型,可以分為兩種切分模式。一種是按照不同的表(或者Schema)來(lái)切分到不同的數(shù)據(jù)庫(kù)(主機(jī))之上,這種切可以稱之為數(shù)據(jù)的垂直(縱向)切分;另外一種則是根據(jù)表中的數(shù)據(jù)的邏輯關(guān)系,將同一個(gè)表中的數(shù)據(jù)按照某種條件拆分到多臺(tái)數(shù)據(jù)庫(kù)(主機(jī))上面,這種切分稱之為數(shù)據(jù)的水平(橫向)切分。

    垂直切分的最大特點(diǎn)就是規(guī)則簡(jiǎn)單,實(shí)施也更為方便,尤其適合各業(yè)務(wù)之間的耦合度非常低,相互影響很小,業(yè)務(wù)邏輯非常清晰的系統(tǒng)。在這種系統(tǒng)中,可以很容易做到將不同業(yè)務(wù)模塊所使用的表分拆到不同的數(shù)據(jù)庫(kù)中。根據(jù)不同的表來(lái)進(jìn)行拆分,對(duì)應(yīng)用程序的影響也更小,拆分規(guī)則也會(huì)比較簡(jiǎn)單清晰。

    水平切分于垂直切分相比,相對(duì)來(lái)說(shuō)稍微復(fù)雜一些。因?yàn)橐獙⑼粋€(gè)表中的不同數(shù)據(jù)拆分到不同的數(shù)據(jù)庫(kù)中,對(duì)于應(yīng)用程序來(lái)說(shuō),拆分規(guī)則本身就較根據(jù)表名來(lái)拆分更為復(fù)雜,后期的數(shù)據(jù)維護(hù)也會(huì)更為復(fù)雜一些。

    當(dāng)我們某個(gè)(或者某些)表的數(shù)據(jù)量和訪問(wèn)量特別的大,通過(guò)垂直切分將其放在獨(dú)立的設(shè)備上后仍然無(wú)法滿足性能要求,這時(shí)候我們就必須將垂直切分和水平切分相結(jié)合,先垂直切分,然后再水平切分,才能解決這種超大型表的性能問(wèn)題。

    下面我們就針對(duì)垂直、水平以及組合切分這三種數(shù)據(jù)切分方式的架構(gòu)實(shí)現(xiàn)及切分后數(shù)據(jù)的整合進(jìn)行相應(yīng)的分析。

     

    數(shù)據(jù)的垂直切分

    我們先來(lái)看一下,數(shù)據(jù)的垂直切分到底是如何一個(gè)切分法的。數(shù)據(jù)的垂直切分,也可以稱之為縱向切分。將數(shù)據(jù)庫(kù)想象成為由很多個(gè)一大塊一大塊的“數(shù)據(jù)塊”(表)組成,我們垂直的將這些“數(shù)據(jù)塊”切開(kāi),然后將他們分散到多臺(tái)數(shù)據(jù)庫(kù)主機(jī)上面。這樣的切分方法就是一個(gè)垂直(縱向)的數(shù)據(jù)切分。

    一個(gè)架構(gòu)設(shè)計(jì)較好的應(yīng)用系統(tǒng),其總體功能肯定是由很多個(gè)功能模塊所組成的,而每一個(gè)功能模塊所需要的數(shù)據(jù)對(duì)應(yīng)到數(shù)據(jù)庫(kù)中就是一個(gè)或者多個(gè)表。而在架構(gòu)設(shè)計(jì)中,各個(gè)功能模塊相互之間的交互點(diǎn)越統(tǒng)一越少,系統(tǒng)的耦合度就越低,系統(tǒng)各個(gè)模塊的維護(hù)性以及擴(kuò)展性也就越好。這樣的系統(tǒng),實(shí)現(xiàn)數(shù)據(jù)的垂直切分也就越容易。

    當(dāng)我們的功能模塊越清晰,耦合度越低,數(shù)據(jù)垂直切分的規(guī)則定義也就越容易。完全可以根據(jù)功能模塊來(lái)進(jìn)行數(shù)據(jù)的切分,不同功能模塊的數(shù)據(jù)存放于不同的數(shù)據(jù)庫(kù)主機(jī)中,可以很容易就避免掉跨數(shù)據(jù)庫(kù)的Join存在,同時(shí)系統(tǒng)架構(gòu)也非常的清晰。

    當(dāng)然,很難有系統(tǒng)能夠做到所有功能模塊所使用的表完全獨(dú)立,完全不需要訪問(wèn)對(duì)方的表或者需要兩個(gè)模塊的表進(jìn)行Join操作。這種情況下,我們就必須根據(jù)實(shí)際的應(yīng)用場(chǎng)景進(jìn)行評(píng)估權(quán)衡。決定是遷就應(yīng)用程序?qū)⑿枰狫oin的表的相關(guān)某快都存放在同一個(gè)數(shù)據(jù)庫(kù)中,還是讓?xiě)?yīng)用程序做更多的事情,也就是程序完全通過(guò)模塊接口取得不同數(shù)據(jù)庫(kù)中的數(shù)據(jù),然后在程序中完成Join操作。

    一般來(lái)說(shuō),如果是一個(gè)負(fù)載相對(duì)不是很大的系統(tǒng),而且表關(guān)聯(lián)又非常的頻繁,那可能數(shù)據(jù)庫(kù)讓步,將幾個(gè)相關(guān)模塊合并在一起減少應(yīng)用程序的工作的方案可以減少較多的工作量,是一個(gè)可行的方案。

    當(dāng)然,通過(guò)數(shù)據(jù)庫(kù)的讓步,讓多個(gè)模塊集中共用數(shù)據(jù)源,實(shí)際上也是簡(jiǎn)介的默許了各模塊架構(gòu)耦合度增大的發(fā)展,可能會(huì)讓以后的架構(gòu)越來(lái)越惡化。尤其是當(dāng)發(fā)展到一定階段之后,發(fā)現(xiàn)數(shù)據(jù)庫(kù)實(shí)在無(wú)法承擔(dān)這些表所帶來(lái)的壓力,不得不面臨再次切分的時(shí)候,所帶來(lái)的架構(gòu)改造成本可能會(huì)遠(yuǎn)遠(yuǎn)大于最初的時(shí)候。

    所以,在數(shù)據(jù)庫(kù)進(jìn)行垂直切分的時(shí)候,如何切分,切分到什么樣的程度,是一個(gè)比較考驗(yàn)人的難題。只能在實(shí)際的應(yīng)用場(chǎng)景中通過(guò)平衡各方面的成本和收益,才能分析出一個(gè)真正適合自己的拆分方案。

    比如在本書(shū)所使用示例系統(tǒng)的example數(shù)據(jù)庫(kù),我們簡(jiǎn)單的分析一下,然后再設(shè)計(jì)一個(gè)簡(jiǎn)單的切分規(guī)則,進(jìn)行一次垂直垂直拆分。

    系統(tǒng)功能可以基本分為四個(gè)功能模塊:用戶,群組消息,相冊(cè)以及事件,分別對(duì)應(yīng)為如下這些表:

    1. 用戶模塊表:user,user_profile,user_group,user_photo_album

    2. 群組討論表:groups,group_message,group_message_content,top_message

    3. 相冊(cè)相關(guān)表:photo,photo_album,photo_album_relation,photo_comment

    4. 事件信息表:event

    初略一看,沒(méi)有哪一個(gè)模塊可以脫離其他模塊獨(dú)立存在,模塊與模塊之間都存在著關(guān)系,莫非無(wú)法切分?

    當(dāng)然不是,我們?cè)偕晕⑸钊敕治鲆幌拢梢园l(fā)現(xiàn),雖然各個(gè)模塊所使用的表之間都有關(guān)聯(lián),但是關(guān)聯(lián)關(guān)系還算比較清晰,也比較簡(jiǎn)單。

    ◆群組討論模塊和用戶模塊之間主要存在通過(guò)用戶或者是群組關(guān)系來(lái)進(jìn)行關(guān)聯(lián)。一般關(guān)聯(lián)的時(shí)候都會(huì)是通過(guò)用戶的id或者nick_name以及group的id來(lái)進(jìn)行關(guān)聯(lián),通過(guò)模塊之間的接口實(shí)現(xiàn)不會(huì)帶來(lái)太多麻煩;

    ◆相冊(cè)模塊僅僅與用戶模塊存在通過(guò)用戶的關(guān)聯(lián)。這兩個(gè)模塊之間的關(guān)聯(lián)基本就有通過(guò)用戶id關(guān)聯(lián)的內(nèi)容,簡(jiǎn)單清晰,接口明確;

    ◆ 事件模塊與各個(gè)模塊可能都有關(guān)聯(lián),但是都只關(guān)注其各個(gè)模塊中對(duì)象的ID信息,同樣可以做到很容易分拆。

    所以,我們第一步可以將數(shù)據(jù)庫(kù)按照功能模塊相關(guān)的表進(jìn)行一次垂直拆分,每個(gè)模塊所涉及的表單獨(dú)到一個(gè)數(shù)據(jù)庫(kù)中,模塊與模塊之間的表關(guān)聯(lián)都在應(yīng)用系統(tǒng)端通過(guò)藉口來(lái)處理。如下圖所示:

    通過(guò)這樣的垂直切分之后,之前只能通過(guò)一個(gè)數(shù)據(jù)庫(kù)來(lái)提供的服務(wù),就被分拆成四個(gè)數(shù)據(jù)庫(kù)來(lái)提供服務(wù),服務(wù)能力自然是增加幾倍了。

    垂直切分的優(yōu)點(diǎn)

    ◆ 數(shù)據(jù)庫(kù)的拆分簡(jiǎn)單明了,拆分規(guī)則明確;

    ◆ 應(yīng)用程序模塊清晰明確,整合容易;

    ◆ 數(shù)據(jù)維護(hù)方便易行,容易定位;

    垂直切分的缺點(diǎn)

    ◆ 部分表關(guān)聯(lián)無(wú)法在數(shù)據(jù)庫(kù)級(jí)別完成,需要在程序中完成;

    ◆ 對(duì)于訪問(wèn)極其頻繁且數(shù)據(jù)量超大的表仍然存在性能平靜,不一定能滿足要求;

    ◆ 事務(wù)處理相對(duì)更為復(fù)雜;

    ◆ 切分達(dá)到一定程度之后,擴(kuò)展性會(huì)遇到限制;

    ◆ 過(guò)讀切分可能會(huì)帶來(lái)系統(tǒng)過(guò)渡復(fù)雜而難以維護(hù)。

    針對(duì)于垂直切分可能遇到數(shù)據(jù)切分及事務(wù)問(wèn)題,在數(shù)據(jù)庫(kù)層面實(shí)在是很難找到一個(gè)較好的處理方案。實(shí)際應(yīng)用案例中,數(shù)據(jù)庫(kù)的垂直切分大多是與應(yīng)用系統(tǒng)的模塊相對(duì)應(yīng),同一個(gè)模塊的數(shù)據(jù)源存放于同一個(gè)數(shù)據(jù)庫(kù)中,可以解決模塊內(nèi)部的數(shù)據(jù)關(guān)聯(lián)問(wèn)題。而模塊與模塊之間,則通過(guò)應(yīng)用程序以服務(wù)接口方式來(lái)相互提供所需要的數(shù)據(jù)。雖然這樣做在數(shù)據(jù)庫(kù)的總體操作次數(shù)方面確實(shí)會(huì)有所增加,但是在系統(tǒng)整體擴(kuò)展性以及架構(gòu)模塊化方面,都是有益的。可能在某些操作的單次響應(yīng)時(shí)間會(huì)稍有增加,但是系統(tǒng)的整體性能很可能反而會(huì)有一定的提升。而擴(kuò)展瓶頸問(wèn)題,就只能依靠下一節(jié)將要介紹的數(shù)據(jù)水平切分架構(gòu)來(lái)解決了。

     

    數(shù)據(jù)的水平切分

    上面一節(jié)分析介紹了數(shù)據(jù)的垂直切分,這一節(jié)再分析一下數(shù)據(jù)的水平切分。數(shù)據(jù)的垂直切分基本上可以簡(jiǎn)單的理解為按照表按照模塊來(lái)切分?jǐn)?shù)據(jù),而水平切分就不再是按照表或者是功能模塊來(lái)切分了。一般來(lái)說(shuō),簡(jiǎn)單的水平切分主要是將某個(gè)訪問(wèn)極其平凡的表再按照某個(gè)字段的某種規(guī)則來(lái)分散到多個(gè)表之中,每個(gè)表中包含一部分?jǐn)?shù)據(jù)。

    簡(jiǎn)單來(lái)說(shuō),我們可以將數(shù)據(jù)的水平切分理解為是按照數(shù)據(jù)行的切分,就是將表中的某些行切分到一個(gè)數(shù)據(jù)庫(kù),而另外的某些行又切分到其他的數(shù)據(jù)庫(kù)中。當(dāng)然,為了能夠比較容易的判定各行數(shù)據(jù)被切分到哪個(gè)數(shù)據(jù)庫(kù)中了,切分總是都需要按照某種特定的規(guī)則來(lái)進(jìn)行的。如根據(jù)某個(gè)數(shù)字類型字段基于特定數(shù)目取模,某個(gè)時(shí)間類型字段的范圍,或者是某個(gè)字符類型字段的hash值。如果整個(gè)系統(tǒng)中大部分核心表都可以通過(guò)某個(gè)字段來(lái)進(jìn)行關(guān)聯(lián),那這個(gè)字段自然是一個(gè)進(jìn)行水平分區(qū)的上上之選了,當(dāng)然,非常特殊無(wú)法使用就只能另選其他了。

    一般來(lái)說(shuō),像現(xiàn)在互聯(lián)網(wǎng)非常火爆的Web2.0類型的網(wǎng)站,基本上大部分?jǐn)?shù)據(jù)都能夠通過(guò)會(huì)員用戶信息關(guān)聯(lián)上,可能很多核心表都非常適合通過(guò)會(huì)員ID來(lái)進(jìn)行數(shù)據(jù)的水平切分。而像論壇社區(qū)討論系統(tǒng),就更容易切分了,非常容易按照論壇編號(hào)來(lái)進(jìn)行數(shù)據(jù)的水平切分。切分之后基本上不會(huì)出現(xiàn)各個(gè)庫(kù)之間的交互。

    如我們的示例系統(tǒng),所有數(shù)據(jù)都是和用戶關(guān)聯(lián)的,那么我們就可以根據(jù)用戶來(lái)進(jìn)行水平拆分,將不同用戶的數(shù)據(jù)切分到不同的數(shù)據(jù)庫(kù)中。當(dāng)然,唯一有點(diǎn)區(qū)別的是用戶模塊中的groups表和用戶沒(méi)有直接關(guān)系,所以groups不能根據(jù)用戶來(lái)進(jìn)行水平拆分。對(duì)于這種特殊情況下的表,我們完全可以獨(dú)立出來(lái),單獨(dú)放在一個(gè)獨(dú)立的數(shù)據(jù)庫(kù)中。其實(shí)這個(gè)做法可以說(shuō)是利用了前面一節(jié)所介紹的“數(shù)據(jù)的垂直切分”方法,我將在下一節(jié)中更為詳細(xì)的介紹這種垂直切分與水平切分同時(shí)使用的聯(lián)合切分方法。

    所以,對(duì)于我們的示例數(shù)據(jù)庫(kù)來(lái)說(shuō),大部分的表都可以根據(jù)用戶ID來(lái)進(jìn)行水平的切分。不同用戶相關(guān)的數(shù)據(jù)進(jìn)行切分之后存放在不同的數(shù)據(jù)庫(kù)中。如將所有用戶ID通過(guò)2取模然后分別存放于兩個(gè)不同的數(shù)據(jù)庫(kù)中。每個(gè)和用戶ID關(guān)聯(lián)上的表都可以這樣切分。這樣,基本上每個(gè)用戶相關(guān)的數(shù)據(jù),都在同一個(gè)數(shù)據(jù)庫(kù)中,即使是需要關(guān)聯(lián),也可以非常簡(jiǎn)單的關(guān)聯(lián)上。

    我們可以通過(guò)下圖來(lái)更為直觀的展示水平切分相關(guān)信息:水平切分的優(yōu)點(diǎn)

    ◆ 表關(guān)聯(lián)基本能夠在數(shù)據(jù)庫(kù)端全部完成;

    ◆ 不會(huì)存在某些超大型數(shù)據(jù)量和高負(fù)載的表遇到瓶頸的問(wèn)題;

    ◆ 應(yīng)用程序端整體架構(gòu)改動(dòng)相對(duì)較少;

    ◆ 事務(wù)處理相對(duì)簡(jiǎn)單;

    ◆ 只要切分規(guī)則能夠定義好,基本上較難遇到擴(kuò)展性限制;

    水平切分的缺點(diǎn)

    ◆ 切分規(guī)則相對(duì)更為復(fù)雜,很難抽象出一個(gè)能夠滿足整個(gè)數(shù)據(jù)庫(kù)的切分規(guī)則;

    ◆ 后期數(shù)據(jù)的維護(hù)難度有所增加,人為手工定位數(shù)據(jù)更困難;

    ◆ 應(yīng)用系統(tǒng)各模塊耦合度較高,可能會(huì)對(duì)后面數(shù)據(jù)的遷移拆分造成一定的困難。

     

    垂直與水平切分的聯(lián)合使用

    上面兩節(jié)內(nèi)容中,我們分別,了解了“垂直”和“水平”這兩種切分方式的實(shí)現(xiàn)以及切分之后的架構(gòu)信息,同時(shí)也分析了兩種架構(gòu)各自的優(yōu)缺點(diǎn)。但是在實(shí)際的應(yīng)用場(chǎng)景中,除了那些負(fù)載并不是太大,業(yè)務(wù)邏輯也相對(duì)較簡(jiǎn)單的系統(tǒng)可以通過(guò)上面兩種切分方法之一來(lái)解決擴(kuò)展性問(wèn)題之外,恐怕其他大部分業(yè)務(wù)邏輯稍微復(fù)雜一點(diǎn),系統(tǒng)負(fù)載大一些的系統(tǒng),都無(wú)法通過(guò)上面任何一種數(shù)據(jù)的切分方法來(lái)實(shí)現(xiàn)較好的擴(kuò)展性,而需要將上述兩種切分方法結(jié)合使用,不同的場(chǎng)景使用不同的切分方法。

    在這一節(jié)中,我將結(jié)合垂直切分和水平切分各自的優(yōu)缺點(diǎn),進(jìn)一步完善我們的整體架構(gòu),讓系統(tǒng)的擴(kuò)展性進(jìn)一步提高。

    一般來(lái)說(shuō),我們數(shù)據(jù)庫(kù)中的所有表很難通過(guò)某一個(gè)(或少數(shù)幾個(gè))字段全部關(guān)聯(lián)起來(lái),所以很難簡(jiǎn)單的僅僅通過(guò)數(shù)據(jù)的水平切分來(lái)解決所有問(wèn)題。而垂直切分也只能解決部分問(wèn)題,對(duì)于那些負(fù)載非常高的系統(tǒng),即使僅僅只是單個(gè)表都無(wú)法通過(guò)單臺(tái)數(shù)據(jù)庫(kù)主機(jī)來(lái)承擔(dān)其負(fù)載。我們必須結(jié)合“垂直”和“水平”兩種切分方式同時(shí)使用,充分利用兩者的優(yōu)點(diǎn),避開(kāi)其缺點(diǎn)。

    每一個(gè)應(yīng)用系統(tǒng)的負(fù)載都是一步一步增長(zhǎng)上來(lái)的,在開(kāi)始遇到性能瓶頸的時(shí)候,大多數(shù)架構(gòu)師和DBA都會(huì)選擇先進(jìn)行數(shù)據(jù)的垂直拆分,因?yàn)檫@樣的成本最先,最符合這個(gè)時(shí)期所追求的最大投入產(chǎn)出比。然而,隨著業(yè)務(wù)的不斷擴(kuò)張,系統(tǒng)負(fù)載的持續(xù)增長(zhǎng),在系統(tǒng)穩(wěn)定一段時(shí)期之后,經(jīng)過(guò)了垂直拆分之后的數(shù)據(jù)庫(kù)集群可能又再一次不堪重負(fù),遇到了性能瓶頸。

    這時(shí)候我們?cè)撊绾尉駬瘢渴窃俅芜M(jìn)一步細(xì)分模塊呢,還是尋求其他的辦法來(lái)解決?如果我們?cè)僖淮蜗褡铋_(kāi)始那樣繼續(xù)細(xì)分模塊,進(jìn)行數(shù)據(jù)的垂直切分,那我們可能在不久的將來(lái),又會(huì)遇到現(xiàn)在所面對(duì)的同樣的問(wèn)題。而且隨著模塊的不斷的細(xì)化,應(yīng)用系統(tǒng)的架構(gòu)也會(huì)越來(lái)越復(fù)雜,整個(gè)系統(tǒng)很可能會(huì)出現(xiàn)失控的局面。

    這時(shí)候我們就必須要通過(guò)數(shù)據(jù)的水平切分的優(yōu)勢(shì),來(lái)解決這里所遇到的問(wèn)題。而且,我們完全不必要在使用數(shù)據(jù)水平切分的時(shí)候,推倒之前進(jìn)行數(shù)據(jù)垂直切分的成果,而是在其基礎(chǔ)上利用水平切分的優(yōu)勢(shì)來(lái)避開(kāi)垂直切分的弊端,解決系統(tǒng)復(fù)雜性不斷擴(kuò)大的問(wèn)題。而水平拆分的弊端(規(guī)則難以統(tǒng)一)也已經(jīng)被之前的垂直切分解決掉了,讓水平拆分可以進(jìn)行的得心應(yīng)手。

    對(duì)于我們的示例數(shù)據(jù)庫(kù),假設(shè)在最開(kāi)始,我們進(jìn)行了數(shù)據(jù)的垂直切分,然而隨著業(yè)務(wù)的不斷增長(zhǎng),數(shù)據(jù)庫(kù)系統(tǒng)遇到了瓶頸,我們選擇重構(gòu)數(shù)據(jù)庫(kù)集群的架構(gòu)。如何重構(gòu)?考慮到之前已經(jīng)做好了數(shù)據(jù)的垂直切分,而且模塊結(jié)構(gòu)清晰明確。而業(yè)務(wù)增長(zhǎng)的勢(shì)頭越來(lái)越猛,即使現(xiàn)在進(jìn)一步再次拆分模塊,也堅(jiān)持不了太久。我們選擇了在垂直切分的基礎(chǔ)上再進(jìn)行水平拆分。

    在經(jīng)歷過(guò)垂直拆分后的各個(gè)數(shù)據(jù)庫(kù)集群中的每一個(gè)都只有一個(gè)功能模塊,而每個(gè)功能模塊中的所有表基本上都會(huì)與某個(gè)字段進(jìn)行關(guān)聯(lián)。如用戶模塊全部都可以通過(guò)用戶ID進(jìn)行切分,群組討論模塊則都通過(guò)群組ID來(lái)切分,相冊(cè)模塊則根據(jù)相冊(cè)ID來(lái)進(jìn)切分,最后的事件通知信息表考慮到數(shù)據(jù)的時(shí)限性(僅僅只會(huì)訪問(wèn)最近某個(gè)事件段的信息),則考慮按時(shí)間來(lái)切分。

    下圖展示了切分后的整個(gè)架構(gòu):

    實(shí)際上,在很多大型的應(yīng)用系統(tǒng)中,垂直切分和水平切這兩種數(shù)據(jù)的切分方法基本上都是并存的,而且經(jīng)常在不斷的交替進(jìn)行,以不斷的增加系統(tǒng)的擴(kuò)展能力。我們?cè)趹?yīng)對(duì)不同的應(yīng)用場(chǎng)景的時(shí)候,也需要充分考慮到這兩種切分方法各自的局限,以及各自的優(yōu)勢(shì),在不同的時(shí)期(負(fù)載壓力)使用不同的結(jié)合方式。

    聯(lián)合切分的優(yōu)點(diǎn)

    ◆ 可以充分利用垂直切分和水平切分各自的優(yōu)勢(shì)而避免各自的缺陷;

    ◆ 讓系統(tǒng)擴(kuò)展性得到最大化提升;

    聯(lián)合切分的缺點(diǎn)

    ◆ 數(shù)據(jù)庫(kù)系統(tǒng)架構(gòu)比較復(fù)雜,維護(hù)難度更大;

    ◆ 應(yīng)用程序架構(gòu)也相對(duì)更復(fù)雜;

     

    數(shù)據(jù)切分及整合方案

    通過(guò)前面的章節(jié),我們已經(jīng)很清楚了通過(guò)數(shù)據(jù)庫(kù)的數(shù)據(jù)切分可以極大的提高系統(tǒng)的擴(kuò)展性。但是,數(shù)據(jù)庫(kù)中的數(shù)據(jù)在經(jīng)過(guò)垂直和(或)水平切分被存放在不同的數(shù)據(jù)庫(kù)主機(jī)之后,應(yīng)用系統(tǒng)面臨的最大問(wèn)題就是如何來(lái)讓這些數(shù)據(jù)源得到較好的整合,可能這也是很多讀者朋友非常關(guān)心的一個(gè)問(wèn)題。這一節(jié)我們主要針對(duì)的內(nèi)容就是分析可以使用的各種可以幫助我們實(shí)現(xiàn)數(shù)據(jù)切分以及數(shù)據(jù)整合的整體解決方案。

    數(shù)據(jù)的整合很難依靠數(shù)據(jù)庫(kù)本身來(lái)達(dá)到這個(gè)效果,雖然MySQL存在Federated存儲(chǔ)引擎,可以解決部分類似的問(wèn)題,但是在實(shí)際應(yīng)用場(chǎng)景中卻很難較好的運(yùn)用。那我們?cè)撊绾蝸?lái)整合這些分散在各個(gè)MySQL主機(jī)上面的數(shù)據(jù)源呢?

    總的來(lái)說(shuō),存在兩種解決思路:

    1. 在每個(gè)應(yīng)用程序模塊中配置管理自己需要的一個(gè)(或者多個(gè))數(shù)據(jù)源,直接訪問(wèn)各個(gè)數(shù)據(jù)庫(kù),在模塊內(nèi)完成數(shù)據(jù)的整合;

    2. 通過(guò)中間代理層來(lái)統(tǒng)一管理所有的數(shù)據(jù)源,后端數(shù)據(jù)庫(kù)集群對(duì)前端應(yīng)用程序透明;

    可能90%以上的人在面對(duì)上面這兩種解決思路的時(shí)候都會(huì)傾向于選擇第二種,尤其是系統(tǒng)不斷變得龐大復(fù)雜的時(shí)候。確實(shí),這是一個(gè)非常正確的選擇,雖然短期內(nèi)需要付出的成本可能會(huì)相對(duì)更大一些,但是對(duì)整個(gè)系統(tǒng)的擴(kuò)展性來(lái)說(shuō),是非常有幫助的。

    所以,對(duì)于第一種解決思路我這里就不準(zhǔn)備過(guò)多的分析,下面我重點(diǎn)分析一下在第二種解決思路中的一些解決方案。

    ★ 自行開(kāi)發(fā)中間代理層

    在決定選擇通過(guò)數(shù)據(jù)庫(kù)的中間代理層來(lái)解決數(shù)據(jù)源整合的架構(gòu)方向之后,有不少公司(或者企業(yè))選擇了通過(guò)自行開(kāi)發(fā)符合自身應(yīng)用特定場(chǎng)景的代理層應(yīng)用程序。

    通過(guò)自行開(kāi)發(fā)中間代理層可以最大程度的應(yīng)對(duì)自身應(yīng)用的特定,最大化的定制很多個(gè)性化需求,在面對(duì)變化的時(shí)候也可以靈活的應(yīng)對(duì)。這應(yīng)該說(shuō)是自行開(kāi)發(fā)代理層最大的優(yōu)勢(shì)了。

    當(dāng)然,選擇自行開(kāi)發(fā),享受讓個(gè)性化定制最大化的樂(lè)趣的同時(shí),自然也需要投入更多的成本來(lái)進(jìn)行前期研發(fā)以及后期的持續(xù)升級(jí)改進(jìn)工作,而且本身的技術(shù)門(mén)檻可能也比簡(jiǎn)單的Web應(yīng)用要更高一些。所以,在決定選擇自行開(kāi)發(fā)之前,還是需要進(jìn)行比較全面的評(píng)估為好。

    由于自行開(kāi)發(fā)更多時(shí)候考慮的是如何更好的適應(yīng)自身應(yīng)用系統(tǒng),應(yīng)對(duì)自身的業(yè)務(wù)場(chǎng)景,所以這里也不好分析太多。后面我們主要分析一下當(dāng)前比較流行的幾種數(shù)據(jù)源整合解決方案。

    ★利用MySQLProxy實(shí)現(xiàn)數(shù)據(jù)切分及整合

    MySQLProxy是MySQL官方提供的一個(gè)數(shù)據(jù)庫(kù)代理層產(chǎn)品,和MySQLServer一樣,同樣是一個(gè)基于GPL開(kāi)源協(xié)議的開(kāi)源產(chǎn)品。可用來(lái)監(jiān)視、分析或者傳輸他們之間的通訊信息。他的靈活性允許你最大限度的使用它,目前具備的功能主要有連接路由,Query分析,Query過(guò)濾和修改,負(fù)載均衡,以及基本的HA機(jī)制等。

    實(shí)際上,MySQLProxy本身并不具有上述所有的這些功能,而是提供了實(shí)現(xiàn)上述功能的基礎(chǔ)。要實(shí)現(xiàn)這些功能,還需要通過(guò)我們自行編寫(xiě)LUA腳本來(lái)實(shí)現(xiàn)。

    MySQLProxy實(shí)際上是在客戶端請(qǐng)求與MySQLServer之間建立了一個(gè)連接池。所有客戶端請(qǐng)求都是發(fā)向MySQLProxy,然后經(jīng)由MySQLProxy進(jìn)行相應(yīng)的分析,判斷出是讀操作還是寫(xiě)操作,分發(fā)至對(duì)應(yīng)的MySQLServer上。對(duì)于多節(jié)點(diǎn)Slave集群,也可以起做到負(fù)載均衡的效果。以下是MySQLProxy的基本架構(gòu)圖:

    通過(guò)上面的架構(gòu)簡(jiǎn)圖,我們可以很清晰的看出MySQLProxy在實(shí)際應(yīng)用中所處的位置,以及能做的基本事情。關(guān)于MySQLProxy更為詳細(xì)的實(shí)施細(xì)則在MySQL官方文檔中有非常詳細(xì)的介紹和示例,感興趣的讀者朋友可以直接從MySQL官方網(wǎng)站免費(fèi)下載或者在線閱讀,我這里就不累述浪費(fèi)紙張了。

    ★利用Amoeba實(shí)現(xiàn)數(shù)據(jù)切分及整合

    Amoeba是一個(gè)基于Java開(kāi)發(fā)的,專注于解決分布式數(shù)據(jù)庫(kù)數(shù)據(jù)源整合Proxy程序的開(kāi)源框架,基于GPL3開(kāi)源協(xié)議。目前,Amoeba已經(jīng)具有Query路由,Query過(guò)濾,讀寫(xiě)分離,負(fù)載均衡以及HA機(jī)制等相關(guān)內(nèi)容。

    Amoeba 主要解決的以下幾個(gè)問(wèn)題:

    1. 數(shù)據(jù)切分后復(fù)雜數(shù)據(jù)源整合;

    2. 提供數(shù)據(jù)切分規(guī)則并降低數(shù)據(jù)切分規(guī)則給數(shù)據(jù)庫(kù)帶來(lái)的影響;

    3. 降低數(shù)據(jù)庫(kù)與客戶端的連接數(shù);

    4. 讀寫(xiě)分離路由;

    我們可以看出,Amoeba所做的事情,正好就是我們通過(guò)數(shù)據(jù)切分來(lái)提升數(shù)據(jù)庫(kù)的擴(kuò)展性所需要的。

    Amoeba并不是一個(gè)代理層的Proxy程序,而是一個(gè)開(kāi)發(fā)數(shù)據(jù)庫(kù)代理層Proxy程序的開(kāi)發(fā)框架,目前基于Amoeba所開(kāi)發(fā)的Proxy程序有AmoebaForMySQL和AmoebaForAladin兩個(gè)。

    AmoebaForMySQL主要是專門(mén)針對(duì)MySQL數(shù)據(jù)庫(kù)的解決方案,前端應(yīng)用程序請(qǐng)求的協(xié)議以及后端連接的數(shù)據(jù)源數(shù)據(jù)庫(kù)都必須是MySQL。對(duì)于客戶端的任何應(yīng)用程序來(lái)說(shuō),AmoebaForMySQL和一個(gè)MySQL數(shù)據(jù)庫(kù)沒(méi)有什么區(qū)別,任何使用MySQL協(xié)議的客戶端請(qǐng)求,都可以被AmoebaForMySQL解析并進(jìn)行相應(yīng)的處理。下如可以告訴我們AmoebaForMySQL的架構(gòu)信息(出自Amoeba開(kāi)發(fā)者博客):

    AmoebaForAladin則是一個(gè)適用更為廣泛,功能更為強(qiáng)大的Proxy程序。他可以同時(shí)連接不同數(shù)據(jù)庫(kù)的數(shù)據(jù)源為前端應(yīng)用程序提供服務(wù),但是僅僅接受符合MySQL協(xié)議的客戶端應(yīng)用程序請(qǐng)求。也就是說(shuō),只要前端應(yīng)用程序通過(guò)MySQL協(xié)議連接上來(lái)之后,AmoebaForAladin會(huì)自動(dòng)分析Query語(yǔ)句,根據(jù)Query語(yǔ)句中所請(qǐng)求的數(shù)據(jù)來(lái)自動(dòng)識(shí)別出該所Query的數(shù)據(jù)源是在什么類型數(shù)據(jù)庫(kù)的哪一個(gè)物理主機(jī)上面。下圖展示了AmoebaForAladin的架構(gòu)細(xì)節(jié)(出自Amoeba開(kāi)發(fā)者博客):

    咋一看,兩者好像完全一樣嘛。細(xì)看之后,才會(huì)發(fā)現(xiàn)兩者主要的區(qū)別僅在于通過(guò)MySQLProtocalAdapter處理之后,根據(jù)分析結(jié)果判斷出數(shù)據(jù)源數(shù)據(jù)庫(kù),然后選擇特定的JDBC驅(qū)動(dòng)和相應(yīng)協(xié)議連接后端數(shù)據(jù)庫(kù)。

    其實(shí)通過(guò)上面兩個(gè)架構(gòu)圖大家可能也已經(jīng)發(fā)現(xiàn)了Amoeba的特點(diǎn)了,他僅僅只是一個(gè)開(kāi)發(fā)框架,我們除了選擇他已經(jīng)提供的ForMySQL和ForAladin這兩款產(chǎn)品之外,還可以基于自身的需求進(jìn)行相應(yīng)的二次開(kāi)發(fā),得到更適應(yīng)我們自己應(yīng)用特點(diǎn)的Proxy程序。

    當(dāng)對(duì)于使用MySQL數(shù)據(jù)庫(kù)來(lái)說(shuō),不論是AmoebaForMySQL還是AmoebaForAladin都可以很好的使用。當(dāng)然,考慮到任何一個(gè)系統(tǒng)越是復(fù)雜,其性能肯定就會(huì)有一定的損失,維護(hù)成本自然也會(huì)相對(duì)更高一些。所以,對(duì)于僅僅需要使用MySQL數(shù)據(jù)庫(kù)的時(shí)候,我還是建議使用AmoebaForMySQL。

    AmoebaForMySQL的使用非常簡(jiǎn)單,所有的配置文件都是標(biāo)準(zhǔn)的XML文件,總共有四個(gè)配置文件。分別為:

    ◆amoeba.xml:主配置文件,配置所有數(shù)據(jù)源以及Amoeba自身的參數(shù)設(shè)置;

    ◆rule.xml:配置所有Query路由規(guī)則的信息;

    ◆functionMap.xml:配置用于解析Query中的函數(shù)所對(duì)應(yīng)的Java實(shí)現(xiàn)類;

    ◆ rullFunctionMap.xml:配置路由規(guī)則中需要使用到的特定函數(shù)的實(shí)現(xiàn)類;

    如果您的規(guī)則不是太復(fù)雜,基本上僅需要使用到上面四個(gè)配置文件中的前面兩個(gè)就可完成所有工作。Proxy程序常用的功能如讀寫(xiě)分離,負(fù)載均衡等配置都在amoeba.xml中進(jìn)行。此外,Amoeba已經(jīng)支持了實(shí)現(xiàn)數(shù)據(jù)的垂直切分和水平切分的自動(dòng)路由,路由規(guī)則可以在rule.xml進(jìn)行設(shè)置。

    目前Amoeba少有欠缺的主要就是其在線管理功能以及對(duì)事務(wù)的支持了,曾經(jīng)在與相關(guān)開(kāi)發(fā)者的溝通過(guò)程中提出過(guò)相關(guān)的建議,希望能夠提供一個(gè)可以進(jìn)行在線維護(hù)管理的命令行管理工具,方便在線維護(hù)使用,得到的反饋是管理專門(mén)的管理模塊已經(jīng)納入開(kāi)發(fā)日程了。另外在事務(wù)支持方面暫時(shí)還是Amoeba無(wú)法做到的,即使客戶端應(yīng)用在提交給Amoeba的請(qǐng)求是包含事務(wù)信息的,Amoeba也會(huì)忽略事務(wù)相關(guān)信息。當(dāng)然,在經(jīng)過(guò)不斷完善之后,我相信事務(wù)支持肯定是Amoeba重點(diǎn)考慮增加的feature。

    關(guān)于Amoeba更為詳細(xì)的使用方法讀者朋友可以通過(guò)Amoeba開(kāi)發(fā)者博客(http://amoeba.sf.net)上面提供的使用手冊(cè)獲取,這里就不再細(xì)述了。

    ★利用HiveDB實(shí)現(xiàn)數(shù)據(jù)切分及整合

    和前面的MySQLProxy以及Amoeba一樣,HiveDB同樣是一個(gè)基于Java針對(duì)MySQL數(shù)據(jù)庫(kù)的提供數(shù)據(jù)切分及整合的開(kāi)源框架,只是目前的HiveDB僅僅支持?jǐn)?shù)據(jù)的水平切分。主要解決大數(shù)據(jù)量下數(shù)據(jù)庫(kù)的擴(kuò)展性及數(shù)據(jù)的高性能訪問(wèn)問(wèn)題,同時(shí)支持?jǐn)?shù)據(jù)的冗余及基本的HA機(jī)制。

    HiveDB的實(shí)現(xiàn)機(jī)制與MySQLProxy和Amoeba有一定的差異,他并不是借助MySQL的Replication功能來(lái)實(shí)現(xiàn)數(shù)據(jù)的冗余,而是自行實(shí)現(xiàn)了數(shù)據(jù)冗余機(jī)制,而其底層主要是基于HibernateShards來(lái)實(shí)現(xiàn)的數(shù)據(jù)切分工作。

    在HiveDB中,通過(guò)用戶自定義的各種Partitionkeys(其實(shí)就是制定數(shù)據(jù)切分規(guī)則),將數(shù)據(jù)分散到多個(gè)MySQLServer中。在訪問(wèn)的時(shí)候,在運(yùn)行Query請(qǐng)求的時(shí)候,會(huì)自動(dòng)分析過(guò)濾條件,并行從多個(gè)MySQLServer中讀取數(shù)據(jù),并合并結(jié)果集返回給客戶端應(yīng)用程序。

    單純從功能方面來(lái)講,HiveDB可能并不如MySQLProxy和Amoeba那樣強(qiáng)大,但是其數(shù)據(jù)切分的思路與前面二者并無(wú)本質(zhì)差異。此外,HiveDB并不僅僅只是一個(gè)開(kāi)源愛(ài)好者所共享的內(nèi)容,而是存在商業(yè)公司支持的開(kāi)源項(xiàng)目。

    下面是HiveDB官方網(wǎng)站上面一章圖片,描述了HiveDB如何來(lái)組織數(shù)據(jù)的基本信息,雖然不能詳細(xì)的表現(xiàn)出太多架構(gòu)方面的信息,但是也基本可以展示出其在數(shù)據(jù)切分方面獨(dú)特的一面了。

    ★ mycat 數(shù)據(jù)整合:具體http://www.songwie.com/articlelist/11

    ★ 其他實(shí)現(xiàn)數(shù)據(jù)切分及整合的解決方案

    除了上面介紹的幾個(gè)數(shù)據(jù)切分及整合的整體解決方案之外,還存在很多其他同樣提供了數(shù)據(jù)切分與整合的解決方案。如基于MySQLProxy的基礎(chǔ)上做了進(jìn)一步擴(kuò)展的HSCALE,通過(guò)Rails構(gòu)建的SpockProxy,以及基于Pathon的Pyshards等等。

    不管大家選擇使用哪一種解決方案,總體設(shè)計(jì)思路基本上都不應(yīng)該會(huì)有任何變化,那就是通過(guò)數(shù)據(jù)的垂直和水平切分,增強(qiáng)數(shù)據(jù)庫(kù)的整體服務(wù)能力,讓?xiě)?yīng)用系統(tǒng)的整體擴(kuò)展能力盡可能的提升,擴(kuò)展方式盡可能的便捷。

    只要我們通過(guò)中間層Proxy應(yīng)用程序較好的解決了數(shù)據(jù)切分和數(shù)據(jù)源整合問(wèn)題,那么數(shù)據(jù)庫(kù)的線性擴(kuò)展能力將很容易做到像我們的應(yīng)用程序一樣方便,只需要通過(guò)添加廉價(jià)的PCServer服務(wù)器,即可線性增加數(shù)據(jù)庫(kù)集群的整體服務(wù)能力,讓數(shù)據(jù)庫(kù)不再輕易成為應(yīng)用系統(tǒng)的性能瓶頸。

     


    數(shù)據(jù)切分與整合可能存在的問(wèn)題

    這里,大家應(yīng)該對(duì)數(shù)據(jù)切分與整合的實(shí)施有了一定的認(rèn)識(shí)了,或許很多讀者朋友都已經(jīng)根據(jù)各種解決方案各自特性的優(yōu)劣基本選定了適合于自己應(yīng)用場(chǎng)景的方案,后面的工作主要就是實(shí)施準(zhǔn)備了。

    在實(shí)施數(shù)據(jù)切分方案之前,有些可能存在的問(wèn)題我們還是需要做一些分析的。一般來(lái)說(shuō),我們可能遇到的問(wèn)題主要會(huì)有以下幾點(diǎn):

    ◆ 引入分布式事務(wù)的問(wèn)題;

    ◆跨節(jié)點(diǎn)Join的問(wèn)題;

    ◆ 跨節(jié)點(diǎn)合并排序分頁(yè)問(wèn)題;

     

    1. 引入分布式事務(wù)的問(wèn)題

    一旦數(shù)據(jù)進(jìn)行切分被分別存放在多個(gè)MySQLServer中之后,不管我們的切分規(guī)則設(shè)計(jì)的多么的完美(實(shí)際上并不存在完美的切分規(guī)則),都可能造成之前的某些事務(wù)所涉及到的數(shù)據(jù)已經(jīng)不在同一個(gè)MySQLServer中了。

    在這樣的場(chǎng)景下,如果我們的應(yīng)用程序仍然按照老的解決方案,那么勢(shì)必需要引入分布式事務(wù)來(lái)解決。而在MySQL各個(gè)版本中,只有從MySQL5.0開(kāi)始以后的各個(gè)版本才開(kāi)始對(duì)分布式事務(wù)提供支持,而且目前僅有Innodb提供分布式事務(wù)支持。不僅如此,即使我們剛好使用了支持分布式事務(wù)的MySQL版本,同時(shí)也是使用的Innodb存儲(chǔ)引擎,分布式事務(wù)本身對(duì)于系統(tǒng)資源的消耗就是很大的,性能本身也并不是太高。而且引入分布式事務(wù)本身在異常處理方面就會(huì)帶來(lái)較多比較難控制的因素。

    怎么辦?其實(shí)我們可以可以通過(guò)一個(gè)變通的方法來(lái)解決這種問(wèn)題,首先需要考慮的一件事情就是:是否數(shù)據(jù)庫(kù)是唯一一個(gè)能夠解決事務(wù)的地方呢?其實(shí)并不是這樣的,我們完全可以結(jié)合數(shù)據(jù)庫(kù)以及應(yīng)用程序兩者來(lái)共同解決。各個(gè)數(shù)據(jù)庫(kù)解決自己身上的事務(wù),然后通過(guò)應(yīng)用程序來(lái)控制多個(gè)數(shù)據(jù)庫(kù)上面的事務(wù)。

    也就是說(shuō),只要我們?cè)敢猓耆梢詫⒁粋€(gè)跨多個(gè)數(shù)據(jù)庫(kù)的分布式事務(wù)分拆成多個(gè)僅處于單個(gè)數(shù)據(jù)庫(kù)上面的小事務(wù),并通過(guò)應(yīng)用程序來(lái)總控各個(gè)小事務(wù)。當(dāng)然,這樣作的要求就是我們的俄應(yīng)用程序必須要有足夠的健壯性,當(dāng)然也會(huì)給應(yīng)用程序帶來(lái)一些技術(shù)難度。

     

    2.跨節(jié)點(diǎn)Join的問(wèn)題

    上面介紹了可能引入分布式事務(wù)的問(wèn)題,現(xiàn)在我們?cè)倏纯葱枰绻?jié)點(diǎn)Join的問(wèn)題。數(shù)據(jù)切分之后,可能會(huì)造成有些老的Join語(yǔ)句無(wú)法繼續(xù)使用,因?yàn)镴oin使用的數(shù)據(jù)源可能被切分到多個(gè)MySQLServer中了。

    怎么辦?這個(gè)問(wèn)題從MySQL數(shù)據(jù)庫(kù)角度來(lái)看,如果非得在數(shù)據(jù)庫(kù)端來(lái)直接解決的話,恐怕只能通過(guò)MySQL一種特殊的存儲(chǔ)引擎Federated來(lái)解決了。Federated存儲(chǔ)引擎是MySQL解決類似于Oracle的DBLink之類問(wèn)題的解決方案。和OracleDBLink的主要區(qū)別在于Federated會(huì)保存一份遠(yuǎn)端表結(jié)構(gòu)的定義信息在本地。咋一看,F(xiàn)ederated確實(shí)是解決跨節(jié)點(diǎn)Join非常好的解決方案。但是我們還應(yīng)該清楚一點(diǎn),那就似乎如果遠(yuǎn)端的表結(jié)構(gòu)發(fā)生了變更,本地的表定義信息是不會(huì)跟著發(fā)生相應(yīng)變化的。如果在更新遠(yuǎn)端表結(jié)構(gòu)的時(shí)候并沒(méi)有更新本地的Federated表定義信息,就很可能造成Query運(yùn)行出錯(cuò),無(wú)法得到正確的結(jié)果。

    對(duì)待這類問(wèn)題,我還是推薦通過(guò)應(yīng)用程序來(lái)進(jìn)行處理,先在驅(qū)動(dòng)表所在的MySQLServer中取出相應(yīng)的驅(qū)動(dòng)結(jié)果集,然后根據(jù)驅(qū)動(dòng)結(jié)果集再到被驅(qū)動(dòng)表所在的MySQLServer中取出相應(yīng)的數(shù)據(jù)。可能很多讀者朋友會(huì)認(rèn)為這樣做對(duì)性能會(huì)產(chǎn)生一定的影響,是的,確實(shí)是會(huì)對(duì)性能有一定的負(fù)面影響,但是除了此法,基本上沒(méi)有太多其他更好的解決辦法了。而且,由于數(shù)據(jù)庫(kù)通過(guò)較好的擴(kuò)展之后,每臺(tái)MySQLServer的負(fù)載就可以得到較好的控制,單純針對(duì)單條Query來(lái)說(shuō),其響應(yīng)時(shí)間可能比不切分之前要提高一些,所以性能方面所帶來(lái)的負(fù)面影響也并不是太大。更何況,類似于這種需要跨節(jié)點(diǎn)Join的需求也并不是太多,相對(duì)于總體性能而言,可能也只是很小一部分而已。所以為了整體性能的考慮,偶爾犧牲那么一點(diǎn)點(diǎn),其實(shí)是值得的,畢竟系統(tǒng)優(yōu)化本身就是存在很多取舍和平衡的過(guò)程。

     

    3. 跨節(jié)點(diǎn)合并排序分頁(yè)問(wèn)題

    一旦進(jìn)行了數(shù)據(jù)的水平切分之后,可能就并不僅僅只有跨節(jié)點(diǎn)Join無(wú)法正常運(yùn)行,有些排序分頁(yè)的Query語(yǔ)句的數(shù)據(jù)源可能也會(huì)被切分到多個(gè)節(jié)點(diǎn),這樣造成的直接后果就是這些排序分頁(yè)Query無(wú)法繼續(xù)正常運(yùn)行。其實(shí)這和跨節(jié)點(diǎn)Join是一個(gè)道理,數(shù)據(jù)源存在于多個(gè)節(jié)點(diǎn)上,要通過(guò)一個(gè)Query來(lái)解決,就和跨節(jié)點(diǎn)Join是一樣的操作。同樣Federated也可以部分解決,當(dāng)然存在的風(fēng)險(xiǎn)也一樣。

    還是同樣的問(wèn)題,怎么辦?我同樣仍然繼續(xù)建議通過(guò)應(yīng)用程序來(lái)解決。

    如何解決?解決的思路大體上和跨節(jié)點(diǎn)Join的解決類似,但是有一點(diǎn)和跨節(jié)點(diǎn)Join不太一樣,Join很多時(shí)候都有一個(gè)驅(qū)動(dòng)與被驅(qū)動(dòng)的關(guān)系,所以Join本身涉及到的多個(gè)表之間的數(shù)據(jù)讀取一般都會(huì)存在一個(gè)順序關(guān)系。但是排序分頁(yè)就不太一樣了,排序分頁(yè)的數(shù)據(jù)源基本上可以說(shuō)是一個(gè)表(或者一個(gè)結(jié)果集),本身并不存在一個(gè)順序關(guān)系,所以在從多個(gè)數(shù)據(jù)源取數(shù)據(jù)的過(guò)程是完全可以并行的。這樣,排序分頁(yè)數(shù)據(jù)的取數(shù)效率我們可以做的比跨庫(kù)Join更高,所以帶來(lái)的性能損失相對(duì)的要更小,在有些情況下可能比在原來(lái)未進(jìn)行數(shù)據(jù)切分的數(shù)據(jù)庫(kù)中效率更高了。當(dāng)然,不論是跨節(jié)點(diǎn)Join還是跨節(jié)點(diǎn)排序分頁(yè),都會(huì)使我們的應(yīng)用服務(wù)器消耗更多的資源,尤其是內(nèi)存資源,因?yàn)槲覀冊(cè)谧x取訪問(wèn)以及合并結(jié)果集的這個(gè)過(guò)程需要比原來(lái)處理更多的數(shù)據(jù)。

    分析到這里,可能很多讀者朋友會(huì)發(fā)現(xiàn),上面所有的這些問(wèn)題,我給出的建議基本上都是通過(guò)應(yīng)用程序來(lái)解決。大家可能心里開(kāi)始犯嘀咕了,是不是因?yàn)槲沂荄BA,所以就很多事情都扔給應(yīng)用架構(gòu)師和開(kāi)發(fā)人員了?

    其實(shí)完全不是這樣,首先應(yīng)用程序由于其特殊性,可以非常容易做到很好的擴(kuò)展性,但是數(shù)據(jù)庫(kù)就不一樣,必須借助很多其他的方式才能做到擴(kuò)展,而且在這個(gè)擴(kuò)展過(guò)程中,很難避免帶來(lái)有些原來(lái)在集中式數(shù)據(jù)庫(kù)中可以解決但被切分開(kāi)成一個(gè)數(shù)據(jù)庫(kù)集群之后就成為一個(gè)難題的情況。要想讓系統(tǒng)整體得到最大限度的擴(kuò)展,我們只能讓?xiě)?yīng)用程序做更多的事情,來(lái)解決數(shù)據(jù)庫(kù)集群無(wú)法較好解決的問(wèn)題。

     

    小結(jié)

    通過(guò)數(shù)據(jù)切分技術(shù)將一個(gè)大的MySQLServer切分成多個(gè)小的MySQLServer,既解決了寫(xiě)入性能瓶頸問(wèn)題,同時(shí)也再一次提升了整個(gè)數(shù)據(jù)庫(kù)集群的擴(kuò)展性。不論是通過(guò)垂直切分,還是水平切分,都能夠讓系統(tǒng)遇到瓶頸的可能性更小。尤其是當(dāng)我們使用垂直和水平相結(jié)合的切分方法之后,理論上將不會(huì)再遇到擴(kuò)展瓶頸了。

    posted @ 2015-03-16 18:27 小馬歌 閱讀(4305) | 評(píng)論 (0)編輯 收藏
     
         摘要: from:http://wuhuajun.iteye.com/blog/1905578Thrift Java Servers ComparedThis article talks only about Java servers. See this page if you are interested in C++ servers.本文僅討論Java版的Thrift server...  閱讀全文
    posted @ 2015-03-12 17:25 小馬歌 閱讀(417) | 評(píng)論 (0)編輯 收藏
     

    1、添加依賴 jar

    <dependency>   <groupId>org.apache.thrift</groupId>   <artifactId>libthrift</artifactId>   <version>0.8.0</version> </dependency> <dependency>   <groupId>org.slf4j</groupId>   <artifactId>slf4j-log4j12</artifactId>   <version>1.6.1</version> </dependency> 

    2、編寫(xiě)IDL文件 Hello.thrift

    namespace java service.demo
    service Hello {
        string helloString(1:string para)
        i32 helloInt(1:i32 para)
        bool helloBoolean(1:bool para)
        void helloVoid()
        string helloNull()
    }


    3、生成代碼

    thrift -o <output directory> -gen java Hello.thrift
    生成代碼縮略圖:



    4、編寫(xiě)實(shí)現(xiàn)類、實(shí)現(xiàn)Hello.Iface:

    縮略圖:



    5、編寫(xiě)服務(wù)端,發(fā)布(阻塞式IO + 多線程處理)服務(wù)。

    1. /** 
    2.      * 阻塞式、多線程處理 
    3.      *  
    4.      * @param args 
    5.      */  
    6.     @SuppressWarnings({ "unchecked", "rawtypes" })  
    7.     public static void main(String[] args) {  
    8.         try {  
    9.             //設(shè)置傳輸通道,普通通道  
    10.             TServerTransport serverTransport = new TServerSocket(7911);  
    11.               
    12.             //使用高密度二進(jìn)制協(xié)議  
    13.             TProtocolFactory proFactory = new TCompactProtocol.Factory();  
    14.               
    15.             //設(shè)置處理器HelloImpl  
    16.             TProcessor processor = new Hello.Processor(new HelloImpl());  
    17.               
    18.             //創(chuàng)建服務(wù)器  
    19.             TServer server = new TThreadPoolServer(  
    20.                     new Args(serverTransport)  
    21.                     .protocolFactory(proFactory)  
    22.                     .processor(processor)  
    23.                 );  
    24.               
    25.             System.out.println("Start server on port 7911...");  
    26.             server.serve();  
    27.         } catch (Exception e) {  
    28.             e.printStackTrace();  
    29.         }  
    30.     }  



    6、編寫(xiě)客戶端,調(diào)用(阻塞式IO + 多線程處理)服務(wù):

    1. public static void main(String[] args) throws Exception {  
    2.         // 設(shè)置傳輸通道 - 普通IO流通道  
    3.         TTransport transport = new TSocket("localhost", 7911);  
    4.         transport.open();  
    5.           
    6.         //使用高密度二進(jìn)制協(xié)議  
    7.         TProtocol protocol = new TCompactProtocol(transport);  
    8.           
    9.         //創(chuàng)建Client  
    10.         Hello.Client client = new Hello.Client(protocol);  
    11.           
    12.         long start = System.currentTimeMillis();  
    13.         for(int i=0; i<10000; i++){  
    14.             client.helloBoolean(false);  
    15.             client.helloInt(111);  
    16.             client.helloNull();  
    17.             client.helloString("dongjian");  
    18.             client.helloVoid();  
    19.         }  
    20.         System.out.println("耗時(shí):" + (System.currentTimeMillis() - start));  
    21.           
    22.         //關(guān)閉資源  
    23.         transport.close();  
    24.     }  



    現(xiàn)在已完成整個(gè)開(kāi)發(fā)過(guò)程,超級(jí)無(wú)敵簡(jiǎn)單。

    其中服務(wù)端使用的協(xié)議需要與客戶端保持一致

    -------------------------------------------------------------------------------------------------------------------


    上面展示了普通且常用的服務(wù)端和客戶端,下面請(qǐng)看非阻塞IO,即java中的NIO:


    基于非阻塞IO(NIO)的服務(wù)端

    1. public static void main(String[] args) {  
    2.         try {  
    3.             //傳輸通道 - 非阻塞方式  
    4.             TNonblockingServerTransport serverTransport = new TNonblockingServerSocket(7911);  
    5.               
    6.             //異步IO,需要使用TFramedTransport,它將分塊緩存讀取。  
    7.             TTransportFactory transportFactory = new TFramedTransport.Factory();  
    8.               
    9.             //使用高密度二進(jìn)制協(xié)議  
    10.             TProtocolFactory proFactory = new TCompactProtocol.Factory();  
    11.               
    12.             //設(shè)置處理器 HelloImpl  
    13.             TProcessor processor = new Hello.Processor(new HelloImpl());  
    14.               
    15.             //創(chuàng)建服務(wù)器  
    16.             TServer server = new TThreadedSelectorServer(  
    17.                     new Args(serverTransport)  
    18.                     .protocolFactory(proFactory)  
    19.                     .transportFactory(transportFactory)  
    20.                     .processor(processor)  
    21.                 );  
    22.               
    23.             System.out.println("Start server on port 7911...");  
    24.             server.serve();  
    25.         } catch (Exception e) {  
    26.             e.printStackTrace();  
    27.         }  
    28.     }  



    調(diào)用非阻塞IO(NIO)服務(wù)的客戶端

    1. public static void main(String[] args) throws Exception {  
    2.         //設(shè)置傳輸通道,對(duì)于非阻塞服務(wù),需要使用TFramedTransport,它將數(shù)據(jù)分塊發(fā)送  
    3.         TTransport transport = new TFramedTransport(new TSocket("localhost", 7911));  
    4.         transport.open();  
    5.           
    6.         //使用高密度二進(jìn)制協(xié)議  
    7.         TProtocol protocol = new TCompactProtocol(transport);  
    8.           
    9.         //創(chuàng)建Client  
    10.         Hello.Client client = new Hello.Client(protocol);  
    11.           
    12.         long start = System.currentTimeMillis();  
    13.         for(int i=0; i<10000; i++){  
    14.             client.helloBoolean(false);  
    15.             client.helloInt(111);  
    16.             client.helloNull();  
    17.             client.helloString("360buy");  
    18.             client.helloVoid();  
    19.         }  
    20.         System.out.println("耗時(shí):" + (System.currentTimeMillis() - start));  
    21.           
    22.         //關(guān)閉資源  
    23.         transport.close();  
    24.     }  



    -----------------------------------------------------------------------------------------------------------------------------------

    客戶端異步調(diào)用

    1. /** 調(diào)用[非阻塞IO]服務(wù),異步 */  
    2.     public static void main(String[] args) {  
    3.         try {  
    4.             //異步調(diào)用管理器  
    5.             TAsyncClientManager clientManager = new TAsyncClientManager();  
    6.             //設(shè)置傳輸通道,調(diào)用非阻塞IO。  
    7.             final TNonblockingTransport transport = new TNonblockingSocket("localhost", 7911);    
    8.             //設(shè)置協(xié)議  
    9.             TProtocolFactory protocol = new TCompactProtocol.Factory();    
    10.             //創(chuàng)建Client  
    11.             final Hello.AsyncClient client = new Hello.AsyncClient(protocol, clientManager, transport);  
    12.             // 調(diào)用服務(wù)   
    13.             System.out.println("開(kāi)始:" + System.currentTimeMillis());  
    14.             client.helloBoolean(false, new AsyncMethodCallback<Hello.AsyncClient.helloBoolean_call>() {  
    15.                 public void onError(Exception exception) {  
    16.                     System.out.println("錯(cuò)誤1: " + System.currentTimeMillis());  
    17.                 }  
    18.                 public void onComplete(helloBoolean_call response) {  
    19.                     System.out.println("完成1: " + System.currentTimeMillis());  
    20.                     try {  
    21.                         client.helloBoolean(false, new AsyncMethodCallback<Hello.AsyncClient.helloBoolean_call>() {  
    22.                             public void onError(Exception exception) {  
    23.                                 System.out.println("錯(cuò)誤2: " + System.currentTimeMillis());  
    24.                             }  
    25.                               
    26.                             public void onComplete(helloBoolean_call response) {  
    27.                                 System.out.println("完成2: " + System.currentTimeMillis());  
    28.                                 transport.close();  
    29.                             }  
    30.                         });  
    31.                     } catch (TException e) {  
    32.                         e.printStackTrace();  
    33.                     }  
    34.                 }  
    35.             });  
    36.             System.out.println("結(jié)束:" + System.currentTimeMillis());  
    37.             Thread.sleep(5000);  
    38.         } catch (Exception e) {  
    39.             e.printStackTrace();  
    40.         }  
    41.     }  


    -----------------------------------------------------------------------------------------------------------------------------------

    使用SSL的服務(wù)端:



    調(diào)用基于SSL服務(wù)端的客戶端:


    posted @ 2015-03-12 17:20 小馬歌 閱讀(536) | 評(píng)論 (0)編輯 收藏
     
         摘要: 作為Java程序員來(lái)說(shuō),最痛苦的事情莫過(guò)于可以選擇的范圍太廣,可以讀的書(shū)太多,往往容易無(wú)所適從。我想就我自己讀過(guò)的技術(shù)書(shū)籍中挑選出來(lái)一些,按照學(xué)習(xí)的先后順序,推薦給大家,特別是那些想不斷提高自己技術(shù)水平的Java程序員們。 一、Java編程入門(mén)類  對(duì)于沒(méi)有Java編程經(jīng)驗(yàn)的程序員要入門(mén),隨便讀什么入門(mén)書(shū)籍都一樣,這個(gè)階段需要你快速的掌握J(rèn)ava基礎(chǔ)語(yǔ)法和基本用法,宗...  閱讀全文
    posted @ 2015-03-11 13:47 小馬歌 閱讀(310) | 評(píng)論 (0)編輯 收藏
     

    from: http://wapapp.baidu.com/tianhuimin/item/6e144c362eced2ff96f88d42

    1 概述1.1 研發(fā)背景

    支撐互聯(lián)網(wǎng)應(yīng)用的各種服務(wù)通常都是用復(fù)雜大規(guī)模分布式集群來(lái)實(shí)現(xiàn)的。而這些互聯(lián)網(wǎng)應(yīng)用又構(gòu)建在不同的軟件模塊集上,這些軟件模塊,有可能是由不同的團(tuán)隊(duì)開(kāi) 發(fā)、可能使用不同的編程語(yǔ)言來(lái)實(shí)現(xiàn)、有可能布在了幾千臺(tái)服務(wù)器,橫跨多個(gè)不同的數(shù)據(jù)中心。因此,就需要一些可以幫助理解系統(tǒng)行為、用于分析性能問(wèn)題的工 具。

    hydra分布式跟蹤系統(tǒng)就為了解決以上這些問(wèn)題而設(shè)計(jì)的。

    1.2 理論依據(jù)

    Google的論文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》是我們?cè)O(shè)計(jì)開(kāi)發(fā)的指導(dǎo)思想(原文和譯文地址 https://github.com/bigbully/Dapper-translation)。Google針對(duì)自己的分布式跟蹤系統(tǒng)Dapper 在生產(chǎn)環(huán)境下運(yùn)行兩年多時(shí)間積累的經(jīng)驗(yàn),在論文中重點(diǎn)提到了分布式跟蹤系統(tǒng)對(duì)業(yè)務(wù)系統(tǒng)的零侵入這個(gè)先天優(yōu)勢(shì),并總結(jié)了大量的應(yīng)用場(chǎng)景,還提及它的不足之 處。我們通過(guò)對(duì)這篇論文的深入研究,并參考了Twitter同樣依據(jù)這篇論文的scala實(shí)現(xiàn)Zipkin,結(jié)合我們自身的現(xiàn)有架構(gòu),我們認(rèn)為分布式跟蹤 系統(tǒng)在我們內(nèi)部是非常適合的,而且也是急需的。

    1.3 功能概述

    hydra目前的功能并不復(fù)雜,他可以接入一些基礎(chǔ)組件,然后實(shí)現(xiàn)在基礎(chǔ)組件上收集在組建上產(chǎn)生的行為的時(shí)間消耗,并且提供跟蹤查詢頁(yè)面,對(duì)跟蹤到的數(shù)據(jù)進(jìn)行查詢和展示。

    我們會(huì)在之后的功能介紹中對(duì)hydra現(xiàn)有功能進(jìn)行說(shuō)明。

    2 領(lǐng)域模型

    分布式跟蹤的領(lǐng)域模型其實(shí)已經(jīng)很成熟,早在1997年IBM就把ARM2.0(Application Response Measurement)作為一個(gè)公開(kāi)的標(biāo)準(zhǔn)提供給了Open Group,無(wú)奈當(dāng)時(shí)SOA的架構(gòu)還未成熟,對(duì)業(yè)務(wù)的跟蹤還需要直接嵌入到業(yè)務(wù)代碼中,致使跟蹤系統(tǒng)無(wú)法順利推廣。

    如今互聯(lián)網(wǎng)領(lǐng)域大多數(shù)后臺(tái)服務(wù)都已經(jīng)完成了SOA化,所以對(duì)業(yè)務(wù)的跟蹤可以直接簡(jiǎn)化為對(duì)服務(wù)調(diào)用框架的跟蹤,所以越來(lái)越多的跟蹤系統(tǒng)也涌現(xiàn)出來(lái)。 在hydra系統(tǒng)中,我們使用的領(lǐng)域模型參考了Google的Dapper和Twitter的Zipkin(http://twitter.github.io/zipkin/)。

    2.1 hydra中的跟蹤數(shù)據(jù)模型

    參考Dapper和Zipkin的設(shè)計(jì),hydra也提煉出了自己的領(lǐng)域模型,如圖所示:

    Hydra - 京東開(kāi)源的基于Dubbo的調(diào)用分布跟蹤系統(tǒng)
    • Trace:一次服務(wù)調(diào)用追蹤鏈路。

    • Span:追蹤服務(wù)調(diào)基本結(jié)構(gòu),多span形成樹(shù)形結(jié)構(gòu)組合成一次Trace追蹤記錄。

    • Annotation:在span中的標(biāo)注點(diǎn),記錄整個(gè)span時(shí)間段內(nèi)發(fā)生的事件。

    • BinaryAnnotation:屬于Annotation一種類型和普通Annotation區(qū)別,這鍵值對(duì)形式標(biāo)注在span中發(fā)生的事件,和一些其他相關(guān)的信息。

    Annotation在整個(gè)跟蹤數(shù)據(jù)模型中最靈活的,靈活運(yùn)用annotation基本能表達(dá)你所想到的跟蹤場(chǎng)景。在hydra中(參考了zipkin)定義4種不同value的annotation用來(lái)表達(dá)記錄span 4個(gè)最基本的事件。通過(guò)這4個(gè)annotation能計(jì)算出鏈路中業(yè)務(wù)消耗和網(wǎng)絡(luò)消耗時(shí)間。

    2.2 dubbo服務(wù)調(diào)用框架的模型

    公司內(nèi)部,尤其是我們部門(mén)有很多業(yè)務(wù)系統(tǒng)使用dubbo作為服務(wù)調(diào)用框,所以我們的分布式跟蹤系統(tǒng)第一個(gè)接入組件就是dubbo。 另一個(gè)原因也是因?yàn)槲覀儓F(tuán)隊(duì)對(duì)dubbo有著非常深入的理解,加之dubbo本身的架構(gòu)本身十分適合擴(kuò)展,作為服務(wù)調(diào)用框架而言,跟蹤的效果會(huì)非常明顯, 比如Twitter的Zipkin也是植入到內(nèi)部的Finagle服務(wù)調(diào)用框架上來(lái)進(jìn)行跟蹤的。

    由于現(xiàn)階段hydra主要接入了dubbo服務(wù)調(diào)用框架,所以在這必須了解dubbo的幾個(gè)模型,如下圖所示:

    Hydra - 京東開(kāi)源的基于Dubbo的調(diào)用分布跟蹤系統(tǒng)
    • Application:一類業(yè)務(wù)類型的服務(wù),下面可能包含多個(gè)接口服務(wù),可能出現(xiàn)多種類型業(yè)務(wù)跟蹤鏈路。

    • InterfaceService:接口服務(wù),一個(gè)服務(wù)接口提供多種業(yè)務(wù)處理方法。

    • Method:接口服務(wù)中具體處理業(yè)務(wù)的方法。

    2.3 Hydra中跟蹤模型和dubbo模型之間關(guān)系Hydra - 京東開(kāi)源的基于Dubbo的調(diào)用分布跟蹤系統(tǒng)

    如圖所示的應(yīng)用場(chǎng)景對(duì)A服務(wù)的調(diào)用。A服務(wù)在被調(diào)用的過(guò)程中會(huì)繼續(xù)調(diào)用服務(wù)B和服務(wù)C,而服務(wù)C被調(diào)用之后又會(huì)繼續(xù)調(diào)用服務(wù)D和服 務(wù)E。在我們的領(lǐng)域模型中,服務(wù)A被調(diào)用到調(diào)用完成的過(guò)程,就是一次trace。而每一個(gè)服務(wù)被調(diào)用并返回的過(guò)程(一去一回的箭頭)為一個(gè)span。可以 看到這個(gè)示例中包含5個(gè)span,client-A,A-B,A-C,C-D,C-E。span本身以樹(shù)形結(jié)構(gòu)展開(kāi),A-C是C-D和C-E的父 span,而client-A是整個(gè)樹(shù)形結(jié)構(gòu)的root span。之后要提到的一個(gè)概念就是annotation,annotation代表在服務(wù)調(diào)用過(guò)程中發(fā)生的一些我們感興趣的事情,如圖所示C-E上標(biāo)出 來(lái)的那四個(gè)點(diǎn),就是四個(gè)annotation,來(lái)記錄事件時(shí)間戳,分別是C服務(wù)的cs(client send),E服務(wù)的ss(server receive),E服務(wù)的ss(server send), C服務(wù)的cr(client receive)。如果有一些自定義的annotation我們會(huì)把它作為BinaryAnnotation,其實(shí)就是一個(gè)k-v對(duì),記錄任何跟蹤系統(tǒng)想 記錄的信息,比如服務(wù)調(diào)用中的異常信息,重要的業(yè)務(wù)信息等等。

    3 功能介紹

    當(dāng)前hydra1.0版的功能主要分為兩個(gè)部分,跟蹤查詢和跟蹤展示。

    如圖所示為查詢頁(yè)面:

    Hydra - 京東開(kāi)源的基于Dubbo的調(diào)用分布跟蹤系統(tǒng)

    在hydra針對(duì)業(yè)務(wù)提出兩個(gè)相關(guān)的概念:應(yīng)用和服務(wù)。不同的業(yè)務(wù)的所屬不同的應(yīng)用(相當(dāng)于dubbo中的Application),服務(wù)(相當(dāng)于dubbo中的interface)掛在應(yīng)用之下。

    在hydra的查詢界面中首先要選擇想要關(guān)注的應(yīng)用名,然后通過(guò)自動(dòng)完成的方式輸入應(yīng)用下的服務(wù)。選擇服務(wù)的開(kāi)始時(shí)間和需要查看的跟蹤次數(shù)。另外hydra需要確定返回?cái)?shù)據(jù)的總量,防止查詢出大數(shù)據(jù)量導(dǎo)致頁(yè)面失去響應(yīng)。

    另外我們提供對(duì)額外的篩選條件:調(diào)用響應(yīng)時(shí)間、是否發(fā)生異常。調(diào)用響應(yīng)時(shí)間指的是這一次服務(wù)調(diào)用從調(diào)用開(kāi)始到調(diào)用結(jié)束的時(shí)間,是否發(fā)生異常則包括一次服務(wù)調(diào)用中所有歷經(jīng)的服務(wù)拋出的異常都會(huì)捕獲到。

    對(duì)于查詢之后的數(shù)據(jù),hydra提供在前臺(tái)進(jìn)行排序的功能。

    對(duì)于每一次跟蹤,我們可以進(jìn)一步展示他的服務(wù)調(diào)用層級(jí)與響應(yīng)時(shí)間的時(shí)序圖。如下圖所示:

    Hydra - 京東開(kāi)源的基于Dubbo的調(diào)用分布跟蹤系統(tǒng)

    我們參考Dapper中論述的場(chǎng)景,在時(shí)序圖中用綠色代表服務(wù)調(diào)用時(shí)間,淺藍(lán)色代表網(wǎng)絡(luò)耗時(shí),另外如果服務(wù)調(diào)用拋出異常被 hydra捕捉到的話,會(huì)用紅色表示。鼠標(biāo)移動(dòng)到時(shí)序圖中的每一個(gè)對(duì)象上,會(huì)Tip展現(xiàn)詳細(xì)信息,包括服務(wù)名、方法名、調(diào)用時(shí)長(zhǎng)、Endpoint、異常 信息等。

    左側(cè)的樹(shù)形結(jié)構(gòu)圖可以收起和展開(kāi),同時(shí)右側(cè)的時(shí)序圖產(chǎn)生聯(lián)動(dòng),利于調(diào)整關(guān)注點(diǎn)在不同的服務(wù)上。

    4 整體架構(gòu)4.1 完整版Hydra - 京東開(kāi)源的基于Dubbo的調(diào)用分布跟蹤系統(tǒng)

    對(duì)于分布式跟蹤系統(tǒng)而言,必須對(duì)接入的基礎(chǔ)組件進(jìn)行改造,我們對(duì)dubbo的改造很簡(jiǎn)單,只是在過(guò)濾器鏈上增加一個(gè)過(guò)濾器,我們將其封裝成一個(gè)hydra-dubbo的jar包,由dubbo直接依賴。

    所有跟蹤所需的通用性的API我們封裝在hydra-client中,遍于接入各種組件。 hydra-manager用來(lái)完成每個(gè)服務(wù)的注冊(cè)、采樣率的調(diào)成、發(fā)送seed生成全局唯一的traceId等通用性的功能。所有hydra-manager數(shù)據(jù)統(tǒng)一用mysql進(jìn)行存儲(chǔ)。

    我們使用hydra-collector和hydra-collector-service進(jìn)行跟蹤數(shù)據(jù)的異步存儲(chǔ),中間使用metaQ進(jìn)行緩沖。

    hydra-manager和hydra-collector使用dobbo提供服務(wù)。

    4.2 精簡(jiǎn)版

    考慮到數(shù)據(jù)量不大的情況,以及部署的復(fù)雜度。我們提供了兩種更簡(jiǎn)便的架構(gòu)

    • 如果考慮到數(shù)據(jù)量沒(méi)有那么大,可以不使用hbase,用mysql代替,即精簡(jiǎn)版1。因?yàn)楫吘筯adoop集群和hbase集群的部署和維護(hù)工作量很大。

    • 如果并發(fā)量也不是很大的話,可以不使用消息中間件,也就是精簡(jiǎn)版2,如圖所示。在hydra-collector端直接進(jìn)行數(shù)據(jù)落地,當(dāng)然仍然是異步的。

    Hydra - 京東開(kāi)源的基于Dubbo的調(diào)用分布跟蹤系統(tǒng)

    在使用mysql進(jìn)行存儲(chǔ)的時(shí)候我們并未進(jìn)行分庫(kù)分表,因?yàn)榭紤]到存儲(chǔ)的是監(jiān)控?cái)?shù)據(jù),時(shí)效性較高,而長(zhǎng)期的監(jiān)控?cái)?shù)據(jù)的保留意義并不大。所以我們?cè)谥鞅砩嫌忻鞔_的時(shí)間戳字段,使用者可以自行決定何時(shí)對(duì)保存的歷史數(shù)據(jù)進(jìn)行遷移。

    5 Quick Start5.1 部署簡(jiǎn)介

    Hydra分布式跟蹤系統(tǒng)可以跟蹤環(huán)境的數(shù)據(jù)量大小選擇上文所述的三種部署方式

    • 高并發(fā),大數(shù)據(jù)量:hydra-client | Queue | hbase

    • 高并發(fā),小數(shù)據(jù)量:hydra-client | Queue | mysql

    • 低并發(fā),小數(shù)據(jù)量:hydra-client | mysql

    因?yàn)槭莙uick start,這里只介紹低并發(fā)和小數(shù)據(jù)量的情況。不過(guò)這里會(huì)詳細(xì)介紹如何通過(guò)配置文件的修改來(lái)切換這三種部署方式。

    5.2 硬件要求
    • 1或多臺(tái)業(yè)務(wù)系統(tǒng)集群機(jī)

    • 1套zookeeper單點(diǎn)或集群機(jī)

    • 1臺(tái)機(jī)器部署Hydra-manager

    • 1或多臺(tái)機(jī)器部署Hydra-Collector

    • 1臺(tái)機(jī)器部署Hydra-web

    • 1臺(tái)數(shù)據(jù)庫(kù)服務(wù)器

    5.3 軟件要求
    • Dubbo:Hydra是基于alibaba的dubbo框架基準(zhǔn)上做的服務(wù)跟蹤系統(tǒng),理論上原有的Dubbo框架服務(wù)群中所有應(yīng)用不需要額外的配置,皆可以平滑的接入Hydra系統(tǒng)。

    • Zookeeper:各個(gè)服務(wù)點(diǎn)依賴于zookeeper來(lái)讀取Hydra-manager和Hydra-collector獲取數(shù)據(jù)交互路由點(diǎn),來(lái)完成跟蹤數(shù)據(jù)的推送和跟蹤的控制。

    • Mysql:跟蹤數(shù)據(jù)的持久化存儲(chǔ)。

    • Tomcat:前端web應(yīng)用容器

    5.4 源碼獲取

    可以暫時(shí)使用master,后續(xù)版本會(huì)歸并到dubbo管理端

    5.5 項(xiàng)目構(gòu)建打包

    maven項(xiàng)目不用多說(shuō)。mvn clean install。不過(guò)不得不說(shuō)的是,hydra項(xiàng)目中包含一些涉及數(shù)據(jù)庫(kù)讀寫(xiě)的單元測(cè)試(mysql,hbase),配置文件分別在:

    • modules/hydra-manager-db/src/test/resources/mysql.properties

    • modules/hydra-store/hydra-mysql/src/test/resources/mysql.properties

    • modules/hydra-store/hydra-hbase/src/test/resources/hbase-site.xml

    • modules/hydra-store/hydra-hbase/src/test/resources/hydra-hbase-test.xml

    mysql需要?jiǎng)?chuàng)建測(cè)試用數(shù)據(jù)庫(kù)和測(cè)試用表,hbase需要?jiǎng)?chuàng)建測(cè)試用表

    • docs/table-hbase/initTable
      (hbase建表時(shí)可以根據(jù)hbase集群的具體情況調(diào)整域分區(qū),涉及到table-mysql中對(duì)TB_PARA_SERVICE_ID_GEN初始化數(shù)據(jù)的設(shè)計(jì))

    • docs/table-mysql

    當(dāng)然對(duì)于不需要使用hbase的同學(xué)也可以自行移除modules/hydar-store/hydra-hbase。

    當(dāng)然用maven構(gòu)建跳過(guò)測(cè)試也是可以的。使用mvn clean install -Dmaven.test.skip=true

    需要打包的子項(xiàng)目會(huì)通過(guò)maven:assemblly插件打成tar.gz包在各自的target目錄下。

    5.6 安裝部署5.6.1 Hydra-client

    hydra-client中包含hydra與dubbo的集成,以及hydra跟蹤收集的相關(guān)功能。如果需要進(jìn)行dubbo服務(wù)的跟蹤,只需要把這個(gè)jar包放在dubbo服務(wù)的classpath下,就會(huì)自動(dòng)開(kāi)啟跟蹤功能!

    5.6.2 Hydra-manager
    1. 部署:scp -r target/*.tar.gz username@ip:dirname

    2. 配置:cd basedir/conf (需要修改配置)

    3. 啟動(dòng):cd basedir/bin
      sh manager.sh start

    4. 停止:cd basedir/bin
      sh manager.sh stop

    5. 輸入:cd basedir/log
      tail -f manager.log

    5.6.3 Hydra-collector
    1. 部署:scp -r target/*.tar.gz username@ip:dirname

    2. 配置:cd basedir/conf (需要修改配置)

    3. 啟動(dòng):cd basedir/bin
      sh collector-mysql.sh start 
      (這里注意一下,如果在hydra-collector中需要發(fā)送到Queue中,則需要啟動(dòng)collector.sh,jar包會(huì)加載不同的配置文件。)

    4. 停止:cd basedir/bin
      sh collector-mysql.sh stop

    5. 輸入:cd basedir/log
      tail -f *.log

    5.6.4 Hydra-web
    1. 需要在web.xml中修改引入的配置文件為hydra-mysql.xml,注掉hydra-hbase.xml

    2. 部署:scp -r target/*.war username@ip:$TOMCAT_WEBAPPS

    6 模擬場(chǎng)景6.1 場(chǎng)景描述

    我們模擬了兩個(gè)測(cè)試場(chǎng)景,均是基于dubbo服務(wù)調(diào)用

    場(chǎng)景exp1:

    A --> B --> C         

    即服務(wù)A調(diào)用服務(wù)B,服務(wù)B調(diào)用服務(wù)C。測(cè)試用例在modules/hydra-example/hydra-exmple-exp1/。熟悉dubbo的同學(xué)一定不會(huì)陌生。

    場(chǎng)景exp2:

    A --> B --> C1 --> E                     --> C2 --> D1 --> C1 --> E                            --> D2         

    場(chǎng)景2很復(fù)雜,基本涵蓋了對(duì)同步調(diào)用跟蹤的大多數(shù)可能遇到的場(chǎng)景。測(cè)試用例在modules/hydra-example/hydra-exmple-exp2/。

    6.2 模擬場(chǎng)景dubbo服務(wù)的部署

    Hydra默認(rèn)使用了hydra-exmple中的兩個(gè)應(yīng)用場(chǎng)景來(lái)做,你可以在hydra-test/hydra-test-integration打包中獲得應(yīng)用場(chǎng)景。

    獲得tar.gz包或者zip包后,將服務(wù)分布式部署到不同的機(jī)器上,以模擬應(yīng)用場(chǎng)景,一下介紹場(chǎng)景一的部署方法,場(chǎng)景二的部署方法類似。

    hydra-test-intergration 分為windows版和linux版(默認(rèn)),見(jiàn)如下打包方法。

    • 打包:linux: mvn package -Pruntime-env-linux
      window: mvn package -Pruntime-env-windows

    • 部署: scp -r target/*.tar.gz username@ip:dirname

    • 配置: cd basedir/conf
      修改 *exp1.properties

    • 啟動(dòng): cd basedir/bin
      cd exp1
      sh startA.sh
      cd ..
      sh startTrigger-exp1.sh start

    • 停止: cd basedir/bin
      sh startTrigger-exp1.sh stop
      All.sh stop

    • 輸出: cd basedir/log
      tail -f *.log

    6.3 部署舉例

    以下演示安裝樣例:

    1. 部署zookeeper單點(diǎn)或集群環(huán)境,以保證獲得最佳SOA,zookeeper的部署請(qǐng)參照官方文檔。

    2. 部署實(shí)驗(yàn)場(chǎng)景exp1,只需要部署hydra-test-integration模塊打包的tar.gz包,拷貝三份分布式部署。

    3. 部署一個(gè)觸發(fā)器Trigger,以激活服務(wù)的調(diào)用。

    4. 部署一個(gè)Manager,以管理各個(gè)跟蹤點(diǎn)的跟蹤上下文。

    5. 部署一個(gè)或者多個(gè)Collector消費(fèi)機(jī)集群,以搜集來(lái)自Hydra-client推送過(guò)來(lái)的跟蹤數(shù)據(jù)。

    6. 部署一個(gè)web應(yīng)用,已提供給前端展現(xiàn)應(yīng)用系統(tǒng)服務(wù)上下文。

    exp1場(chǎng)景說(shuō)明:

    有三個(gè)服務(wù)應(yīng)用A、B、C和一個(gè)觸發(fā)RPC調(diào)用的應(yīng)用Trigger,服務(wù)調(diào)用關(guān)系為A-B-C, 每隔500s觸發(fā)一個(gè)調(diào)用,持續(xù)時(shí)間為1天。

    部署地址舉例:

    角色ipportZK192.168.200.110-1122181~A192.168.200.11020990B192.168.200.11120991C192.168.200.11220992Trigger192.168.200.113-Manager192.168.228.8120890Collector192.168.228.81-8220889Web192.168.228.818080MySql-DB192.168.228.8133067 測(cè)試相關(guān)7.1 測(cè)試說(shuō)明

    本測(cè)試針對(duì)Hydra-Client模塊進(jìn)行功能測(cè)試和壓力測(cè)試,以便在Hydra開(kāi)發(fā)的過(guò)程中及時(shí)發(fā)現(xiàn)重要bug和幫助優(yōu)化Hydra系統(tǒng)性能。

    本測(cè)試目前只針對(duì)Hydra-client的測(cè)試,重點(diǎn)關(guān)注業(yè)務(wù)系統(tǒng)接入Hydra和不接入Hydra前后性能影響,以保證Hydra系統(tǒng)接入端的低侵入性和穩(wěn)定性。

    針對(duì)Hydra-Client的測(cè)試,在部署上,只用部署應(yīng)用場(chǎng)景(帶Hydra_client)和Benchmark觸發(fā)點(diǎn),然后在應(yīng)用Benchmark和應(yīng)用場(chǎng)景上埋點(diǎn)分析Hydra性能。


    資料來(lái)源:http://www.open-open.com/lib/view/open1370253915148.html

    posted @ 2015-03-09 16:06 小馬歌 閱讀(5054) | 評(píng)論 (0)編輯 收藏
     
         摘要: from:http://www.jb51.net/article/48304.htm本教程將Java8的新特新逐一列出,并將使用簡(jiǎn)單的代碼示例來(lái)指導(dǎo)你如何使用默認(rèn)接口方法,lambda表達(dá)式,方法引用以及多重Annotation,之后你將會(huì)學(xué)到最新的API上的改進(jìn),比如流,函數(shù)式接口,Map以及全新的日期API“Java is still not dead—and peop...  閱讀全文
    posted @ 2015-03-09 14:52 小馬歌 閱讀(396) | 評(píng)論 (1)編輯 收藏
     
    posted @ 2015-03-06 17:03 小馬歌 閱讀(223) | 評(píng)論 (0)編輯 收藏
    僅列出標(biāo)題
    共95頁(yè): First 上一頁(yè) 12 13 14 15 16 17 18 19 20 下一頁(yè) Last 
     
    主站蜘蛛池模板: 一二三四视频在线观看中文版免费 | 日韩免费码中文在线观看| 国产成人精品免费午夜app| 久久青青草原亚洲av无码app| 国产一区二区免费| a级毛片高清免费视频| 久久影院亚洲一区| 亚洲婷婷第一狠人综合精品| 91九色精品国产免费| 亚洲另类视频在线观看| 69堂人成无码免费视频果冻传媒 | 2021国产精品成人免费视频| 亚洲制服丝袜在线播放| 中文字幕无码免费久久99| 亚洲色大成WWW亚洲女子| 日韩一级免费视频| 免费看一级一级人妻片| 亚洲人成色7777在线观看不卡 | 在线观看亚洲一区二区| 最近中文字幕免费完整| 亚洲午夜电影在线观看高清| 免费做爰猛烈吃奶摸视频在线观看| 亚洲色大成网站www久久九 | 97无码免费人妻超级碰碰碰碰 | 亚洲视频在线观看地址| 97国产免费全部免费观看| 男人天堂2018亚洲男人天堂| 在线观看永久免费视频网站| 人人鲁免费播放视频人人香蕉| 亚洲乱码无码永久不卡在线| 亚洲精品免费在线观看| 亚洲剧情在线观看| 国产成人精品免费视频大全五级| 亚洲小说图片视频| 成人免费无码大片a毛片软件| 18禁亚洲深夜福利人口| 久久久久亚洲AV成人网| 无码成A毛片免费| 久久精品国产亚洲AV久| 四虎永久在线精品免费影视 | 深夜免费在线视频|