专业的编程技术博客社区

网站首页 > 博客文章 正文

使用Protobuf压缩踩坑分享(protobuf 数据压缩)

baijin 2024-08-15 17:01:32 博客文章 17 ℃ 0 评论

在使用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;
    }
}

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表