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

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

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

    少年阿賓

    那些青春的歲月

      BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
      500 Posts :: 0 Stories :: 135 Comments :: 0 Trackbacks

    #

    反射只能讀取類信息,而 ASM 除了讀還能寫。
    反射讀取類信息時需要進行類加載處理,而 ASM 則不需要將類加載到內(nèi)存中。
    反射相對于 ASM 來說使用方便,想直接操縱 ASM 的話需要有 JVM 指令基礎(chǔ)。  
    反射是讀取持久堆上存儲的類信息。而 ASM 是直接處理 .class 字節(jié)碼的小工具(工具雖小,但是功能非常強大!) 
    posted @ 2015-04-03 18:20 abin 閱讀(1217) | 評論 (0)編輯 收藏

     If you are not sure about the string pool usage, try -XX:+PrintStringTableStatistics JVM argument. It will print you the string pool usage when your program terminates.
    posted @ 2015-03-31 18:22 abin 閱讀(335) | 評論 (0)編輯 收藏

    基本概念:
          在軟件系統(tǒng)中,“行為請求者”與“行為實現(xiàn)者”通常呈現(xiàn)一種“緊耦合”。但在某些場合,比如要對行為進行“記錄、撤銷/重做、事務(wù)”等處理,這種無法抵御變化的緊耦合是不合適的。在這種情況下,如何將“行為請求者”與“行為實現(xiàn)者”解耦?將一組行為抽象為對象實現(xiàn)二者之間的松耦合。這就是命令模式(Command Pattern)。

         將來自客戶端的請求傳入一個對象,從而使你可用不同的請求對客戶進行參數(shù)化。用于“行為請求者”與“行為實現(xiàn)者”解耦,可實現(xiàn)二者之間的松耦合,以便適應(yīng)變化。分離變化與不變的因素。

       在面向?qū)ο蟮某绦蛟O(shè)計中,一個對象調(diào)用另一個對象,一般情況下的調(diào)用過程是:創(chuàng)建目標(biāo)對象實例;設(shè)置調(diào)用參數(shù);調(diào)用目標(biāo)對象的方法。

    但在有些情況下有必要使用一個專門的類對這種調(diào)用過程加以封裝,我們把這種專門的類稱作command類。


    特點
    1)、command模式將調(diào)用操作的對象和實現(xiàn)該操作的對象解耦
    2)、可以將多個命令裝配成一個復(fù)合命令,復(fù)合命令是Composite模式的一個實例
    3)、增加新的command很容易,無需改變已有的類

    應(yīng)用場景:

    我們來分析下命令模式的使用場景吧,一般情況下如下幾類場景中使用命令模式會達到很好的效果:

          1、當(dāng)一個應(yīng)用程序調(diào)用者與多個目標(biāo)對象之間存在調(diào)用關(guān)系時,并且目標(biāo)對象之間的操作很類似的時候。

          2、例如當(dāng)一個目標(biāo)對象內(nèi)部的方法調(diào)用太復(fù)雜,或者內(nèi)部的方法需要協(xié)作才能完成對象的某個特點操作時。

          3、有時候調(diào)用者調(diào)用目標(biāo)對象后,需要回調(diào)一些方法。

         命令模式是將行為請求者和行為實現(xiàn)者解耦合的方式。對命令進行封裝,將命令和執(zhí)行命令分隔開。請求的一方發(fā)出命令,要求執(zhí)行某些操作,接受一方收到命令,執(zhí)行這些操作的真正實現(xiàn)。請求的一方不必知道接受方的接口,以及如何被操作。 


        命令模式可以應(yīng)用到很多場景,比如實現(xiàn)do/undo功能、實現(xiàn)導(dǎo)航功能。

    posted @ 2015-03-30 21:23 abin 閱讀(2144) | 評論 (2)編輯 收藏

    ApplicationContext 是 BeanFactory 接口的子接口,它增強了 BeanFactory 的功能,處于 context 包下。很多時候, ApplicationContext 允許以聲明式方式操作容器,無須手動創(chuàng)建。可利用如 ContextLoader 的支持類,在 Web 應(yīng)用啟動時自動創(chuàng)建 ApplicationContext。當(dāng)然,也可以采用編程方式創(chuàng)建 ApplicationContext。

    ApplicationContext包括BeanFactory的全部功能,因此建議優(yōu)先使用ApplicationContext。除非對于某些內(nèi)存非常關(guān)鍵的應(yīng)用,才考慮使用 BeanFactory。

    spring為ApplicationContext提供的3種實現(xiàn)分別為:

    1、  ClassPathXmlApplicationContext:利用類路徑的XML文件來載入Bean定義的信息

    [1]  ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");

    [2]  String[] locations = {"bean1.xml", "bean2.xml", "bean3.xml"};

    ApplicationContext ctx = new ClassPathXmlApplication(locations);

    2、 FileSystemXmlApplicationContext:利用文件系統(tǒng)中的XMl文件來載入Bean

    定義的信息

    [1]  ApplicationContext ctx = new FileSystemXmlApplicationContext("bean.xml"); //加載單個配置文件

    [2]  String[] locations = {"bean1.xml", "bean2.xml", "bean3.xml"};

     ApplicationContext ctx = new FileSystemXmlApplicationContext(locations );

    //加載多個配置文件

    [3]  ApplicationContext ctx =new FileSystemXmlApplicationContext("D:/project/bean.xml");

    //根據(jù)具體路徑加載

    3、 XmlWebApplicationContext:從Web系統(tǒng)中的XML文件來載入Bean定義的信息。

     ServletContext servletContext = request.getSession().getServletContext();    

     ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);

     

     

    配置WebApplicationContext的兩種方法:

    (1)        利用Listener接口來實現(xiàn)

    <listener>

           <listener-class>

    org.springframework.web.context.ContextLoaderListener

    </listener-class>

    </listener>

    <context-param>

           <param-name>contextConfigLocation</param-name>

           <param-value>classpath:applicationContext</param-value>

    </context-param>

    (2)        利用Servlet接口來實現(xiàn)

    <context-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>classpath:applicationContext</param-value>

    </context-param>

    <Servlet>

           <servlet-name>context</servlet-name>

           <servlet-class>

               org.springframework.web.context.ContextLoaderServlet

           </servlet-class>

    </servlet>

    posted @ 2015-03-27 14:53 abin 閱讀(403) | 評論 (0)編輯 收藏

    裝飾者模式(Decorator Pattern),是在不必改變原類文件和使用繼承的情況下,動態(tài)的擴展一個對象的功能。它是通過創(chuàng)建一個包裝對象,也就是裝飾來包裹真實的對象。
    使用裝飾者模式的時候需要注意一下幾點內(nèi)容:
    (1)裝飾對象和真實對象有相同的接口。這樣客戶端對象就可以以和真實對象相同的方式和裝飾對象交互。
    (2)裝飾對象包含一個真實對象的引用。
    (3)裝飾對象接受所有的來自客戶端的請求,它把這些請求轉(zhuǎn)發(fā)給真實的對象。
    (4)裝飾對象可以在轉(zhuǎn)發(fā)這些請求以前或以后增加一些附加功能。這樣就確保了在運行時,不用修改給定對象的結(jié)構(gòu)就可以在外部增加附加的功能。在面向?qū)ο蟮脑O(shè)計中,通常是通過繼承來實現(xiàn)對給定類的功能擴展。然而,裝飾者模式,不需要子類可以在應(yīng)用程序運行時,動態(tài)擴展功能,更加方便、靈活。

    適用裝飾者模式場合:
    1.當(dāng)我們需要為某個現(xiàn)有的對象,動態(tài)的增加一個新的功能或職責(zé)時,可以考慮使用裝飾模式。
    2.當(dāng)某個對象的職責(zé)經(jīng)常發(fā)生變化或者經(jīng)常需要動態(tài)的增加職責(zé),避免為了適應(yīng)這樣的變化,而增加繼承子類擴展的方式,因為這種方式會造成子類膨脹的速度過快,難以控制。

    推薦你一本設(shè)計模式方面的優(yōu)秀書籍:鄭阿奇 主編的《軟件秘笈-設(shè)計模式那點事》。里面講解很到位,實例通俗易懂,看了收獲很大!

    posted @ 2015-03-27 00:11 abin 閱讀(903) | 評論 (0)編輯 收藏

    二分查找的基本思想是將n個元素分成大致相等的兩部分,去a[n/2]與x做比較,如果x=a[n/2],則找到x,算法中止;如果x<a[n/2],則只要在數(shù)組a的左半部分繼續(xù)搜索x,如果x>a[n/2],則只要在數(shù)組a的右半部搜索x.

    時間復(fù)雜度無非就是while循環(huán)的次數(shù)!

    總共有n個元素,

    漸漸跟下去就是n,n/2,n/4,....n/2^k,其中k就是循環(huán)的次數(shù)

    由于你n/2^k取整后>=1

    即令n/2^k=1

    可得k=log2n,(是以2為底,n的對數(shù))

    所以時間復(fù)雜度可以表示O()=O(logn)

    posted @ 2015-03-26 16:30 abin 閱讀(635) | 評論 (0)編輯 收藏

    Static 靜態(tài):這里主要記錄的是靜態(tài)程序塊和靜態(tài)方法

    如果有些代碼必須在項目啟動的時候就執(zhí)行,就需要使用靜態(tài)代碼塊,這種代碼是主動執(zhí)行的;需要在項目啟動的時候就初始化但是不執(zhí)行,在不創(chuàng)建對象的情況下,可以供其他程序調(diào)用,而在調(diào)用的時候才執(zhí)行,這需要使用靜態(tài)方法,這種代碼是被動執(zhí)行的. 靜態(tài)方法在類加載的時候 就已經(jīng)加載 可以用類名直接調(diào)用。

    靜態(tài)代碼塊和靜態(tài)方法的區(qū)別是:

    靜態(tài)代碼塊是自動執(zhí)行的;

    靜態(tài)方法是被調(diào)用的時候才執(zhí)行的.

    靜態(tài)方法:如果我們在程序編寫的時候需要一個不實例化對象就可以調(diào)用的方法,我們就可以使用靜態(tài)方法,具體實現(xiàn)是在方法前面加上static,如下:

    public static void method(){}

    在使用靜態(tài)方法的時候需要注意一下幾個方面:

    在靜態(tài)方法里只能直接調(diào)用同類中其他的靜態(tài)成員(包括變量和方法),而不能直接訪問類中的非靜態(tài)成員。這是因為,對于非靜態(tài)的方法和變量,需要先創(chuàng)建類的實例對象后才可使用,而靜態(tài)方法在使用前不用創(chuàng)建任何對象。(備注:靜態(tài)變量是屬于整個類的變量而不是屬于某個對象的)

    靜態(tài)方法不能以任何方式引用this和super關(guān)鍵字,因為靜態(tài)方法在使用前不用創(chuàng)建任何實例對象,當(dāng)靜態(tài)方法調(diào)用時,this所引用的對象根本沒有產(chǎn)生。

    靜態(tài)程序塊:當(dāng)一個類需要在被載入時就執(zhí)行一段程序,這樣可以使用靜態(tài)程序塊。

    public class DemoClass {

    private DemoClass(){}

    public static DemoClass _instance;

    static{

    if(null == _instance ){

    _instance = new DemoClass();

    }

    }

    public static DemoClass getInstance(){

    return _instance;

    }

    }

    這樣的程序在類被加載的時候就執(zhí)行了static中的代碼。

    Ps:java中類的裝載步驟:

    在Java中,類裝載器把一個類裝入Java虛擬機中,要經(jīng)過三個步驟來完成:裝載、鏈接和初始化,其中鏈接又可以分成校驗、準(zhǔn)備和解析三步,除了解析外,其它步驟是嚴(yán)格按照順序完成的,各個步驟的主要工作如下:

    所謂裝載就是尋找一個類或是一個接口的二進制形式并用該二進制形式來構(gòu)造代表這個類或是這個接口的class對象的過程。其中類或接口的名稱是給定了的。

    裝載:查找和導(dǎo)入類或接口的二進制數(shù)據(jù);

    鏈接:執(zhí)行下面的校驗、準(zhǔn)備和解析步驟,其中解析步驟是可以選擇的;

    校驗:檢查導(dǎo)入類或接口的二進制數(shù)據(jù)的正確性;

    準(zhǔn)備:給類的靜態(tài)變量分配并初始化存儲空間;

    解析:將符號引用轉(zhuǎn)成直接引用;

    初始化:激活類的靜態(tài)變量的初始化Java代碼和靜態(tài)Java代碼塊

    posted @ 2015-03-25 15:24 abin 閱讀(331) | 評論 (0)編輯 收藏

    replication的限制:一旦數(shù)據(jù)庫過于龐大,尤其是當(dāng)寫入過于頻繁,很難由一臺主機支撐的時候,我們還是會面臨到擴展瓶頸。數(shù)據(jù)切分(sharding):通過某種特定的條件,將我們存放在同一個數(shù)據(jù)庫中的數(shù)據(jù)分散存放到多個數(shù)據(jù)庫(主機)上面,以達到分散單臺設(shè)備負(fù)載的效果。。數(shù)據(jù)的切分同時還可以提高系統(tǒng)的總體可用性,因為單臺設(shè)備Crash之后,只有總體數(shù)據(jù)的某部分不可用,而不是所有的數(shù)據(jù)。

    數(shù)據(jù)的切分(Sharding)模式

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

    垂直切分:

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

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

    1.用戶模塊表:user,user_profile,user_group,user_photo_album
    2.群組討論表:groups,group_message,group_message_content,top_message
    3.相冊相關(guān)表:photo,photo_album,photo_album_relation,photo_comment
    4.事件信息表:event


    • 群組討論模塊和用戶模塊之間主要存在通過用戶或者是群組關(guān)系來進行關(guān)聯(lián)。一般關(guān)聯(lián)的時候都會是通過用戶的id或者nick_name以及group的id來進行關(guān)聯(lián),通過模塊之間的接口實現(xiàn)不會帶來太多麻煩;
    • 相冊模塊僅僅與用戶模塊存在通過用戶的關(guān)聯(lián)。這兩個模塊之間的關(guān)聯(lián)基本就有通過用戶id關(guān)聯(lián)的內(nèi)容,簡單清晰,接口明確;
    • 事件模塊與各個模塊可能都有關(guān)聯(lián),但是都只關(guān)注其各個模塊中對象的ID信息,同樣可以做到很容易分拆。

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

    • 數(shù)據(jù)庫的拆分簡單明了,拆分規(guī)則明確;
    • 應(yīng)用程序模塊清晰明確,整合容易;
    • 數(shù)據(jù)維護方便易行,容易定位;

    垂直切分的缺點


    • 部分表關(guān)聯(lián)無法在數(shù)據(jù)庫級別完成,需要在程序中完成
    • 對于訪問極其頻繁且數(shù)據(jù)量超大的表仍然存在性能瓶頸,不一定能滿足要求;
    • 事務(wù)處理相對更為復(fù)雜
    • 切分達到一定程度之后,擴展性會遇到限制;
    • 過讀切分可能會帶來系統(tǒng)過渡復(fù)雜而難以維護。

    水平切分

    將某個訪問極其頻繁的表再按照某個字段的某種規(guī)則來分散到多個表之中,每個表中包含一部分?jǐn)?shù)據(jù)。

    對于上面的例子:所有數(shù)據(jù)都是和用戶關(guān)聯(lián)的,那么我們就可以根據(jù)用戶來進行水平拆分,將不同用戶的數(shù)據(jù)切分到不同的數(shù)據(jù)庫中。

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

    水平切分的優(yōu)點


    • 表關(guān)聯(lián)基本能夠在數(shù)據(jù)庫端全部完成;
    • 不會存在某些超大型數(shù)據(jù)量和高負(fù)載的表遇到瓶頸的問題;
    • 應(yīng)用程序端整體架構(gòu)改動相對較少;
    • 事務(wù)處理相對簡單;
    • 只要切分規(guī)則能夠定義好,基本上較難遇到擴展性限制;

    水平切分的缺點

    • 切分規(guī)則相對更為復(fù)雜,很難抽象出一個能夠滿足整個數(shù)據(jù)庫的切分規(guī)則;
    • 后期數(shù)據(jù)的維護難度有所增加,人為手工定位數(shù)據(jù)更困難;
    • 應(yīng)用系統(tǒng)各模塊耦合度較高,可能會對后面數(shù)據(jù)的遷移拆分造成一定的困難。

    兩種切分結(jié)合用:

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

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

    如果我們再一次像最開始那樣繼續(xù)細(xì)分模塊,進行數(shù)據(jù)的垂直切分,那我們可能在不久的將來,又會遇到現(xiàn)在所面對的同樣的問題。而且隨著模塊的不斷的細(xì)化,應(yīng)用系統(tǒng)的架構(gòu)也會越來越復(fù)雜,整個系統(tǒng)很可能會出現(xiàn)失控的局面。

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

    示例數(shù)據(jù)庫:

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

    ==>選擇了在垂直切分的基礎(chǔ)上再進行水平拆分。

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

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

    數(shù)據(jù)庫中的數(shù)據(jù)在經(jīng)過垂直和(或)水平切分被存放在不同的數(shù)據(jù)庫主機之后,應(yīng)用系統(tǒng)面臨的最大問題就是如何來讓這些數(shù)據(jù)源得到較好的整合,其中存在兩種解決思路:

    • 在每個應(yīng)用程序模塊中配置管理自己需要的一個(或者多個)數(shù)據(jù)源,直接訪問各個數(shù)據(jù)庫,在模塊內(nèi)完成數(shù)據(jù)的整合;
    • 通過中間代理層來統(tǒng)一管理所有的數(shù)據(jù)源,后端數(shù)據(jù)庫集群對前端應(yīng)用程序透明;

    第二種方案,雖然短期內(nèi)需要付出的成本可能會相對更大一些,但是對整個系統(tǒng)的擴展性來說,是非常有幫助的。針對第二種方案,可以選擇的方法和思路有:

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

    可用來監(jiān)視、分析或者傳輸他們之間的通訊信息。他的靈活性允許你最大限度的使用它,目前具備的功能主要有連接路由,Query分析,Query過濾和修改,負(fù)載均衡,以及基本的HA機制等。MySQLProxy 本身并不具有上述所有的這些功能,而是提供了實現(xiàn)上述功能的基礎(chǔ)。要實現(xiàn)這些功能,還需要通過我們自行編寫LUA腳本來實現(xiàn)。

    原理:MySQLProxy 實際上是在客戶端請求與MySQLServer 之間建立了一個連接池。所有客戶端請求都是發(fā)向MySQLProxy,然后經(jīng)由MySQLProxy 進行相應(yīng)的分析,判斷出是讀操作還是寫操作,分發(fā)至對應(yīng)的MySQLServer 上。對于多節(jié)點Slave集群,也可以起做到負(fù)載均衡的效果。

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

    Amoeba是一個基于Java開發(fā)的,專注于解決分布式數(shù)據(jù)庫數(shù)據(jù)源整合Proxy程序的開源框架,Amoeba已經(jīng)具有Query路由,Query過濾,讀寫分離,負(fù)載均衡以及HA機制等相關(guān)內(nèi)容。Amoeba主要解決的以下幾個問題:

    • 數(shù)據(jù)切分后復(fù)雜數(shù)據(jù)源整合;
    • 提供數(shù)據(jù)切分規(guī)則并降低數(shù)據(jù)切分規(guī)則給數(shù)據(jù)庫帶來的影響;
    • 降低數(shù)據(jù)庫與客戶端的連接數(shù);
    • 讀寫分離路由;

    AmoebaFor MySQL 主要是專門針對MySQL數(shù)據(jù)庫的解決方案,前端應(yīng)用程序請求的協(xié)議以及后端連接的數(shù)據(jù)源數(shù)據(jù)庫都必須是MySQL。對于客戶端的任何應(yīng)用程序來說,AmoebaForMySQL 和一個MySQL數(shù)據(jù)庫沒有什么區(qū)別,任何使用MySQL協(xié)議的客戶端請求,都可以被AmoebaFor MySQL 解析并進行相應(yīng)的處理。

    Proxy程序常用的功能如讀寫分離,負(fù)載均衡等配置都在amoeba.xml中進行。Amoeba已經(jīng)支持了實現(xiàn)數(shù)據(jù)的垂直切分和水平切分的自動路由,路由規(guī)則可以在rule.xml進行設(shè)置。

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


    HiveDB同樣是一個基于Java針對MySQL數(shù)據(jù)庫的提供數(shù)據(jù)切分及整合的開源框架,只是目前的HiveDB僅僅支持?jǐn)?shù)據(jù)的水平切分。主要解決大數(shù)據(jù)量下數(shù)據(jù)庫的擴展性及數(shù)據(jù)的高性能訪問問題,同時支持?jǐn)?shù)據(jù)的冗余及基本的HA機制。

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

    引入分布式事務(wù)的問題?

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

    ==>將一個跨多個數(shù)據(jù)庫的分布式事務(wù)分拆成多個僅處于單個數(shù)據(jù)庫上面的小事務(wù),并通過應(yīng)用程序來總控各個小事務(wù)。

    跨節(jié)點Join的問題?


    ==>先從一個節(jié)點取出數(shù)據(jù),然后根據(jù)這些數(shù)據(jù),再到另一個表中取數(shù)據(jù).
    ==>使用Federated存儲引擎,問題是:乎如果遠(yuǎn)端的表結(jié)構(gòu)發(fā)生了變更,本地的表定義信息是不會跟著發(fā)生相應(yīng)變化的。

    跨節(jié)點合并排序分頁問題?

    ==>Join本身涉及到的多個表之間的數(shù)據(jù)讀取一般都會存在一個順序關(guān)系。但是排序分頁就不太一樣了,排序分頁的數(shù)據(jù)源基本上可以說是一個表(或者一個結(jié)果集),本身并不存在一個順序關(guān)系,所以在從多個數(shù)據(jù)源取數(shù)據(jù)的過程是完全可以并行的。這樣,排序分頁數(shù)據(jù)的取數(shù)效率我們可以做的比跨庫Join更高,所以帶來的性能損失相對的要更小。  
    posted @ 2015-03-24 16:13 abin 閱讀(852) | 評論 (0)編輯 收藏

    前言

    有人反饋之前幾篇文章過于理論缺少實際操作細(xì)節(jié),這篇文章就多一些可操作性的內(nèi)容吧。

    注:這篇文章是以 MySQL 為背景,很多內(nèi)容同時適用于其他關(guān)系型數(shù)據(jù)庫,需要有一些索引知識為基礎(chǔ)。

     

    優(yōu)化目標(biāo)

      1.減少 IO 次數(shù)

      IO永遠(yuǎn)是數(shù)據(jù)庫最容易瓶頸的地方,這是由數(shù)據(jù)庫的職責(zé)所決定的,大部分?jǐn)?shù)據(jù)庫操作中超過90%的時間都是 IO 操作所占用的,減少 IO 次數(shù)是 SQL 優(yōu)化中需要第一優(yōu)先考慮,當(dāng)然,也是收效最明顯的優(yōu)化手段。

      2.降低 CPU 計算

      除了 IO 瓶頸之外,SQL優(yōu)化中需要考慮的就是 CPU 運算量的優(yōu)化了。order by, group by,distinct … 都是消耗 CPU 的大戶(這些操作基本上都是 CPU 處理內(nèi)存中的數(shù)據(jù)比較運算)。當(dāng)我們的 IO 優(yōu)化做到一定階段之后,降低 CPU 計算也就成為了我們 SQL 優(yōu)化的重要目標(biāo)

     

    優(yōu)化方法

      改變 SQL 執(zhí)行計劃

      明確了優(yōu)化目標(biāo)之后,我們需要確定達到我們目標(biāo)的方法。對于 SQL 語句來說,達到上述2個目標(biāo)的方法其實只有一個,那就是改變 SQL 的執(zhí)行計劃,讓他盡量“少走彎路”,盡量通過各種“捷徑”來找到我們需要的數(shù)據(jù),以達到 “減少 IO 次數(shù)” 和 “降低 CPU 計算” 的目標(biāo)

     

    常見誤區(qū)

     

    1.count(1)和count(primary_key) 優(yōu)于 count(*)

      很多人為了統(tǒng)計記錄條數(shù),就使用 count(1) 和 count(primary_key) 而不是 count(*) ,他們認(rèn)為這樣性能更好,其實這是一個誤區(qū)。對于有些場景,這樣做可能性能會更差,應(yīng)為數(shù)據(jù)庫對 count(*) 計數(shù)操作做了一些特別的優(yōu)化。

     

    2.count(column) 和 count(*) 是一樣的

      這個誤區(qū)甚至在很多的資深工程師或者是 DBA 中都普遍存在,很多人都會認(rèn)為這是理所當(dāng)然的。實際上,count(column) 和 count(*) 是一個完全不一樣的操作,所代表的意義也完全不一樣。

      count(column) 是表示結(jié)果集中有多少個column字段不為空的記錄

      count(*) 是表示整個結(jié)果集有多少條記錄

     

    3.select a,b from … 比 select a,b,c from … 可以讓數(shù)據(jù)庫訪問更少的數(shù)據(jù)量

      這個誤區(qū)主要存在于大量的開發(fā)人員中,主要原因是對數(shù)據(jù)庫的存儲原理不是太了解。

      實際上,大多數(shù)關(guān)系型數(shù)據(jù)庫都是按照行(row)的方式存儲,而數(shù)據(jù)存取操作都是以一個固定大小的IO單元(被稱作 block 或者 page)為單位,一般為4KB,8KB… 大多數(shù)時候,每個IO單元中存儲了多行,每行都是存儲了該行的所有字段(lob等特殊類型字段除外)。

      所以,我們是取一個字段還是多個字段,實際上數(shù)據(jù)庫在表中需要訪問的數(shù)據(jù)量其實是一樣的。

      當(dāng)然,也有例外情況,那就是我們的這個查詢在索引中就可以完成,也就是說當(dāng)只取 a,b兩個字段的時候,不需要回表,而c這個字段不在使用的索引中,需要回表取得其數(shù)據(jù)。在這樣的情況下,二者的IO量會有較大差異。

     

    4.order by 一定需要排序操作

      我們知道索引數(shù)據(jù)實際上是有序的,如果我們的需要的數(shù)據(jù)和某個索引的順序一致,而且我們的查詢又通過這個索引來執(zhí)行,那么數(shù)據(jù)庫一般會省略排序操作,而直接將數(shù)據(jù)返回,因為數(shù)據(jù)庫知道數(shù)據(jù)已經(jīng)滿足我們的排序需求了。

      實際上,利用索引來優(yōu)化有排序需求的 SQL,是一個非常重要的優(yōu)化手段

      延伸閱讀:MySQL ORDER BY 的實現(xiàn)分析,MySQL 中 GROUP BY 基本實現(xiàn)原理以及 MySQL DISTINCT 的基本實現(xiàn)原理這3篇文章中有更為深入的分析,尤其是第一篇

     

    5.執(zhí)行計劃中有 filesort 就會進行磁盤文件排序

      有這個誤區(qū)其實并不能怪我們,而是因為 MySQL 開發(fā)者在用詞方面的問題。filesort 是我們在使用 explain 命令查看一條 SQL 的執(zhí)行計劃的時候可能會看到在 “Extra” 一列顯示的信息。

      實際上,只要一條 SQL 語句需要進行排序操作,都會顯示“Using filesort”,這并不表示就會有文件排序操作。

     

    基本原則

    1.盡量少 join

      MySQL 的優(yōu)勢在于簡單,但這在某些方面其實也是其劣勢。MySQL 優(yōu)化器效率高,但是由于其統(tǒng)計信息的量有限,優(yōu)化器工作過程出現(xiàn)偏差的可能性也就更多。對于復(fù)雜的多表 Join,一方面由于其優(yōu)化器受限,再者在 Join 這方面所下的功夫還不夠,所以性能表現(xiàn)離 Oracle 等關(guān)系型數(shù)據(jù)庫前輩還是有一定距離。但如果是簡單的單表查詢,這一差距就會極小甚至在有些場景下要優(yōu)于這些數(shù)據(jù)庫前輩。

     

    2.盡量少排序

      排序操作會消耗較多的 CPU 資源,所以減少排序可以在緩存命中率高等 IO 能力足夠的場景下會較大影響 SQL 的響應(yīng)時間。

      對于MySQL來說,減少排序有多種辦法,比如:

      上面誤區(qū)中提到的通過利用索引來排序的方式進行優(yōu)化

      減少參與排序的記錄條數(shù)

      非必要不對數(shù)據(jù)進行排序

      …

     

    3.盡量避免 select *

      很多人看到這一點后覺得比較難理解,上面不是在誤區(qū)中剛剛說 select 子句中字段的多少并不會影響到讀取的數(shù)據(jù)嗎?

      是的,大多數(shù)時候并不會影響到 IO 量,但是當(dāng)我們還存在 order by 操作的時候,select 子句中的字段多少會在很大程度上影響到我們的排序效率,這一點可以通過我之前一篇介紹 MySQL ORDER BY 的實現(xiàn)分析的文章中有較為詳細(xì)的介紹。

      此外,上面誤區(qū)中不是也說了,只是大多數(shù)時候是不會影響到 IO 量,當(dāng)我們的查詢結(jié)果僅僅只需要在索引中就能找到的時候,還是會極大減少 IO 量的。

     

    4.盡量用 join 代替子查詢

      雖然 Join 性能并不佳,但是和 MySQL 的子查詢比起來還是有非常大的性能優(yōu)勢。MySQL 的子查詢執(zhí)行計劃一直存在較大的問題,雖然這個問題已經(jīng)存在多年,但是到目前已經(jīng)發(fā)布的所有穩(wěn)定版本中都普遍存在,一直沒有太大改善。雖然官方也在很早就承認(rèn)這一問題,并且承諾盡快解決,但是至少到目前為止我們還沒有看到哪一個版本較好的解決了這一問題。

     

    5.盡量少 or

      當(dāng) where 子句中存在多個條件以“或”并存的時候,MySQL 的優(yōu)化器并沒有很好的解決其執(zhí)行計劃優(yōu)化問題,再加上 MySQL 特有的 SQL 與 Storage 分層架構(gòu)方式,造成了其性能比較低下,很多時候使用 union all 或者是union(必要的時候)的方式來代替“or”會得到更好的效果。

     

    6.盡量用 union all 代替 union

      union 和 union all 的差異主要是前者需要將兩個(或者多個)結(jié)果集合并后再進行唯一性過濾操作,這就會涉及到排序,增加大量的 CPU 運算,加大資源消耗及延遲。所以當(dāng)我們可以確認(rèn)不可能出現(xiàn)重復(fù)結(jié)果集或者不在乎重復(fù)結(jié)果集的時候,盡量使用 union all 而不是 union。

     

    7.盡量早過濾

      這一優(yōu)化策略其實最常見于索引的優(yōu)化設(shè)計中(將過濾性更好的字段放得更靠前)。

      在 SQL 編寫中同樣可以使用這一原則來優(yōu)化一些 Join 的 SQL。比如我們在多個表進行分頁數(shù)據(jù)查詢的時候,我們最好是能夠在一個表上先過濾好數(shù)據(jù)分好頁,然后再用分好頁的結(jié)果集與另外的表 Join,這樣可以盡可能多的減少不必要的 IO 操作,大大節(jié)省 IO 操作所消耗的時間。

     

    8.避免類型轉(zhuǎn)換

      這里所說的“類型轉(zhuǎn)換”是指 where 子句中出現(xiàn) column 字段的類型和傳入的參數(shù)類型不一致的時候發(fā)生的類型轉(zhuǎn)換:

      人為在column_name 上通過轉(zhuǎn)換函數(shù)進行轉(zhuǎn)換

      直接導(dǎo)致 MySQL(實際上其他數(shù)據(jù)庫也會有同樣的問題)無法使用索引,如果非要轉(zhuǎn)換,應(yīng)該在傳入的參數(shù)上進行轉(zhuǎn)換

      由數(shù)據(jù)庫自己進行轉(zhuǎn)換

      如果我們傳入的數(shù)據(jù)類型和字段類型不一致,同時我們又沒有做任何類型轉(zhuǎn)換處理,MySQL 可能會自己對我們的數(shù)據(jù)進行類型轉(zhuǎn)換操作,也可能不進行處理而交由存儲引擎去處理,這樣一來,就會出現(xiàn)索引無法使用的情況而造成執(zhí)行計劃問題。

     

    9.優(yōu)先優(yōu)化高并發(fā)的 SQL,而不是執(zhí)行頻率低某些“大”SQL

      對于破壞性來說,高并發(fā)的 SQL 總是會比低頻率的來得大,因為高并發(fā)的 SQL 一旦出現(xiàn)問題,甚至不會給我們?nèi)魏未⒌臋C會就會將系統(tǒng)壓跨。而對于一些雖然需要消耗大量 IO 而且響應(yīng)很慢的 SQL,由于頻率低,即使遇到,最多就是讓整個系統(tǒng)響應(yīng)慢一點,但至少可能撐一會兒,讓我們有緩沖的機會。

     

    10.從全局出發(fā)優(yōu)化,而不是片面調(diào)整

      SQL 優(yōu)化不能是單獨針對某一個進行,而應(yīng)充分考慮系統(tǒng)中所有的 SQL,尤其是在通過調(diào)整索引優(yōu)化 SQL 的執(zhí)行計劃的時候,千萬不能顧此失彼,因小失大。

     

    11.盡可能對每一條運行在數(shù)據(jù)庫中的SQL進行 explain

      優(yōu)化 SQL,需要做到心中有數(shù),知道 SQL 的執(zhí)行計劃才能判斷是否有優(yōu)化余地,才能判斷是否存在執(zhí)行計劃問題。在對數(shù)據(jù)庫中運行的 SQL 進行了一段時間的優(yōu)化之后,很明顯的問題 SQL 可能已經(jīng)很少了,大多都需要去發(fā)掘,這時候就需要進行大量的 explain 操作收集執(zhí)行計劃,并判斷是否需要進行優(yōu)化。

     

    原文地址:http://isky000.com/database/mysql-performance-tuning-sql

    posted @ 2015-03-24 15:51 abin 閱讀(370) | 評論 (0)編輯 收藏

    一,單一Bean

    • 裝載

    1. 實例化; 
    2. 設(shè)置屬性值; 
    3. 如果實現(xiàn)了BeanNameAware接口,調(diào)用setBeanName設(shè)置Bean的ID或者Name; 
    4. 如果實現(xiàn)BeanFactoryAware接口,調(diào)用setBeanFactory 設(shè)置BeanFactory; 
    5. 如果實現(xiàn)ApplicationContextAware,調(diào)用setApplicationContext設(shè)置ApplicationContext 
    6. 調(diào)用BeanPostProcessor的預(yù)先初始化方法; 
    7. 調(diào)用InitializingBean的afterPropertiesSet()方法; 
    8. 調(diào)用定制init-method方法; 
    9. 調(diào)用BeanPostProcessor的后初始化方法;

    • spring容器關(guān)閉

    1. 調(diào)用DisposableBean的destroy(); 
    2. 調(diào)用定制的destroy-method方法;

     

    二,多個Bean的先后順序

    • 優(yōu)先加載BeanPostProcessor的實現(xiàn)Bean
    • 按Bean文件和Bean的定義順序按bean的裝載順序(即使加載多個spring文件時存在id覆蓋)
    • “設(shè)置屬性值”(第2步)時,遇到ref,則在“實例化”(第1步)之后先加載ref的id對應(yīng)的bean
    • AbstractFactoryBean的子類,在第6步之后,會調(diào)用createInstance方法,之后會調(diào)用getObjectType方法
    • BeanFactoryUtils類也會改變Bean的加載順序
    posted @ 2015-03-23 22:10 abin 閱讀(629) | 評論 (0)編輯 收藏

    僅列出標(biāo)題
    共50頁: First 上一頁 2 3 4 5 6 7 8 9 10 下一頁 Last 
    主站蜘蛛池模板: 福利免费观看午夜体检区| 无码亚洲成a人在线观看| 亚洲色图国产精品| 亚洲成色在线综合网站| 黑人精品videos亚洲人| 久久国产亚洲电影天堂| 亚洲va在线va天堂va888www| 亚洲av日韩综合一区在线观看| 亚洲国产精品特色大片观看完整版 | 亚洲色图在线播放| 亚洲精品美女视频| 亚洲制服在线观看| 亚洲色少妇熟女11p| 色天使色婷婷在线影院亚洲| 成年免费a级毛片| a级毛片免费观看视频| 久久久久久AV无码免费网站| 91热成人精品国产免费| 免费A级毛片无码免费视| 日韩视频在线免费| 亚洲熟女乱综合一区二区| 国产亚洲无线码一区二区| 亚洲尹人九九大色香蕉网站| 亚洲av无码电影网| 色婷婷亚洲一区二区三区| 国产免费久久精品丫丫| 日韩精品无码一区二区三区免费 | 亚洲AV无码片一区二区三区| 青青视频免费在线| 免费看黄的成人APP| 男女免费观看在线爽爽爽视频 | 在线观看免费黄网站| 日韩精品久久久久久免费| 丁香花在线观看免费观看| 五月婷婷亚洲综合| 亚洲精品无码不卡| 亚洲AV性色在线观看| 日韩精品无码免费专区网站| 免费成人福利视频| 亚洲精品老司机在线观看| 亚洲视频在线免费观看|