[Java programming language only]

ObjectTransformer 插件

[Java programming language only]使用 ObjectTransformer 插件,您可以序列化、反序列化和复制高速缓存中的对象,从而提高性能。

Deprecated featureObjectTransformer 接口已由 DataSerializer 插件替代,您可使用这些插件在 WebSphere® eXtreme Scale 中有效存储任意数据,以便现有产品 API 能够有效与您的数据进行交互。

如果您发现与处理器使用率相关的性能问题,请将 ObjectTransformer 插件添加到每个映射。如果未提供 ObjectTransformer 插件,那么会花费多达总处理器时间的 60-70% 的时间来序列化和复制条目。

作用

使用 ObjectTransformer 的插件,应用程序可以为以下操作提供定制方法:
  • 序列化或反序列化条目的键
  • 序列化或反序列化条目的值
  • 复制条目的键或值

如果未提供 ObjectTransformer 插件,那么由于 ObjectGrid 使用序列化和反序列化序列来复制对象,因此您必须可以序列化键和值。此方法开销很高,因此在性能至关重要时,使用 ObjectTransformer 插件。应用程序首次在事务中查找对象时会进行复制。您可以通过将映射的复制方式设置为 NO_COPY 来避免进行此复制,或通过将复制方式设置为 COPY_ON_READ 来减少进行此复制。通过在此插件上提供定制复制方法来在应用程序需要的情况下优化复制操作。此类插件可将复制开销从总处理器时间的 65-70% 降低为总处理器时间的 2/3。

缺省 copyKeycopyValue 方法实现首次尝试使用 clone 方法(如果提供了此方法)。如果未提供 clone 方法实现,那么实现会缺省为序列化。

eXtreme Scale 在分布式方式下运行时,还会直接使用对象序列化。LogSequence 使用 ObjectTransformer 插件,以帮助在将更改传输到 ObjectGrid 中对等项之前序列化键和值。您在提供定制序列化方法而不是使用内置 Java™ 开发者套件序列化时,必须谨慎。对象版本控制是一个复杂的问题,如果您不确保定制方法针对版本控制而设计,那么可能会遇到版本兼容性问题。

以下列表描述 eXtreme Scale 如何尝试同时序列化键和值:
  • 如果编写和插入定制 ObjectTransformer 插件,那么 eXtreme Scale 会调用 ObjectTransformer 接口中的方法,来序列化键和值以及获取对象键和值的副本。
  • 如果未使用定制 ObjectTransformer 插件,那么 eXtreme Scale 会根据缺省值序列化和反序列化值。如果使用缺省插件,那么会将每个对象作为 Externalizable 或 Serializable 来实现。
    • 如果对象支持 Externalizable 接口,那么会调用 writeExternal 方法。作为 Externalizable 实现的对象性能更高。
    • 如果对象不支持 Externalizable 接口且实现 Serializable 接口,那么此对象会使用 ObjectOutputStream 方法进行保存。

使用 ObjectTransformer 接口

ObjectTransformer 对象必须实现 ObjectTransformer 接口并遵循公共 ObjectGrid 插件约定。

可以通过两种方法(程序配置和 XML 配置)来将 ObjectTransformer 对象添加到 BackingMap 配置,如下所示。

通过编程方式插入 ObjectTransformer 对象

以下代码片段创建定制 ObjectTransformer 对象,并将其添加到 BackingMap:
ObjectGridManager objectGridManager = ObjectGridManagerFactory.getObjectGridManager();
ObjectGrid myGrid = objectGridManager.createObjectGrid("myGrid", false);
BackingMap backingMap = myGrid.getMap("myMap");
MyObjectTransformer myObjectTransformer = new MyObjectTransformer();
backingMap.setObjectTransformer(myObjectTransformer);

用于插入 ObjectTransformer 的 XML 配置方法

假定 ObjectTransformer 实现的类名是 com.company.org.MyObjectTransformer 类。此类实现 ObjectTransformer 接口。可以使用以下 XML 配置 ObjectTransformer 实现:
<?xml version="1.0" encoding="UTF-8"?>
<objectGridConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://ibm.com/ws/objectgrid/config ../objectGrid.xsd"
    xmlns="http://ibm.com/ws/objectgrid/config">
    <objectGrids>
        <objectGrid name="myGrid">
	    	    <backingMap name="myMap" pluginCollectionRef="myMap" />
        </objectGrid>
    </objectGrids>

    <backingMapPluginCollections>
		<backingMapPluginCollection id="myMap">
	     	     <bean id="ObjectTransformer" className="com.company.org.MyObjectTransformer" />
	</backingMapPluginCollection>
    </backingMapPluginCollections>
</objectGridConfig>

ObjectTransformer 使用场景

您可以在以下情况下使用 ObjectTransformer 插件:
  • 不可序列化的对象
  • 可序列化的对象,但提高序列化性能
  • 键或值副本
在以下示例中,使用 ObjectGrid 来存储 Stock 类:
/**
* Stock object for ObjectGrid demo
*
*
*/
public class Stock implements Cloneable {
    String ticket;
    double price;
    String company;
    String description;
    int serialNumber;
    long lastTransactionTime;
    /**
    * @return Returns the description.
    */
    public String getDescription() {
        return description;
    }
    /**
    * @param description The description to set.
    */
    	public void setDescription(String description) {
              this.description = description;
    }
    /**
    * @return Returns the lastTransactionTime.
    */
    public long getLastTransactionTime() {
        return lastTransactionTime;
    }
    /**
    * @param lastTransactionTime The lastTransactionTime to set.
    */
    public void setLastTransactionTime(long lastTransactionTime) {
        this.lastTransactionTime = lastTransactionTime;
    }
    /**
    * @return Returns the price.
    */
    public double getPrice() {
        return price;
    }
    /**
    * @param price The price to set.
    */
    public void setPrice(double price) {
        		this.price = price;
    }
    /**
    * @return Returns the serialNumber.
    */
    public int getSerialNumber() {
        return serialNumber;
    }
    /**
    * @param serialNumber The serialNumber to set.
    */
    public void setSerialNumber(int serialNumber) {
        this.serialNumber = serialNumber;
    }
    /**
    * @return Returns the ticket.
    */
    public String getTicket() {
        return ticket;
    }
    /**
    * @param ticket The ticket to set.
    */
    public void setTicket(String ticket) {
        this.ticket = ticket;
    }
    /**
    * @return Returns the company.
    */
    public String getCompany() {
        return company;
    }
    /**
    * @param company The company to set.
    */
    public void setCompany(String company) {
        this.company = company;
    }
    //clone
    public Object clone() throws CloneNotSupportedException
    {
              return super.clone();
    }
}

您可以为 Stock 类编写定制 Object Transformer 类:

/**
* Custom implementation of ObjectGrid ObjectTransformer for stock object
*
*/
public class MyStockObjectTransformer implements ObjectTransformer {
/* (non−Javadoc)
* @see
* com.ibm.websphere.objectgrid.plugins.ObjectTransformer#serializeKey
* (java.lang.Object,
* java.io.ObjectOutputStream)
*/
public void serializeKey(Object key, ObjectOutputStream stream) throws IOException {
    String ticket= (String) key;
    stream.writeUTF(ticket);
}

/* (non−Javadoc)
* @see com.ibm.websphere.objectgrid.plugins.
ObjectTransformer#serializeValue(java.lang.Object,
java.io.ObjectOutputStream)
*/
public void serializeValue(Object value, ObjectOutputStream stream) throws IOException {
    Stock stock= (Stock) value;
    stream.writeUTF(stock.getTicket());
    stream.writeUTF(stock.getCompany());
    stream.writeUTF(stock.getDescription());
    stream.writeDouble(stock.getPrice());
    stream.writeLong(stock.getLastTransactionTime());
    stream.writeInt(stock.getSerialNumber());
}

/* (non−Javadoc)
* @see com.ibm.websphere.objectgrid.plugins.
ObjectTransformer#inflateKey(java.io.ObjectInputStream)
*/
public Object inflateKey(ObjectInputStream stream) throws IOException, ClassNotFoundException {
    String ticket=stream.readUTF();
    return ticket;
}

/* (non−Javadoc)
* @see com.ibm.websphere.objectgrid.plugins.
ObjectTransformer#inflateValue(java.io.ObjectInputStream)
*/

public Object inflateValue(ObjectInputStream stream) throws IOException,	ClassNotFoundException {
    Stock stock=new Stock();
    stock.setTicket(stream.readUTF());
    stock.setCompany(stream.readUTF());
    stock.setDescription(stream.readUTF());
    stock.setPrice(stream.readDouble());
    stock.setLastTransactionTime(stream.readLong());
    stock.setSerialNumber(stream.readInt());
    return stock;
}

/* (non−Javadoc)
* @see com.ibm.websphere.objectgrid.plugins.
ObjectTransformer#copyValue(java.lang.Object)
*/
public Object copyValue(Object value) {
    Stock stock = (Stock) value;
       try {
        return stock.clone();
    }
    catch (CloneNotSupportedException e)
    {
        // display exception message    }
}

/* (non−Javadoc)
* @see com.ibm.websphere.objectgrid.plugins.
ObjectTransformer#copyKey(java.lang.Object)
*/
public Object copyKey(Object key) {
    String ticket=(String) key;
    String ticketCopy= new String (ticket);
    return ticketCopy;
}
}
然后,将此定制 MyStockObjectTransformer 类插入 BackingMap:
ObjectGridManager ogf=ObjectGridManagerFactory.getObjectGridManager();
ObjectGrid og = ogf.getObjectGrid("NYSE");
BackingMap bm = og.defineMap("NYSEStocks");
MyStockObjectTransformer ot = new MyStockObjectTransformer();
bm.setObjectTransformer(ot);