Java 大写操作导致Cassandra环不稳定
我试图将大量数据加载到一个10节点的Cassandra环中 执行插入操作的脚本获得约4000次插入/秒,可能已被阻止 网络I/O。我在一台机器上启动了其中的8个,吞吐量可以扩展 几乎是线性的。(单个吞吐量略有下降,但更高。) 而不是通过额外的过程进行补偿。) 这工作正常,但是,我仍然没有获得足够的吞吐量,所以我 在另外3个虚拟机上启动了相同的设置。(因此,8个进程*4个VM)在 第一个额外的VM,并且随着进一步VM的增加频率和严重性增加 添加后,会出现以下情况:Java 大写操作导致Cassandra环不稳定,java,python,cassandra,bulk-load,cassandra-2.0,Java,Python,Cassandra,Bulk Load,Cassandra 2.0,我试图将大量数据加载到一个10节点的Cassandra环中 执行插入操作的脚本获得约4000次插入/秒,可能已被阻止 网络I/O。我在一台机器上启动了其中的8个,吞吐量可以扩展 几乎是线性的。(单个吞吐量略有下降,但更高。) 而不是通过额外的过程进行补偿。) 这工作正常,但是,我仍然没有获得足够的吞吐量,所以我 在另外3个虚拟机上启动了相同的设置。(因此,8个进程*4个VM)在 第一个额外的VM,并且随着进一步VM的增加频率和严重性增加 添加后,会出现以下情况: 客户端开始接收超时错误。他们可
- 客户端开始接收超时错误。他们可以重新尝试他们的写作,但是 因为它们是分批进行的,所以它们的前进几乎完全是失败的 淘汰
- 环变得不稳定,节点开始将自己标记为“向下”。 此外,不同的节点往往对谁下岗有不同的看法。这个 脚本中止时,ring不会恢复。(我甚至不能 要解决这个问题,只需重新启动单个节点:我必须重新启动 整个环。)
- 4个淋巴结完全死亡。(卡桑德拉根本没有运行。)检查日志,似乎没有任何关于它死亡原因的记录
- 五号,卡桑德拉正在跑步<该节点上的code>nodetool状态挂起。两个线程似乎在某种类型的无限循环中。(他们正在使用100%的CPU。)日志中有一个
java.lang.OutOfMemoryError:java堆空间
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_和_time
将项
拆分为大小为200的批,调用上述函数,并对整个工具包和卡本进行计时。(此代码对环有毒。)
我们尝试了更多的读取,因为(我被告知)每秒20k的插入速度很慢(插入我希望以这种速度插入的数据需要一段时间…),而且Cassandra具有高容量
我的问题是:
客户端似乎也在慢慢泄漏文件描述符。我认为这没有关系。(我正在集群和连接上调用
.shutdown
。)查看驱动程序源,似乎有很多异常会导致泄漏的路径。看起来很像是DDoS在破坏您的设置
执行插入操作的脚本获得约4000个插入/s,可能在网络I/O上阻塞。我在一台机器上启动了其中的8个,吞吐量几乎呈线性扩展
如果通过同一NIC启动访问Cassandra的其他脚本实例使吞吐量接近线性增长,则不会阻止网络IO
出错的客户机IMHO应该永远无法杀死服务器
在任何服务器上抛出足够的负载,它就会开始失败。一些服务器试图将此最小化,例如,web服务器通常会接受最大数量的并发HTTP请求,然后回复忙。然而,即使处理连接并告诉客户机“暂时离开”也需要一些周期。正确的DoS保护涉及专用网络硬件
(他们100%可靠地使用CPU。)有一个java.lang.OutOfMemoryError:java堆空间
更多的证据表明你只是把戒指装得超出了它的容量
要提高吞吐量,请查看硬件和Cassandra配置
- IO过载了吗?这是许多持久性系统的典型瓶颈。我对Cassandra没有具体的经验,但在Mongo DB中,只要工作集无法放入内存,IO性能就非常重要。如果过载,考虑更快的IO子系统(如果这是AWS,则有多种方法来改善IO性能)。
- 你有足够的内存吗?您提到Java正在耗尽堆。您是否已将每个节点上的堆大小设置为最大值,从而允许操作系统和系统上的其他进程需要一些RAM
- CPU过载了吗?似乎是的。不过,在考虑了适当的磁盘和网络IO性能,并回顾了Cassandra配置之后,我将最后看一看CPU。高CPU有时可能是其他事情的症状
- 验证Cassandra配置。我不是这方面的专家,但看看Netflix在测试Cassandra性能时使用的配置
1)如果你正在寻找一个时间负载的数据,然后是一个较小的一致的数据流,考虑使用批量< /P> 2) 可能是因为您试图以比所用硬件能够处理的速度更快的速度加载数据
3) 您应该查看Cassandra系统日志中的消息,如“尝试刷新memtable以恢复空间”,这是堆用完的症状,它们将包含有关内存GC和其他正在进行的任务的信息。为了进行实时监控,您还可以使用jconsole或visualvm通过JMX连接到Cassandra实例。当查看这些时,很明显堆是否开始填满,系统是否开始备份。大多数生产Cassandra实例的堆大小为8GB,当停止世界GC事件变得越来越频繁时,堆大小大于8GB的数量会带来越来越小的回报 nodetool compactionstats