大写会导致Cassandra环不稳定

时间:2014-02-11 23:42:09

标签: java python cassandra bulk-load cassandra-2.0

我正在尝试将大量数据加载到10节点的Cassandra环中。

执行插入的脚本得到~4000个/ s,大概是阻塞的 网络I / O.我在一台机器上启动了其中的8个,吞吐量也在增加 几乎是线性的。 (个别吞吐量略有下降,但更多 而不是由额外的过程补偿。)

这很有效,但是,我仍然没有获得足够的吞吐量,所以我 在另外3个虚拟机上启动了相同的设置。 (因此,8个进程* 4个VM)之后 第一个额外的VM,并且随着进一步的VM的增加频率和严重性 添加后,会发生以下情况:

  • 客户端开始收到超时错误。他们可以重新尝试写作,但是 因为他们分批这样做,他们的前进几乎完全是 消除。
  • 环变得不稳定,节点开始将自己标记为“向下”。 此外,不同的节点倾向于对谁失败有不同的想法。该 脚本中止时,环不会恢复。 (我甚至都没能 通过重新启动单个节点来解决这个问题:我不得不重启 整个戒指。)

“向下”变化。在我上次的比赛中:

  • 4个节点完全死亡。 (Cassandra根本没有跑。)检查日志,似乎没有记录为什么它会死亡。
  • 第五节,Cassandra正在奔跑。该节点上的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_timeitems分成大小为200的批次,调用上述函数,并对整个工具包和kaboodle进行计时。 (此代码对戒指有毒。)

我们尝试了更多的读取,因为(有人告诉我)20k插入/秒很慢(插入我希望以该速率插入的数据需要一段时间......),并且Cassandra具有高容量。

我的问题:

  1. 我在做什么有什么不寻常之处吗?怎么了?
  2. 我只是DDoS-ing我的戒指?
  3. 我怎样才能调试出错的地方?
  4. 错误的客户端,恕我直言,永远不会能够杀死服务器。 (而且上面的内容并不是非常错误。)我能做些什么来防止这种情况发生?
  5. ¹客户端似乎也慢慢泄漏文件描述符。我不认为这是相关的。 (我在群集和连接上都调用.shutdown。)查看驱动程序源,似乎有很多路径会导致异常泄漏。

2 个答案:

答案 0 :(得分:0)

看起来非常像你在设置DDoS。

  

执行插入的脚本获得~4000个/ s,可能在网络I / O上被阻止。我在一台机器上启动了其中的8个,吞吐量几乎是线性的

如果启动通过同一NIC访问Cassandra的其他脚本实例,吞吐量接近线性增加,则网络IO上没有阻止您。

  

错误的客户端,恕我直言,永远不能杀死服务器。

在任何服务器上投入足够的负载,它将开始失败。一些服务器试图最小化此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性能进行基准测试时使用的配置http://techblog.netflix.com/2011/11/benchmarking-cassandra-scalability-on.html

答案 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这样的分布式性能导向系统很难保持可用性和高性能,同时还要坚持防护客户端行为。权衡是提高速度,以便在写入时最小化系统状态检查。这允许极快的写入,但是让维护者有责任正确地配置和监视他们的系统。