我尝试使用Ignite存储事件,但在插入新数据时遇到了太多RAM使用问题 我正在使用1GB堆和默认配置运行点火节点
curs.execute("""CREATE TABLE trololo (id LONG PRIMARY KEY, user_id LONG, event_type INT, timestamp TIMESTAMP) WITH "template=replicated" """);
n = 10000
for i in range(200):
values = []
for j in range(n):
id_ = i * n + j
event_type = random.randint(1, 5)
user_id = random.randint(1000, 5000)
timestamp = datetime.datetime.utcnow() - timedelta(hours=random.randint(1, 100))
values.append("({id}, {user_id}, {event_type}, '{timestamp}')".format(
id=id_, user_id=user_id, event_type=event_type, uid=uid, timestamp=timestamp.strftime('%Y-%m-%dT%H:%M:%S-00:00')
))
query = "INSERT INTO trololo (id, user_id, event_type, TIMESTAMP) VALUES %s;" % ",".join(values)
curs.execute(query)
但是在加载了大约10 ^ 6个事件之后,我获得了100%的CPU使用率,因为所有堆都被占用并且GC试图清理一些空间(不成功)
然后我停了大约10分钟,之后GC成功地清理了一些空间,我可以继续加载新数据
然后再次堆满了并重新加载
这是非常奇怪的行为,我无法找到一种方法如何在没有这些问题的情况下加载10 ^ 7个事件
大约应该采取的事件:
8 + 8 + 4 + 10(时间戳大小?)约为30字节
30字节x3(开销)所以它应该小于每条记录100字节
所以10 ^ 7 * 10 ^ 2 = 10 ^ 9字节= 1Gb
所以似乎10 ^ 7事件应该适合1Gb RAM,不是吗?
答案 0 :(得分:2)
实际上,从版本2.0开始,Ignite会使用默认设置存储所有内容。
这里的主要问题是你生成一个包含10000个插入的非常大的查询字符串,应该对其进行解析,当然,它将存储在堆中。在为每个查询减小此大小后,您将在此处获得更好的结果。
但是,正如您在doc for capacity planning中所看到的,Ignite为每个条目增加了大约200字节的开销。此外,为每个节点添加大约200-300MB的内部存储器和合理的内存量,以便JVM和GC高效运行
如果你真的只想使用1gb堆,你可以尝试调整GC,但我建议增加堆大小。