10

我有一个 4 节点集群,每个盒子上有 16 核 CPU 和 100 GB RAM(每个机架上有 2 个节点)。

截至目前,所有系统都使用 Cassandra (v2.1.4) 的默认 JVM 设置运行。使用此设置,每个节点使用 13GB RAM 和 30% CPU。这是一个写入繁重的集群,偶尔会删除或更新。

我是否需要调整 Cassandra 的 JVM 设置以利用更多内存?为了进行适当的设置,我应该查看哪些内容?

4

2 回答 2

12

我是否需要调整 Cassandra 的 JVM 设置以利用更多内存?

DataStax Tuning Java Resources文档实际上对此有一些非常合理的建议:

许多刚接触 Cassandra 的用户很想将 Java 堆大小调得太高,这会占用大部分底层系统的 RAM。在大多数情况下,增加 Java 堆大小实际上是有害的,原因如下:

  • 在大多数情况下,Java 优雅地处理 8GB 以上垃圾收集的能力会迅速减弱。
  • 现代操作系统为频繁访问的数据维护操作系统页面缓存,并且非常擅长将这些数据保存在内存中,但可以通过提升 Java 堆大小来阻止其工作。

如果您有超过 2GB 的系统内存(这是典型的),请保持 Java 堆的大小相对较小,以便为页面缓存留出更多内存。

由于您的机器上有 100GB 的 RAM,(如果您确实在“默认 JVM 设置”下运行)您的 JVM 最大堆大小应限制为 8192M。实际上,除非您遇到垃圾收集问题,否则我不会偏离这一点。

可以在cassandra-env.sh文件中设置 Cassandra 的 JVM 资源。如果你很好奇,请查看代码cassandra-env.sh并寻找calculate_heap_sizes()方法。这应该让您了解 Cassandra 如何计算您的默认 JVM 设置。

为了进行适当的设置,我应该查看哪些内容?

如果您正在运行OpsCenter(并且应该如此),请为“使用的堆”和“使用的非堆”添加图表。

OpsCenter 一起绘制使用的堆和使用的非堆

这将允许您轻松监控集群的 JVM 堆使用情况。对我有帮助的另一件事是编写了一个 bash 脚本,我在其中基本上劫持了cassandra-env.sh. 这样我就可以在一台新机器上运行它,并立即知道我的MAX_HEAP_SIZEHEAP_NEWSIZE将要做什么:

#!/bin/bash
clear
echo "This is how Cassandra will determine its default Heap and GC Generation sizes."

system_memory_in_mb=`free -m | awk '/Mem:/ {print $2}'`
half_system_memory_in_mb=`expr $system_memory_in_mb / 2`
quarter_system_memory_in_mb=`expr $half_system_memory_in_mb / 2`

echo "   memory = $system_memory_in_mb"
echo "     half = $half_system_memory_in_mb"
echo "  quarter = $quarter_system_memory_in_mb"

echo "cpu cores = "`egrep -c 'processor([[:space:]]+):.*' /proc/cpuinfo`

#cassandra-env logic duped here
#this should help you to see how much memory is being allocated
#to the JVM
    if [ "$half_system_memory_in_mb" -gt "1024" ]
    then
        half_system_memory_in_mb="1024"
    fi
    if [ "$quarter_system_memory_in_mb" -gt "8192" ]
    then
        quarter_system_memory_in_mb="8192"
    fi
    if [ "$half_system_memory_in_mb" -gt "$quarter_system_memory_in_mb" ]
    then
        max_heap_size_in_mb="$half_system_memory_in_mb"
    else
        max_heap_size_in_mb="$quarter_system_memory_in_mb"
    fi
    MAX_HEAP_SIZE="${max_heap_size_in_mb}M"

    # Young gen: min(max_sensible_per_modern_cpu_core * num_cores, 1/4 * heap size)
    max_sensible_yg_per_core_in_mb="100"
    max_sensible_yg_in_mb=`expr ($max_sensible_yg_per_core_in_mb * $system_cpu_cores)`

    desired_yg_in_mb=`expr $max_heap_size_in_mb / 4`
    if [ "$desired_yg_in_mb" -gt "$max_sensible_yg_in_mb" ]
    then
        HEAP_NEWSIZE="${max_sensible_yg_in_mb}M"
    else
        HEAP_NEWSIZE="${desired_yg_in_mb}M"
    fi

echo "Max heap size = " $MAX_HEAP_SIZE
echo " New gen size = " $HEAP_NEWSIZE

更新 20160212

另外,请务必查看Amy Tobey 的 2.1 Cassandra Tuning Guide。她有一些关于如何让您的集群以最佳方式运行的重要提示。

于 2015-05-13T13:13:03.760 回答
1

system_cpu_cores 设置不正确。编辑正确的执行。

#!/bin/bash
clear
echo "This is how Cassandra will determine its default Heap and GC Generation sizes."

system_memory_in_mb=`free -m | awk '/Mem:/ {print $2}'`
half_system_memory_in_mb=`expr $system_memory_in_mb / 2`
quarter_system_memory_in_mb=`expr $half_system_memory_in_mb / 2`
system_cpu_cores=`cat /proc/cpuinfo   | grep -i processor | wc -l`
echo "   memory = $system_memory_in_mb"
echo "     half = $half_system_memory_in_mb"
echo "  quarter = $quarter_system_memory_in_mb"

echo "cpu cores = `egrep -c 'processor([[:space:]]+):.*' /proc/cpuinfo`"

#cassandra-env logic duped here
#this should help you to see how much memory is being allocated
#to the JVM
if [ "$half_system_memory_in_mb" -gt "1024" ]
then
    half_system_memory_in_mb="1024"
fi
if [ "$quarter_system_memory_in_mb" -gt "8192" ]
then
    quarter_system_memory_in_mb="8192"
fi
if [ "$half_system_memory_in_mb" -gt "$quarter_system_memory_in_mb" ]
then
    max_heap_size_in_mb="$half_system_memory_in_mb"
else
    max_heap_size_in_mb="$quarter_system_memory_in_mb"
fi
MAX_HEAP_SIZE="${max_heap_size_in_mb}M"

# Young gen: min(max_sensible_per_modern_cpu_core * num_cores, 1/4 * heap size)
max_sensible_yg_per_core_in_mb="100"
max_sensible_yg_in_mb=`expr $max_sensible_yg_per_core_in_mb * $system_cpu_cores`
desired_yg_in_mb=`expr $max_heap_size_in_mb / 4`
if [ "$desired_yg_in_mb" -gt "$max_sensible_yg_in_mb" ]
then
    HEAP_NEWSIZE="${max_sensible_yg_in_mb}M"
else
    HEAP_NEWSIZE="${desired_yg_in_mb}M"
fi

echo "Max heap size = " $MAX_HEAP_SIZE
echo " New gen size = " $HEAP_NEWSIZE
于 2016-09-25T20:39:14.957 回答