我正在尝试将大量数据加载到10节点的Cassandra环中。
执行插入的脚本得到~4000个/ s,大概是阻塞的 网络I / O.我在一台机器上启动了其中的8个,吞吐量也在增加 几乎是线性的。 (个别吞吐量略有下降,但更多 而不是由额外的过程补偿。)
这很有效,但是,我仍然没有获得足够的吞吐量,所以我 在另外3个虚拟机上启动了相同的设置。 (因此,8个进程* 4个VM)之后 第一个额外的VM,并且随着进一步的VM的增加频率和严重性 添加后,会发生以下情况:
“向下”变化。在我上次的比赛中:
nodetool status
挂起。两个线程似乎处于某种无限循环中。 (他们坚定地使用100%CPU。)日志中有java.lang.OutOfMemoryError: Java heap space
。代码基本上是:
def prepped_batch_insert(session, items, insert_query, silent=False):
# A mapping of number of inserts -> a prepared query for that number of
# inserts.
prepped_statements = {}
def get_prepped_statement(inserts):
if inserts in prepped:
# We already created a prepared query for this many inserts, use
# it:
return prepped_statements[inserts]
else:
# We haven't yet created a prepared query for this many inserts, so
# do so now:
query = ['BEGIN UNLOGGED BATCH']
for idx in xrange(inserts):
query.append(insert_query.query)
query.append('APPLY BATCH;')
query = '\n'.join(query)
ps = session.prepare(query)
prepped_statements[inserts] = ps
return ps
def do_prepped_batch_insert(batch)
ps = get_prepped_statement(len(batch))
# Generate the list of params to the prepared query:
params = []
for idx, item in enumerate(batch):
for k in insert_query.keyorder:
params.append(item[k])
# Do it.
session.execute(ps, params)
return inserter.insert_and_time(
items, # data generator
do_prepped_batch_insert, # The above function
_WHAT_APPEARS_TO_BE_THE_OPTIMAL_CASSANDRA_BATCH_SIZE, # = 200
silent=silent,
)
函数insert_and_time
将items
分成大小为200的批次,调用上述函数,并对整个工具包和kaboodle进行计时。 (此代码对戒指有毒。)
我们尝试了更多的读取,因为(有人告诉我)20k插入/秒很慢(插入我希望以该速率插入的数据需要一段时间......),并且Cassandra具有高容量。
我的问题:
¹客户端似乎也慢慢泄漏文件描述符。我不认为这是相关的。 (我在群集和连接上都调用.shutdown
。)查看驱动程序源,似乎有很多路径会导致异常泄漏。
答案 0 :(得分:0)
看起来非常像你在设置DDoS。
执行插入的脚本获得~4000个/ s,可能在网络I / O上被阻止。我在一台机器上启动了其中的8个,吞吐量几乎是线性的
如果启动通过同一NIC访问Cassandra的其他脚本实例,吞吐量接近线性增加,则网络IO上没有阻止您。
错误的客户端,恕我直言,永远不能杀死服务器。
在任何服务器上投入足够的负载,它将开始失败。一些服务器试图最小化此Web服务器通常会接受最大数量的并发HTTP请求,之后他们将回复它们正忙。然而,即使处理连接并告诉客户“现在就离开”也需要一些周期。适当的DoS保护涉及专用网络硬件。
(他们坚定地使用100%CPU。)有一个java.lang.OutOfMemoryError:Java堆空间
更多证据表明你只是装满你的戒指。
要提高吞吐量,请查看硬件和Cassandra配置。
答案 1 :(得分:0)
你的情况听起来很不寻常,但没有关于你在这里运行的硬件的任何细节是我的一些猜测。问题很可能是堆大小,其次是IO瓶颈。除非你在SSD上运行,否则CPU使用率应该不是问题。
1)如果您正在寻找一次性数据加载,然后是较小的一致数据流,请考虑使用批量loading tool.
2)可能在某种意义上说,您尝试以比您正在使用的硬件更快的速度加载数据。
3)您应该查看Cassandra系统日志中的“尝试刷新memtable以恢复空间”这样的消息,这些消息是堆耗尽的症状,他们将获得有关内存GC和其他正在进行的任务的信息。对于实时监控,您还可以使用jconsole或visualvm通过JMX连接到Cassandra实例。当看到这些时,应该很明显堆是否开始填满并且系统开始备份。大多数生产Cassandra实例的堆大小为8GB,其数量大于减少回报,因为世界GC事件变得更加普遍。
你应该注意的另一件事是等待压缩,这是Cassandra的关键IO瓶颈之一。如果此数字不受限制地增长,则意味着您的系统受到硬盘驱动器速度的限制,您可以通过更多计算机或升级到SSD来缓解压力。 用
检查 nodetool compactionstats
您可以用来监控所有这一切的工具是Datastax Opscenter。此工具允许您从一个位置轻松监控整个群集,社区版本完全免费。
我确实想知道是否还有其他问题,因为我经常对亚马逊m1.large实例进行基准测试,并发现其中大约10个可以支持40~50k写入/秒的流量而没有任何系统不稳定。
4)正如Eric所指出的那样,像Cassandra这样的分布式性能导向系统很难保持可用性和高性能,同时还要坚持防护客户端行为。权衡是提高速度,以便在写入时最小化系统状态检查。这允许极快的写入,但是让维护者有责任正确地配置和监视他们的系统。