当前位置: 首页 > news >正文

Apache Ignite Binary Object 调优

这段内容讲的是 Apache Ignite 中 Binary Object(二进制对象)的调优建议。Ignite 的 Binary Object 是一种 高效的序列化机制,它允许你在不加载类的情况下对对象进行序列化、反序列化、查询和更新。为了提高性能和内存使用效率,Ignite 对 Binary Object 的结构和 schema(模式)有特定的处理方式,因此我们需要遵循一些调优建议。

下面我们逐条解释这些调优建议,帮助你更好地理解和应用它们。


🔍 一、Binary Object 的 Schema 是什么?

定义:

  • 每个 Binary Object 都有一个 Schema(模式)
  • Schema 描述了对象中包含哪些字段,字段的顺序和类型;
  • 这些 Schema 会被 复制到所有节点,以便进行反序列化和查询。

举例:

BinaryObject obj1 = binaryFactory.create().setInt("id", 1).setString("name", "Alice");
BinaryObject obj2 = binaryFactory.create().setString("name", "Bob").setInt("id", 2);
  • 虽然两个对象都有相同的字段 idname,但字段顺序不同;
  • Ignite 会认为它们是 两个不同的 Schema
  • 这会增加内存开销,因为每个 Schema 都要保存。

✅ 建议 1:始终以相同的顺序添加字段

原文:

We strongly recommend you should always add fields to binary objects in the same order.

理由:

  • 如果字段顺序不同,Ignite 会创建 不同的 Schema
  • 多个 Schema 会占用更多内存;
  • 所有节点都会保存这些 Schema,可能造成 内存浪费或溢出

建议做法:

  • 统一字段顺序,避免因为顺序不同导致 Schema 冗余;
  • 可以通过封装统一的字段构造逻辑来保证一致性。

✅ 建议 2:避免频繁创建新的 Schema(尤其是 null 字段的组合)

原文:

If you have multiple fields that are set to null in random combinations, Ignite maintains a different Binary Object schema for each combination…

理由:

  • 每个字段是否为 null 会影响 Schema;
  • 如果你有多个字段,它们的 null 组合很多,Ignite 会为每种组合创建一个新 Schema;
  • 导致 Schema 数量激增,消耗大量堆内存

null 字段的内存开销:

  • 每个 null 字段需要 5 字节:4 字节字段 ID + 1 字节长度;
  • 但如果你 不包含这个字段,Ignite 会创建一个新 Schema;
  • 所以:
    • 如果你经常需要设置 null,建议保留字段并显式设置 null,而不是省略字段
    • 同时,统一字段集合,避免不同组合。

示例:

// 推荐:字段统一,允许 null
BinaryObject obj1 = binaryFactory.create().setInt("age", null).setString("name", "Alice").setDouble("salary", null);BinaryObject obj2 = binaryFactory.create().setInt("age", 30).setString("name", "Bob").setDouble("salary", 5000);
  • 两个对象使用相同的字段集合,Schema 一致;
  • 更节省内存,更高效。

✅ 建议 3:为 null 字段指定类型

原文:

This is also the reason you need to supply field type for null field.

理由:

  • 如果字段是 null,Ignite 无法推断字段的类型;
  • 所以你必须显式提供字段类型,否则会抛出异常。

示例:

// 正确写法:显式指定类型
binaryFactory.create().setField("age", null, Integer.class);

✅ 建议 4:将可选字段封装为嵌套 Binary Object

原文:

You can also nest your Binary Objects if you have a subset of fields which are optional but either all absent or all present.

场景:

  • 有一组字段是可选的,但要么全有,要么全无;
  • 例如:用户信息中有个 “address” 部分,包含 city、street、zip;

建议做法:

  • 将这些字段封装为一个 嵌套 Binary Object
  • 作为父对象的一个字段,可以为 null;
  • 这样不会导致 Schema 爆炸。

示例:

BinaryObject address = binaryFactory.create().setString("city", "Beijing").setString("street", "Chang'an Ave");BinaryObject user = binaryFactory.create().setString("name", "Alice").setObject("address", address); // 嵌套对象

✅ 建议 5:大量可选字段时使用 Map 字段

原文:

If you have a large number of fields which are all optional in any combinations, and very often null, you can store them in a map field.

场景:

  • 有很多字段都是可选的,组合复杂;
  • 大部分字段经常是 null;

建议做法:

  • 定义几个 固定字段
  • 使用一个 map 字段 存储其他可选字段;
  • 减少 Schema 数量,提高灵活性。

示例:

BinaryObject obj = binaryFactory.create().setString("name", "Alice").setMap("extra", Map.of("age", 30, "email", "alice@example.com"));

📌 总结:Binary Object 的最佳实践

建议说明
✅ 统一字段顺序避免不同顺序导致不同 Schema
✅ 统一字段集合避免 null 字段组合过多造成 Schema 爆炸
✅ 显式设置 null 字段类型否则无法确定字段类型
✅ 嵌套可选字段使用嵌套 Binary Object,避免 Schema 冗余
✅ 使用 map 字段处理大量可选字段,提高灵活性
⚠️ 避免频繁新增字段组合会导致 Schema 数量激增,影响内存

🧠 小贴士:如何查看 Binary Schema?

你可以在 Ignite 中使用如下方式查看当前的 Binary Schema:

BinaryMetadata meta = ignite.binary().type("MyType");
System.out.println(meta);

这段内容讲的是 如何在 Apache Ignite 中配置 Binary Object(二进制对象)的行为,包括 字段和类型 ID 的生成方式自定义序列化器(Serializer) 等高级配置。虽然大多数情况下你不需要配置这些内容,但在一些特定场景(如避免哈希冲突、优化序列化、支持自定义类型)下,这些配置非常有用。

下面我们逐句解释这段内容,并结合示例帮助你理解。


🔍 一、Binary Object 的基本机制回顾

在 Ignite 中,Binary Object 是一种 高效的二进制序列化机制,它允许你在不加载类的情况下操作对象的字段,非常适合分布式环境中使用。

Binary Object 的内部结构依赖于:

  • Type ID:标识类的唯一 ID;
  • Field ID:标识字段的唯一 ID;
  • 这些 ID 是通过字段名或类名的 字符串哈希值 计算得到的;
  • 默认情况下,Ignite 使用字符串的 hashCode() 方法生成 ID;
  • 为了避免哈希冲突或实现更灵活的映射逻辑,你可以 自定义 ID 生成方式

🛠 二、Binary Object 的可配置项

Ignite 提供了以下配置接口来定制 Binary Object 的行为:

1. Name Mapper(名称映射器)

  • 用于将类名或字段名进行 预处理转换
  • 例如:将全限定类名转为简写、统一大小写等;
  • 接口:BinaryNameMapper

2. ID Mapper(ID 映射器)

  • 用于将经过 Name Mapper 处理后的名称 转换为唯一的 ID
  • 可以自定义 ID 的生成逻辑,如使用 CRC32、SHA1、固定值等;
  • 接口:BinaryIdMapper

3. Serializer(序列化器)

  • 用于对特定类进行 自定义的序列化/反序列化
  • 当你想对某些类使用自己的序列化方式,而不是 Ignite 默认的 Binary Object 机制时使用;
  • 接口:BinarySerializer

🧩 三、全局配置 vs 每个类型配置

你可以配置:

  • 全局配置:适用于所有 Binary Object;
  • 每个类型(per-type)配置:只适用于某些特定类(支持通配符);

🧱 四、XML 配置详解

<bean class="org.apache.ignite.configuration.IgniteConfiguration"><property name="binaryConfiguration"><bean class="org.apache.ignite.configuration.BinaryConfiguration"><property name="nameMapper" ref="globalNameMapper"/><property name="idMapper" ref="globalIdMapper"/><property name="typeConfigurations"><list><bean class="org.apache.ignite.binary.BinaryTypeConfiguration"><property name="typeName" value="org.apache.ignite.examples.*"/><property name="serializer" ref="exampleSerializer"/></bean></list></property></bean></property></bean>

含义说明:

配置项描述
nameMapper全局名称映射器,用于转换类名/字段名
idMapper全局 ID 映射器,用于将名称转换为 ID
typeConfigurations类型配置列表,可以为特定类设置不同的序列化器
typeName类型名,支持通配符(如 org.apache.ignite.examples.*
serializer对应类型的序列化器

🧪 五、Java 示例:如何实现自定义组件

1. 自定义 ID Mapper 示例

public class MyIdMapper implements BinaryIdMapper {@Overridepublic int typeId(String typeName) {return typeName.hashCode(); // 可以改为 CRC32 或其他算法}@Overridepublic int fieldNameId(int typeId, String fieldName) {return fieldName.hashCode();}
}

2. 自定义 Name Mapper 示例

public class MyNameMapper implements BinaryNameMapper {@Overridepublic String mapTypeName(String typeName) {return typeName.replace("com.mycompany.", ""); // 去掉包名}@Overridepublic String mapFieldName(String fieldName) {return fieldName.toUpperCase(); // 字段名转大写}
}

3. 自定义 Serializer 示例

public class MyCustomSerializer implements BinarySerializer {@Overridepublic void writeBinary(Object obj, BinaryWriter writer) throws BinaryObjectException {MyCustomClass myObj = (MyCustomClass) obj;writer.writeString("name", myObj.getName());writer.writeInt("id", myObj.getId());}@Overridepublic void readBinary(Object obj, BinaryReader reader) throws BinaryObjectException {MyCustomClass myObj = (MyCustomClass) obj;myObj.setName(reader.readString("name"));myObj.setId(reader.readInt("id"));}
}

📌 六、通配符匹配(Wildcards)

你可以在 typeName 中使用通配符来匹配多个类:

<property name="typeName" value="com.example.model.*"/>

表示对 com.example.model 包下的所有类应用此配置。


✅ 七、总结:Binary Object 配置要点

配置项用途是否推荐自定义
Name Mapper转换类名/字段名✅ 在需要统一命名时使用
ID Mapper生成字段/类的唯一 ID✅ 在避免哈希冲突时使用
Serializer自定义类的序列化方式✅ 在需要特殊序列化逻辑时使用
通配符配置对多个类统一配置✅ 提高配置灵活性
全局 vs per-type控制配置作用范围✅ 合理使用,避免冲突

📚 建议使用场景

场景建议配置
避免字段名哈希冲突自定义 ID Mapper
统一字段命名风格自定义 Name Mapper
支持非 POJO 类型使用 BinarySerializer
多个类统一配置使用通配符 + per-type 配置
性能敏感场景自定义 ID 生成算法(如 CRC32)

如果你还有关于 Ignite 的 Binary Object、序列化机制、类加载、缓存查询、集群部署 等方面的问题,欢迎继续提问!

http://www.dtcms.com/a/290185.html

相关文章:

  • 【牛客算法】小美的排列询问
  • Linux 命令大全
  • Java基础教程(010):面向对象中的this和就近原则
  • 移星科技 modbus-tcp 转 modbus-Rtu模块
  • 安卓模拟器安装后,sdk版本详情简介及安卓sdk建议装哪几个版本
  • 突破量子仿真瓶颈:微算法科技MLGO量子算法的算术化与核操作迭代模型
  • 区块链之以太坊合约开发工具——Metamask钱包和Remix IDE
  • Android MTK平台预置多张静态壁纸
  • Freemarker生成Word文档下载到浏览器(下载word)
  • 上海GEO优化公司找哪家怎么做
  • uniapp底部导航栏凸起
  • windows电脑给iOS手机安装ipa包的方法
  • Kubernetes Pod调度基础
  • Leetcode力扣解题记录--第238题(前/后缀积)
  • 【Git#6】多人协作 企业级开发模型
  • 3D可视化模型轻量化陷阱:STL转GLTF的精度损失与压缩比平衡策略
  • 【系统全面】Linux内核原理——基础知识介绍
  • H3C路由器模拟PPPOE拨号
  • MTSC2025参会感悟:Multi-Agent RAG 应用质量保障建设
  • Java IO流体系详解:字节流、字符流与NIO/BIO对比及文件拷贝实践
  • postgresql安装教程-个人笔记
  • 股票分红派息及其数据获取(使用Python)
  • selenium爬取图书信息
  • 关于JVM
  • 低速信号设计之 RGMII 篇
  • Rk3568驱动开发_非阻塞IO_16
  • 有关Mysql数据库的总结
  • Pytest 输出捕获详解:掌握如何查看和控制打印信息
  • Nacos 探活机制深度解析:临时 / 永久实例差异及与 Sentinel 的熔断协作
  • C++11之右值引用与移动语义(提高效率)重要