在我的工作中,我将为以下问题开发并实施解决方案:
给定来自特定数据集字段的30M记录提取(键,值)元组的数据集,按键和值对它们进行分组,存储每个键的相同值的数量.将每个密钥的前5000个最常见值写入数据库.每个数据集行以序列化XML的形式包含最多100个(键,值)元组.
我想出了这样的解决方案(使用Spring-Batch):
批处理作业步骤:
步骤1.迭代数据集行并提取(键,值)元组.获取一些固定数量的元组后,将它们转储到磁盘上.每个元组都转到名为pattern'/ chunk-'的文件,因此指定键的所有值都存储在一个目录中.在一个文件中存储值已排序.
步骤2.迭代所有''目录并将其块文件合并为一个分组相同的值.由于值是按顺序存储的,因此将它们合并为O(n*log k)复杂度是微不足道的,其中"n"是块文件中的值的数量,"k"是块的初始数量.
步骤3.对于每个合并文件(换句话说,对于每个键),使用PriorityQueue顺序读取其值以保持前5000个值而不将所有值加载到内存中.将队列内容写入数据库.
我花了大约一个星期完成这项任务,主要是因为我以前没有使用过Spring-Batch,因为我试图强调需要精确实现多线程部分的可伸缩性.
问题是我的经理认为这个任务太容易花费那么多时间.
问题是 - 您是否知道更有效的解决方案,或者可能效率更低,更容易实施?您需要多长时间来实施我的解决方案?
我知道类似MapReduce的框架,但是我不能使用它们,因为应用程序应该在一个具有3个核心和1GB用于Java堆的简单PC上运行.
先感谢您!
UPD:我想我没有明确表达我的问题.让我以其他方式问:
鉴于问题并且作为项目经理或者至少任务审核者你会接受我的解决方案吗?你会花多少时间来完成这项任务?
我认为隐藏结构定义会使代码更安全,因为您在编译器的帮助下强制执行,不能直接访问结构的任何成员.缺点是用户无法在堆栈上声明结构类型的变量,因为结构的大小未知,有时需要避免使用malloc().这可以(部分成功)解决,alloca(3)所有主要的libc实现都存在,尽管此函数不符合POSIX.鉴于这种优点和缺点,这样的设计一般可以认为好吗?
在lib.h:
struct foo;
extern size_t foo_size;
int foo_get_bar (struct foo *);
Run Code Online (Sandbox Code Playgroud)
在lib.c:
struct foo {
int bar;
};
size_t foo_size = sizeof foo;
int foo_get_bar (struct foo *foo)
{
return foo->bar;
}
Run Code Online (Sandbox Code Playgroud)
在example.c:
#include "lib.h"
int bar(void) {
struct foo *foo = alloca (foo_size);
foo_init (foo);
return foo_get_bar (foo);
}
Run Code Online (Sandbox Code Playgroud)
UPD:更新了问题,明确指出使用的思想alloca()是能够在堆栈上声明结构但隐藏其定义.
如果是这样,您是否知道非TCP网络中可能出现的问题?
了解MQTT我遇到了几个提到MQTT依赖于TCP/IP堆栈的事实.例如,来自mqtt.org:
传感器网络的MQTT针对非TCP/IP网络上的嵌入式设备,而MQTT本身明确需要 TCP/IP堆栈.
但如果您阅读参考文件,您将找不到类似的东西.此外,还有可用于可靠传送的QoS字段,其中0以外的值在TCP/IP网络中基本无用.现在我没有看到任何阻止我使用UNIX管道,域或UDP套接字而不是TCP套接字建立MQTT连接的东西.