Apache Ignite 零部署:真的是零吗?

Apache Ignite 零部署:真的是零吗?

我们是零售网络的技术开发部门。 有一天,管理层设定了通过使用 Apache Ignite 结合 MSSQL 来加速大规模计算的任务,并展示了一个带有精美插图和 Java 代码示例的网站。 我立刻喜欢上了这个网站 零部署,其描述承诺了奇迹:您不必在网格中的每个节点上手动部署 Java 或 Scala 代码,并在每次更改时重新部署它。 随着工作的进展,事实证明零部署具有特定的用途,我想分享其功能。 下面是想法和实施细节。

1。 声明问题

问题的本质如下。 有一个SalesPoint销售点目录和一个Sku(库存单位)产品目录。 销售点有一个“商店类型”属性,其值为“小”和“大”。 分类(销售点的产品列表)连接到每个销售点(从 DBMS 加载),并提供从指定日期开始指定产品的信息
从分类中排除或添加到分类中。

需要组织销售点的分区缓存,并提前一个月在其中存储有关连接产品的信息。 与战斗系统的兼容性需要Ignite客户端节点加载数据,计算表单的聚合(商店类型、产品代码、日期、销售点数)并将其上传回DBMS。

2.文学研究

我还没有任何经验,所以我开始在炉子上跳舞。 也就是说,来自出版物的评论。

2016年文章 Apache Ignite 简介:第一步 包含 Apache Ignite 项目文档的链接,同时对该文档的含糊之处提出批评。 我重新读了几遍,还是没有弄清楚。 我参考的是官方教程 入门
乐观地承诺“您很快就会启动并运行!” 我正在弄清楚环境变量设置,观看了两个 Apache Ignite Essentials 视频,但它们对于我的特定任务来说并不是很有用。 我使用标准文件“example-ignite.xml”成功从命令行启动 Ignite,构建了第一个应用程序 计算应用程序 使用 Maven。 该应用程序可以运行并使用零部署,多美啊!

我进一步阅读,该示例立即使用affinityKey(之前通过 SQL 查询创建),甚至使用神秘的 BinaryObject:

IgniteCache<BinaryObject, BinaryObject> people 
        = ignite.cache("Person").withKeepBinary(); 

已读 :二进制格式 - 类似于反射,通过名称访问对象的字段。 无需完全反序列化对象即可读取字段的值(节省内存)。 但是,既然有零部署,为什么使用 BinaryObject 而不是 Person? 为什么要使用 IgniteCache 转移到IgniteCache ? 目前还不清楚。

我正在重新制作计算应用程序以适合我的情况。 MSSQL中销售点目录的主键定义为[id] [int] NOT NULL,我以此类推创建缓存

IgniteCache<Integer, SalesPoint> salesPointCache=ignite.cache("spCache")

在 xml 配置中我指示缓存已分区

<bean class="org.apache.ignite.configuration.CacheConfiguration">
    <property name="name" value="spCache"/>
    <property name="cacheMode" value="PARTITIONED"/>
</bean>

按销售点分区假定将在每个集群节点上为可用的 salesPointCache 记录构建所需的聚合,之后客户端节点将执行最终求和。

我正在阅读教程 首先点燃计算应用程序,我是这样类比的。 在每个集群节点上,我运行 IgniteRunnable(),如下所示:

  @Override
  public void run() {
    SalesPoint sp=salesPointCache.get(spId);
    sp.calculateSalesPointCount();
    ..
  }

我添加聚合和上传逻辑并在测试数据集上运行它。 一切都在开发服务器上本地运行。

我启动两个 CentOs 测试服务器,在 default-config.xml 中指定 IP 地址,在每个服务器上执行

./bin/ignite.sh config/default-config.xml

两个 Ignite 节点都在运行并且可以互相看到。 我在客户端应用程序的 xml 配置中指定所需的地址,它启动,向拓扑添加第三个节点,然后立即又出现两个节点。 日志显示“ClassNotFoundException: model.SalesPoint”行

SalesPoint sp=salesPointCache.get(spId);

StackOverflow表示错误的原因是CentOs服务器上没有自定义的SalesPoint类。 我们到了。 “你不必在每个节点上手动部署 Java 代码”之类的怎么样? 或者“您的 Java 代码”与 SalesPoint 无关?

我可能错过了一些东西 - 我开始再次搜索,再次阅读和搜索。 过了一会儿,我感觉我已经阅读了有关该主题的所有内容,不再有什么新内容了。 当我搜索时,我发现了一些有趣的评论。

瓦伦丁·库利琴科,GridGain Systems 首席架构师, 回答 StackOverflow,2016 年 XNUMX 月:

Model classes are not peer deployed, but you can use withKeepBinary() flag
on the cache and query BinaryObjects. This way you will avoid deserialization
on the server side and will not get ClassNotFoundException.

另一种权威观点: 丹尼斯·玛格达,GridGain Systems 产品管理总监。

关于哈布雷的文章 关于微服务 参考了 Denis Magda 的三篇文章: 微服务第一部分, 微服务第二部分, 微服务第三部分 2016-2017。 在第二篇文章中,Denis 建议通过 MaintenanceServiceNodeStartup.jar 启动集群节点。 您还可以通过 xml 配置和命令行使用 launch,但随后您需要在每个已部署的集群节点上手动放置自定义类:

That's it. Start (..)  node using MaintenanceServiceNodeStartup file or pass
maintenance-service-node-config.xml to Apache Ignite's ignite.sh/bat scripts.
If you prefer the latter then make sure to build a jar file that will contain
all the classes from java/app/common and java/services/maintenance directories.
The jar has to be added to the classpath of every node where the service
might be deployed.

确实,就是这样。 事实证明,为什么,这种神秘的二进制格式!

3.单罐

丹尼斯在我的个人评分中名列第一,恕我直言,这是所有可用教程中最有用的教程。 在他的 微服务示例 Github 包含一个完全现成的设置集群节点的示例,无需任何额外的抢注即可编译。

我以同样的方式执行此操作,并获得一个 jar 文件,该文件根据命令行参数启动“数据节点”或“客户端节点”。 装配开始并开始工作。 零部署已被击败。

从兆字节的测试数据到数十千兆字节的战斗数据的转变表明,二进制格式的存在是有原因的。 有必要优化节点上的内存消耗,而这正是 BinaryObject 非常有用的地方。

4。 发现

关于 Apache Ignite 项目文档模糊性的第一次批评被证明是公平的;自 2016 年以来几乎没有什么变化。 对于初学者来说,基于网站和/或存储库组装功能原型并不容易。

根据已完成工作的结果,给人的印象是零部署有效,但仅限于系统级别。 像这样的事情:BinaryObject 用于教导远程集群节点使用自定义类; 零部署-内部机制
Apache Ignite 本身并在整个集群中分发系统对象。

我希望我的经验对 Apache Ignite 新用户有用。

来源: habr.com

添加评论