我试图对我的遗留应用程序进行改进,使其具有可伸缩性和可执行性。它当前的体系结构如下所示
假设一个短命的脚本每天被调用一次500k+,每一次调用都是唯一的调用(由一个键标识),它会将几个结构化文件写入自己唯一的日期目录。也可能有脚本重新运行(重新运行将更新同一分区中的文件)。
现在,我有了一个Web应用程序来在UI中显示这个脚本的执行信息(脚本持久化的数据运行在文件系统中)。
这个web应用程序的后端是基于Java的。它有7天的内存缓存(Hashmap)和专门的线程,每30秒唤醒一次,并通过从文件系统读取新信息来刷新缓存中的数据。请注意,7天数据的内存缓存占用大约40 in的RAM空间。
正面是基于反应的。我们通过每30秒通过调用API从Java后端查询数据来刷新浏览器中的数据。
正如您所注意到的,这个体系结构有三个主要问题:
我如何改进这个体系结构?
我正在考虑引入一个Kafka队列,在这个队列中,脚本可以在写入文件系统的同时发布事件。Java服务器可以订阅这些Kafka事件。在从Kafka接收事件时,Java服务器可以
这听起来不错还是你看到了什么瑕疵?
发布于 2020-04-03 02:45:23
一个潜在的解决方案是使用数据库而不是原始文件系统。使用基于预期查询模式的索引,您应该可以看到比处理原始文件更可靠的性能。
由于您正在缓慢地进行重构,您可能需要复制存储机制,并随着时间的推移进行扩展。也就是说,将数据写入现有的文件系统和数据库。然后,理想情况下,您可以慢慢地将查询从一个数据源转移到另一个数据源。这里的缺点/挑战是使两个数据存储保持同步。
您还可以为内存缓存层考虑类似于Redis的东西,作为为缓存层获取水平可伸缩性的一种机制。这可能会帮助您使用多台机器缓存超过7天的数据。
另一个建议可能是写入缓存,因此数据将立即缓存在缓存层中,而无需等待刷新功能的启动。像阿帕奇伊格尼特这样的数据结构支持直通式缓存。
发布于 2020-04-03 05:22:39
关于问题末尾的体系结构方法:
首先,我们讨论了500.000次调用,即平均每0.1728秒调用一次调用。
据我所知,卡夫卡在实时流媒体数据的分发方面表现出色。我认为,如果您需要保证交付,您将更好地使用“经典”消息代理,如ActiveMq。如果监听器/ java后端因任何原因出现故障,则可以将消息持久化到磁盘上。(请注意,卡夫卡也可能是如此,我从未在真实生活中使用过它。)-看看吧。)
使用redis缓存似乎是个不错的主意,但您必须将缓存保存在磁盘上,以涵盖java后端重新启动的场景。老实说,我不明白为什么redis (有磁盘存储)对您来说是可以的,但是数据库不是。两者都会起作用的。
通过websockets推到客户端是可以的(或者使用SSE代替),但不是每0.1728秒一次!您必须聚合您的消息,并且--取决于消息大小--使用更大的时间间隔进行客户端更新。这将是1秒,10秒,1分钟,1小时取决于具体的数据,其大小和使用。
https://softwareengineering.stackexchange.com/questions/408133
复制相似问题