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

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

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

    心有多大舞臺便有多大

    Embrace changes, pursue excellence, share niceness.

    hessian序列化協議+memcached的緩存存取

    大名鼎鼎的memcached恐怕沒人不知道吧!hessian是一種遠程調用的機制,類似與web service,不過它是使用自己的序列化協議.
    那么,為什么要把hessian的序列化協議和memcached結合起來實現緩存的讀取呢?
    有過使用memcached的經驗的人會了解到,php+memcached的性能是最好的,java+memcached的性能比較差,其主要原因就是在于java本身的序列化機制很慢.
    我做了個簡單的測試,一個UserData類,有一個字符串屬性,一個日期屬性,一個double屬性,分別用java,hessian來序列化一百萬次,結果讓人吃驚,不止是hessian序列化的速度要比java的快上一倍,而且hessian序列化后的字節數也要比java的少一倍.因為我在測試的時候只是做了序列化這部分的工作,并沒有把序列化后的結果放到網絡上傳輸,所以,實際中的性能hessian應該會更好!
    既然hessian的序列化協議要比java本身的好,而memcached客戶端的性能又在很大程度上依賴與對象的序列化.所以,我就決定把我的cache實現中序列化這部分的工作改成用hessian來實現了.
    我用的memcached客戶端是用的danga.MemCached包,主要是改動了MemCachedClient的get方法及set方法,在set方法中改為調用hessian的序列化:
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    //修改以前的序列化代碼:
     //(new ObjectOutputStream( bos )).writeObject( value );
    //修改后的序列化代碼:
    serializeByHessian(bos, value);
     val = bos.toByteArray();
    serializeByHessian方法如下:

     protected void serializeByHessian(OutputStream os, Object object) throws IOException {
            AbstractHessianOutput out = new Hessian2Output(os);;
            SerializerFactory serializerFactory = getSerializerFactory();
            out.setSerializerFactory(serializerFactory);
            out.startReply();
            out.writeObject(object);     
            out.completeReply();
            out.flush();
     }
    在get方法中主要是修改了這個方法調用的類ContextObjectInputStream的readObject方法:
    在ContextObjectInputStream中覆蓋了readObjectOverride方法:
     protected Object readObjectOverride() throws IOException,  ClassNotFoundException {
            ByteArrayInputStream is = new ByteArrayInputStream(bytes);
            ClHessian2Input in = new ClHessian2Input(is, this.mLoader);
            in.setSerializerFactory(getSerializerFactory());
            int code = in.read();//"r"
            int major = in.read();//>=2
            int minor = in.read();//0
            Object value = in.readObject();
            is.close();
            return value;
     }
    因為我的框架是基于osgi的,所以我重載了Hessian2Input,把classloader作為參數傳進去,否則hessian在反序列化的時候會找不到類.如果你沒有用osgi框架的話, ClHessian2Input in = new ClHessian2Input(is, this.mLoader);這行代碼就可以直接用: Hessian2Input in = new Hessian2Input(is);
    這樣修改就基本完成了.
    我把memcached client的序列化協議改為hessian也有另外一個系統架構的原因,那就是因為我的服務層邏輯都是用java+spring+osgi的方式實現,而web層則是用php實現,兩者之間通訊已經是采用hessian的遠程調用.所以,部分緩存數據在服務層通過java設置到memcached服務器中,在php中一樣可以用memcached php client讀取出來.(php的memcached client我用的是memcached-client.php,而不是php擴展,所以一樣可以修改memcached-client.php的序列化機制)


    posted on 2008-06-18 10:04 pony 閱讀(7874) 評論(11)  編輯  收藏 所屬分類: Java

    評論

    # re: hessian序列化協議+memcached的緩存存取 2008-06-18 10:17 pony

    另外附帶說一句,我的經驗,在使用memcached的時候,客戶端在創建socket連接時最好把nagle設置為false.熟悉tcp協議的都知道setTcpNoDelay有什么作用.如果Tcp_NoDelay被設置為true,那么發送數據包時將使用nagle算法對要發送的數據進行緩存處理,只有當達到一定數量之后才把包發送出去,設置為false則立即發送包.對于memcached緩存,一般我們放進去的數據,以及發送的get命令都是很小的包,為了將數據及時傳輸出去,所以要禁用nagle.  回復  更多評論   

    # re: hessian序列化協議+memcached的緩存存取 2008-06-18 10:35 CHINA BAIDU

    不錯1!  回復  更多評論   

    # re: hessian序列化協議+memcached的緩存存取 2008-06-18 12:19 dennis

    @pony
    很好的帖子,不知道換成了hession有沒有測試數據?
    對于setTcpNoDelay說反了吧?setTcpNoDelay為true,就是設置TCP_NODELAY,也就是禁掉Nagle算法;默認就是false,表示啟用Nagle算法。禁掉Nagle算法可以提高響應性,相應地會降低吞吐量,在這個場景中沒啥必要。



      回復  更多評論   

    # re: hessian序列化協議+memcached的緩存存取 2008-06-18 13:24 lizongbo

    hession 的序列化效率確實不錯,

    不過需要序列化的對象,試過實現java.io.Externalizable接口的方式沒?


      回復  更多評論   

    # re: hessian序列化協議+memcached的緩存存取 2008-06-18 13:41 pony

    @dennis
    測試hessian和java序列化的代碼,寫的不好請見諒^_^
    由于把數據存儲到memcached服務器中跟網絡環境,內存有很大關系,跟memcached client設置的參數也有很大關系,所以就不做memcached的存取測試了.

    下面的代碼在我的機器上的結果是:
    serialize 1000000 users with hessian spend 8 seconds, total size:93000000
    serialize 1000000 users with java spend 17 seconds, total size:190000000

    /**
    * Created at 2008-06-13.
    * 測試比較java和hessian的序列化效率.
    */
    import java.io.ByteArrayOutputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    import java.util.Date;

    import com.caucho.hessian.io.AbstractHessianOutput;
    import com.caucho.hessian.io.Hessian2Output;
    import com.caucho.hessian.io.SerializerFactory;

    /**
    * @author pony
    *
    * 如果有任何對代碼的修改,請按下面的格式注明修改的內容.
    * 序號 時間 作者 修改內容
    * 1. 2008-6-13 pony created this class.
    */
    public class TestSerializerPerformanceFucntion {
    //序列化次數.
    private static final int COUNT = 1000000;

    private SerializerFactory factory;

    public static void main(String[] args) throws Exception {
    new TestSerializerPerformanceFucntion().testHessianSerializer();
    new TestSerializerPerformanceFucntion().testJavaSerializer();
    }

    public void testHessianSerializer() throws Exception {
    long curr = new Date().getTime();
    int size = COUNT;
    int len = 0;
    for (int i=0; i<size; i++) {
    User user = new User();
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    AbstractHessianOutput out = new Hessian2Output(os);;
    SerializerFactory serializerFactory = getSerializerFactory();
    out.setSerializerFactory(serializerFactory);
    out.startReply();
    out.writeObject(user);
    out.completeReply();
    out.flush();
    os.flush();
    len += os.size();
    out.close();
    }
    long now = new Date().getTime();
    System.out.println("serialize " + size + " users with hessian spend " + (now-curr)/1000 + " seconds, total size:" + len);
    }

    public void testJavaSerializer() throws Exception {
    long curr = new Date().getTime();
    int size = COUNT;
    int len = 0;
    for (int i=0; i<size; i++) {
    User user = new User();
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    new ObjectOutputStream(os).writeObject(user);
    os.flush();
    len += os.size();
    os.close();
    }
    long now = new Date().getTime();
    System.out.println("serialize " + size + " users with java spend " + (now-curr)/1000 + " seconds, total size:" + len);
    }

    public SerializerFactory getSerializerFactory() {
    if (null == factory) {
    factory = new SerializerFactory();
    }
    return factory;
    }
    }


    class User implements Serializable {
    /**
    * serial Version UID.
    */
    private static final long serialVersionUID = -4845300297590675952L;

    private String name = "test name";

    private Date birthday = new Date();

    private int age = 10;

    private double money = 1000.56;

    /**
    * @return the name
    */
    public String getName() {
    return name;
    }

    /**
    * @param name the name to set
    */
    public void setName(String name) {
    this.name = name;
    }

    /**
    * @return the birthday
    */
    public Date getBirthday() {
    return birthday;
    }

    /**
    * @param birthday the birthday to set
    */
    public void setBirthday(Date birthday) {
    this.birthday = birthday;
    }

    /**
    * @return the age
    */
    public int getAge() {
    return age;
    }

    /**
    * @param age the age to set
    */
    public void setAge(int age) {
    this.age = age;
    }

    /**
    * @return the money
    */
    public double getMoney() {
    return money;
    }

    /**
    * @param money the money to set
    */
    public void setMoney(double money) {
    this.money = money;
    }

    /**
    * @return the serialVersionUID
    */
    public static long getSerialVersionUID() {
    return serialVersionUID;
    }
    }  回復  更多評論   

    # re: hessian序列化協議+memcached的緩存存取 2008-06-18 13:54 pony

    @lizongbo
    謝謝!這是個好建議!試過之后,只有驚訝!結果是比hessian的還快了!
    運行結果是:
    serialize 1000000 users with hessian spend 10 seconds, total size:93000000
    serialize 1000000 users with java spend 9 seconds, total size:86000000

    把上面代碼中的Serializable 改為
    Externalizable,實現下面兩個方法:
    public void readExternal(ObjectInput in) throws IOException,
    ClassNotFoundException {
    String name = in.readUTF();
    long time = in.readLong();
    int age = in.readInt();
    double money = in.readDouble();
    this.setName(name);
    this.setBirthday(new Date(time));
    this.setAge(age);
    this.setMoney(money);
    }

    public void writeExternal(ObjectOutput out) throws IOException {
    out.writeUTF(name);
    out.writeLong(birthday.getTime());
    out.writeInt(age);
    out.writeDouble(money);
    }

    不過因為從架構上考慮,我要用php來讀取cache中的內容,所以我希望序列化后的對象能遵循一個統一的協議,所以,我暫時還是要用hessian的方式.  回復  更多評論   

    # re: hessian序列化協議+memcached的緩存存取 2008-12-04 10:31 LiMengyan

    博主能否來個hessian序集?講講hessian部署的結構?我想看看hessian這個服務模塊是怎么給其他應用提供服務的?  回復  更多評論   

    # re: hessian序列化協議+memcached的緩存存取 2010-09-20 11:00 thebye85

    @pony
    怎么我這邊測試還是hessian快  回復  更多評論   

    # re: hessian序列化協議+memcached的緩存存取[未登錄] 2010-10-05 16:38 Jeff

    好文章!  回復  更多評論   

    # re: hessian序列化協議+memcached的緩存存取[未登錄] 2011-06-24 12:03 HK

    好文啊!  回復  更多評論   

    # re: hessian序列化協議+memcached的緩存存取[未登錄] 2013-12-19 15:40 sa

    hessian4.0.7有一個bigdecimal序列化的bug  回復  更多評論   

    主站蜘蛛池模板: 亚洲AV综合色区无码另类小说| 国产免费久久精品久久久| 亚洲精品无码久久久影院相关影片| 亚洲精品色在线网站| 免费无码看av的网站| 亚洲国产精品无码中文lv| 热99re久久免费视精品频软件| 亚洲最大av资源站无码av网址| 成人黄动漫画免费网站视频 | 9i9精品国产免费久久| 成人午夜亚洲精品无码网站| 白白色免费在线视频| 成人亚洲综合天堂| 波霸在线精品视频免费观看| 亚洲精品无码永久中文字幕| 久久青草精品38国产免费| 久久亚洲精品国产精品| 日本免费人成在线网站| 亚洲国产精品免费在线观看| 成人免费视频试看120秒| 精品国产亚洲一区二区三区在线观看| 亚洲AⅤ视频一区二区三区| 国产免费福利体检区久久| 亚洲av日韩av无码黑人| 999国内精品永久免费观看| 亚洲人成色777777精品| 免费国产成人午夜电影| 一区免费在线观看| 亚洲视频在线观看一区| 毛片免费视频观看| 一级做a爰黑人又硬又粗免费看51社区国产精品视 | 欧洲亚洲国产清在高| 91精品免费不卡在线观看| 亚洲性无码一区二区三区| 免费在线看片网站| 一级做a爰全过程免费视频| 亚洲制服丝袜精品久久| 免费少妇a级毛片人成网| a在线观看免费网址大全| 亚洲午夜精品一区二区公牛电影院 | 伊人免费在线观看|