在使用redis,kafka进行大数据量存储的时候,基于省空间与网络开销考虑,决定使用Protobuf压缩存储与传输,在实际使用中遇到如下的问题:
1.不能减少属性字段
2.不能修改属性类型
3.不能调整字段的顺序
4.新增字段要按照顺序添加到后面
5.如果想有好的扩展性,建议使用map数据格式
如果不按照上面的1到4的处理方式,反序列化的时候会报错。
具体实战经验如下,给大家提醒少走弯路
maven 引用
<!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java -->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.20.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.baidu/jprotobuf -->
<dependency>
<groupId>com.baidu</groupId>
<artifactId>jprotobuf</artifactId>
<version>2.4.15</version>
</dependency>
结构体定义如下:
/**
*
* 【重要提醒!!!修改结构必看?!!!】
* 此结构体使用了Protobuf压缩方式,修改结构体必看
* 1.不能减少属性字段
* 2.不能修改属性类型
* 3.不能调整字段的顺序
* 4.新增字段要按照顺序,即只能在后面新增
* 5.如果想有好的扩展性,建议使用map数据格式
* 【重要提醒!!!修改结构必看?!!!】
*/
@Builder
public class TagInfo implements Serializable {
/**
* 标签编码
*/
@Protobuf(fieldType = FieldType.STRING, required = false,order = 1)
private String tagCode;
/**
* 标签类型
*/
@Protobuf(fieldType = FieldType.STRING, required = false,order = 2)
private String tagTypeCode;
/**
* 标签分类
*/
@Protobuf(fieldType = FieldType.INT32, required = false,order = 3)
private Integer tagCategory;
/**
* 打标时间
*/
@Protobuf(fieldType = FieldType.DATE, required = false,order = 4)
private Date tagTime;
/**
* 标签来源
*/
@Protobuf(fieldType = FieldType.STRING, required = false,order = 5)
private String tagSource;
/**
* 运单号
*/
@Protobuf(fieldType = FieldType.STRING, required = false,order = 6)
private String mailNo;
/**
* 标签扩展属性
*/
@Protobuf(fieldType = FieldType.MAP, required = false,order = 7)
private Map<String, String> extend;
public TagInfo() {
}
public TagInfo(String tagCode, String tagTypeCode, Integer tagCategory, Date tagTime, String tagSource, String mailNo, Map<String, String> extend) {
this.tagCode = tagCode;
this.tagTypeCode = tagTypeCode;
this.tagCategory = tagCategory;
this.tagTime = tagTime;
this.tagSource = tagSource;
this.mailNo = mailNo;
this.extend = extend;
}
public String getTagCode() {
return tagCode;
}
public void setTagCode(String tagCode) {
this.tagCode = tagCode;
}
public String getTagTypeCode() {
return tagTypeCode;
}
public void setTagTypeCode(String tagTypeCode) {
this.tagTypeCode = tagTypeCode;
}
public Integer getTagCategory() {
return tagCategory;
}
public void setTagCategory(Integer tagCategory) {
this.tagCategory = tagCategory;
}
public Date getTagTime() {
return tagTime;
}
public void setTagTime(Date tagTime) {
this.tagTime = tagTime;
}
public String getTagSource() {
return tagSource;
}
public void setTagSource(String tagSource) {
this.tagSource = tagSource;
}
public String getMailNo() {
return mailNo;
}
public void setMailNo(String mailNo) {
this.mailNo = mailNo;
}
public Map<String, String> getExtend() {
return extend;
}
public void setExtend(Map<String, String> extend) {
this.extend = extend;
}
}
序列化与反序列化工具类
public class ProtobufSerializer {
/**
* Serialize the given object to binary data.
*
* @param o object to serialize. Can be {@literal null}.
* @return the equivalent binary data. Can be {@literal null}.
*/
public byte[] serialize(TagInfo o) throws SerializationException {
if (!ObjectUtils.isEmpty(o)) {
try {
Codec<TagInfo> codec = ProtobufProxy.create(TagInfo.class);
return codec.encode(o);
} catch (Exception e) {
throw new SerializationException("调用 ProtobufSerializer.serialize异常", e);
}
}
return new byte[0];
}
/**
* Deserialize an object from the given binary data.
*
* @param bytes object binary representation. Can be {@literal null}.
* @return the equivalent object instance. Can be {@literal null}.
*/
public TagInfo deserialize(byte[] bytes) throws SerializationException {
if (ObjectUtils.isEmpty(bytes)||bytes.length > 0) {
try {
Codec<TagInfo> codec = ProtobufProxy.create(TagInfo.class);
return codec.decode(bytes);
} catch (Exception e) {
throw new SerializationException("调用 ProtobufSerializer.deserialize异常", e);
}
}
return null;
}
}
本文暂时没有评论,来添加一个吧(●'◡'●)