转载

Cassandra配置JMX

Cassandra数据库通过JMX方式对外提供监控和管理服务。本文讲解如何配置和开启Cassandra的JMX服务。

环境说明

本文是基于以下版本的系统和服务:

  • cassandra 3.11.6
  • openjdk 1.8.0
  • mx4j 3.0.2
  • Ubuntu 18.04.4 LTS

需要说明的是,当使用java 11以服务形式启动cassandra,服务启动后会进入 active(exited) 状态:

$ systemctl status cassandra
  ● cassandra.service - LSB: distributed storage system for structured data
     Loaded: loaded (/etc/init.d/cassandra; generated)
       Active: active (exited) since Wed 2020-05-13 13:48:21 CST; 4s ago
       Docs: man:systemd-sysv-generator(8)
    Process: 23280 ExecStop=/etc/init.d/cassandra stop (code=exited, status=0/SUCCESS)
    Process: 23298 ExecStart=/etc/init.d/cassandra start (code=exited, status=0/SUCCESS)

这是因为有参数不支持导致jvm启动失败。虽然根据Cassandra 3的文档,java 1.8及以上版本都支持,但至少java 11并不支持。

Cassandra目录和文件

安装和数据目录

Cassandra安装在 /usr/share/cassandra 目录下。这个目录的子目录 /lib 下是Cassandar的依赖包,后面安装配置MX4J服务时,会用到这个目录。

Cassandra的数据文件保存在 /var/lib/cassandra 目录下。一般可以通过这个目录来备份和恢复数据。

日志文件在 /var/log/cassandra 目录下。这个目录有三种日志文件 system.logdebug.loggc.log 。多数情况下,通过查看 system.log 可以了解系统的运行状态和错误信息。

配置和运行脚本

在Ubuntu上通过Debian Packages方式安装Cassandra之后,Cassandra可以以服务方式启动。接下来的配置也都是基于服务方式操作Cassandra的情况。

Cassandra没有提供Systemd服务的配置,所以服务操作还是通过 /etc/init.d/ 目录下的 cassandra 脚本来定义的。可以根据这个脚本来分析Cassandra服务的启动过程。

根据服务启动脚本,可以发现 /etc/default/cassandra 配置脚本会用来设置运行时所需要的环境变量。比如,如果系统默认的java是不兼容的版本,就可以在这个脚本中添加 JAVA_HOMEJRE_HOME 环境变量,比如:

export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
  export JRE_HOME=/usr/lib/jvm/java-8-openjdk-amd64/jre

注意,如果不是以系统服务的方式启动Cassandra,则这个配置脚本中设置的环境变量不会生效。

最主要的配置文件和脚本在 /etc/cassandra 目录下。这个脚本会根据环境变量等参数动态的计算一些jvm启动参数。这个目录下的另外一个配置文件 jvm.options 也可以用来设置jvm启动参数,但是 cassandra-env.sh 脚本设置的优先级比较高,所以要注意确认 jvm.options 中的设置不会被 cassandra-env.sh 覆盖。本文主要使用 cassandra-env.sh 脚本来设置需要的参数。

配置MX4J HttpAdaptor

Cassandra可以与MX4J HttpAdaptor集成,通过Web控制台的方式提供JMX服务访问。

为了开启MX4J HttpAdaptor服务,需要安装MX4J。MX4J可以从 下载页面 下载需要的版本。下载并解压后,在 mx4j-3.0.2/lib 目录下找到 mx4j-tools.jar ,将这个jar包安装到Cassandra的lib目录 /var/lib/cassandra 下,然后重启Cassandra。

如果一切正常,可以看到 system.log 中以下日志内容:

INFO  [main] 2020-05-14 09:29:24,963 Mx4jTool.java:61 - mx4j successfuly loaded

日志里的拼写错误是Cassandra的代码问题,不是我弄错了。

默认情况下MX4J HttpAdaptor监听的是 127.0.0.1 上的 8081 端口。如果启动正常,可以通过本地浏览器访问Web控制台了:

Cassandra配置JMX

8081 这个端口很有可能和其他服务冲突。当端口冲突时,可以在 system.log 中看到以下错误信息:

WARN  [main] 2020-05-14 15:52:41,847 Mx4jTool.java:70 - Could not start register mbean in JMX
  java.lang.reflect.InvocationTargetException: null
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_252]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_252]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_252]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_252]
        at org.apache.cassandra.utils.Mx4jTool.maybeLoad(Mx4jTool.java:60) ~[apache-cassandra-3.11.6.jar:3.11.6]
        at org.apache.cassandra.service.CassandraDaemon.setup(CassandraDaemon.java:197) [apache-cassandra-3.11.6.jar:3.11.6]
        at org.apache.cassandra.service.CassandraDaemon.activate(CassandraDaemon.java:630) [apache-cassandra-3.11.6.jar:3.11.6]
        at org.apache.cassandra.service.CassandraDaemon.main(CassandraDaemon.java:757) [apache-cassandra-3.11.6.jar:3.11.6]
  Caused by: java.net.BindException: Address already in use (Bind failed)
        at java.net.PlainSocketImpl.socketBind(Native Method) ~[na:1.8.0_252]
        at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:387) ~[na:1.8.0_252]
        at java.net.ServerSocket.bind(ServerSocket.java:390) ~[na:1.8.0_252]
        at java.net.ServerSocket.<init>(ServerSocket.java:252) ~[na:1.8.0_252]
        at mx4j.tools.adaptor.PlainAdaptorServerSocketFactory.createServerSocket(PlainAdaptorServerSocketFactory.java:24) ~[mx4j-tools.jar:na]
        at mx4j.tools.adaptor.http.HttpAdaptor.createServerSocket(HttpAdaptor.java:672) ~[mx4j-tools.jar:na]
        at mx4j.tools.adaptor.http.HttpAdaptor.start(HttpAdaptor.java:478) ~[mx4j-tools.jar:na]
        ... 8 common frames omitted

另外,如果希望从远程访问,需要设置监听地址。此时,可以在 /etc/default/cassandra 脚本中将这两个变量设置为期望的值,然后重启Cassandra服务:

export MX4J_ADDRESS="-Dmx4jaddress=0.0.0.0"
  export MX4J_PORT="-Dmx4jport=7081"

设置成功后,可以在 system.log 日志中看到 mx4jaddressmx4jport 虚拟机参数:

INFO  [main] 2020-05-14 16:04:19,007 CassandraDaemon.java:506 - JVM Arguments: [-Xloggc:/var/log/cassandra/gc.log, -ea, -XX:+UseThreadPriorities, -XX:ThreadPriorityPolicy=42, -XX:+HeapDumpOnOutOfMemoryError, -Xss256k, -XX:StringTableSize=1000003, -XX:+AlwaysPreTouch, -XX:-UseBiasedLocking, -XX:+UseTLAB, -XX:+ResizeTLAB, -XX:+UseNUMA, -XX:+PerfDisableSharedMem, -Djava.net.preferIPv4Stack=true, -XX:+UseParNewGC, -XX:+UseConcMarkSweepGC, -XX:+CMSParallelRemarkEnabled, -XX:SurvivorRatio=8, -XX:MaxTenuringThreshold=1, -XX:CMSInitiatingOccupancyFraction=75, -XX:+UseCMSInitiatingOccupancyOnly, -XX:CMSWaitDuration=10000, -XX:+CMSParallelInitialMarkEnabled, -XX:+CMSEdenChunksRecordAlways, -XX:+CMSClassUnloadingEnabled, -XX:+PrintGCDetails, -XX:+PrintGCDateStamps, -XX:+PrintHeapAtGC, -XX:+PrintTenuringDistribution, -XX:+PrintGCApplicationStoppedTime, -XX:+PrintPromotionFailure, -XX:+UseGCLogFileRotation, -XX:NumberOfGCLogFiles=10, -XX:GCLogFileSize=10M, -Xms3952M, -Xmx3952M, -Xmn600M, -XX:+UseCondCardMark, -XX:CompileCommandFile=/etc/cassandra/hotspot_compiler, -javaagent:/usr/share/cassandra/lib/jamm-0.3.0.jar, -Dcassandra.jmx.local.port=7199, -Dcom.sun.management.jmxremote.authenticate=false, -Dcom.sun.management.jmxremote.password.file=/etc/cassandra/jmxremote.password, -Djava.library.path=/usr/share/cassandra/lib/sigar-bin, -Dmx4jaddress=0.0.0.0, -Dmx4jport=7081, -XX:OnOutOfMemoryError=kill -9 %p, -Dlogback.configurationFile=logback.xml, -Dcassandra.logdir=/var/log/cassandra, -Dcassandra.storagedir=/var/lib/cassandra, -Dcassandra-pidfile=/var/run/cassandra/cassandra.pid, -XX:HeapDumpPath=/var/lib/cassandra/java_1589443456.hprof, -XX:ErrorFile=/var/lib/cassandra/hs_err_1589443456.log]

当然,直接在 cassandra-env.sh 脚本设置这两个环境变量也是可以的。

安全

虽然MX4J HttpAdaptor支持用基于户名和密码的基础认证,但是Cassandra没有使用这个特性,任何人都可以访问Web控制台,所以要谨慎决定是否要开启MX4J HttpAdaptor,以及监控的地址。

配置JMX

默认情况下,Cassandra开启了JMX的本地访问,监听端口是 7199 。在Cassandra所在服务器中运行JConsole, 新建连接窗口中选择 远程进程 ,在地址中填入 127.0.0.1:7199 ,用户名和密码留空,然后就可以连接了:

Cassandra配置JMX

由于默认配置下使用的不是SSL连接,JConsole会有警告信息,选择使用不安全连接就可以继续了:

Cassandra配置JMX

连接成功后,可以看到虚拟机的运行状态以及其他JMX信息:

Cassandra配置JMX

远程访问

开启远程访问首先需要在 /etc/default/cassandra 脚本中添加以下两个环境变量:

export LOCAL_JMX=no
  export JVM_OPTS="$JVM_OPTS -Djava.rmi.server.hostname=192.168.112.16"

其中,虚拟机参数 java.rmi.server.hostname 用来设置JMX服务访问的域名或者地址。如果不显试设置,可能会导致远程访问失败。这个地址不一定是服务监听的地址,比如如果cassandra运行在docker容器中,通过端口映射到宿主机上,那么就需要设置为宿主机的地址或者域名。

然后创建文件 /etc/cassandra/jmxremote.password ,用来设置JMX访问所需的用户名和密码,比如在文件中加入:

jmx 12345

这里 jmx 是用户名, 12345 是密码,两者之间用空格分隔。如果有多个用户,则每个用户一行。为了安全性,建议将这个文件设置为只有cassandra用户可以访问和修改。

如果配置成功,重启Cassandra服务可以在 system.log 中的jvm参数信息中看到 java.rmi.server.hostnamecassandra.jmx.remote.portcom.sun.management.jmxremote.rmi.portcom.sun.management.jmxremote.authenticatecom.sun.management.jmxremote.password.file 等的值:

INFO  [main] 2020-05-18 19:11:47,721 CassandraDaemon.java:506 - JVM Arguments: [-Djava.rmi.server.hostname=192.168.112.16, -Xloggc:/var/log/cassandra/gc.log, -ea, -XX:+UseThreadPriorities, -XX:ThreadPriorityPolicy=42, -XX:+HeapDumpOnOutOfMemoryError, -Xss256k, -XX:StringTableSize=1000003, -XX:+AlwaysPreTouch, -XX:-UseBiasedLocking, -XX:+UseTLAB, -XX:+ResizeTLAB, -XX:+UseNUMA, -XX:+PerfDisableSharedMem, -Djava.net.preferIPv4Stack=true, -XX:+UseParNewGC, -XX:+UseConcMarkSweepGC, -XX:+CMSParallelRemarkEnabled, -XX:SurvivorRatio=8, -XX:MaxTenuringThreshold=1, -XX:CMSInitiatingOccupancyFraction=75, -XX:+UseCMSInitiatingOccupancyOnly, -XX:CMSWaitDuration=10000, -XX:+CMSParallelInitialMarkEnabled, -XX:+CMSEdenChunksRecordAlways, -XX:+CMSClassUnloadingEnabled, -XX:+PrintGCDetails, -XX:+PrintGCDateStamps, -XX:+PrintHeapAtGC, -XX:+PrintTenuringDistribution, -XX:+PrintGCApplicationStoppedTime, -XX:+PrintPromotionFailure, -XX:+UseGCLogFileRotation, -XX:NumberOfGCLogFiles=10, -XX:GCLogFileSize=10M, -Xms3952M, -Xmx3952M, -Xmn600M, -XX:+UseCondCardMark, -XX:CompileCommandFile=/etc/cassandra/hotspot_compiler, -javaagent:/usr/share/cassandra/lib/jamm-0.3.0.jar, -Dcassandra.jmx.remote.port=7199, -Dcom.sun.management.jmxremote.rmi.port=7199, -Dcom.sun.management.jmxremote.authenticate=true, -Dcom.sun.management.jmxremote.password.file=/etc/cassandra/jmxremote.password, -Djava.library.path=/usr/share/cassandra/lib/sigar-bin, -Dmx4jaddress=0.0.0.0, -Dmx4jport=7081, -XX:OnOutOfMemoryError=kill -9 %p, -Dlogback.configurationFile=logback.xml, -Dcassandra.logdir=/var/log/cassandra, -Dcassandra.storagedir=/var/lib/cassandra, -Dcassandra-pidfile=/var/run/cassandra/cassandra.pid, -XX:HeapDumpPath=/var/lib/cassandra/java_1589800305.hprof, -XX:ErrorFile=/var/lib/cassandra/hs_err_1589800305.log]

接下来就可以远程访问Cassandra的JMX服务了:

Cassandra配置JMX

除了地址需要改成远程地址之后,还需要指定正确的用户名和密码。后面的操作就和上文中的例子一样了。

在上面的日志信息中,可以看到还有很多JMX相关的配置项。如果要调整这些配置,则需要修改 cassandra-env.sh 脚本。比如如果希望修改JMX服务监听的端口,需要在 cassandra-env.sh 脚本中找到以下部分,然后将 JMX_PORT 变量的值修改为期望的端口:

# Specifies the default port over which Cassandra will be available for
  # JMX connections.
  # For security reasons, you should not expose this port to the internet.  Firewall it if needed.
  JMX_PORT="7199"

修改保存后,重启Cassandra服务,成功的话就可以看到日志中的相关信息,并用新端口访问了。

其它相关的配置可以参考 cassandra-env.sh 脚本中的注释说明和Cassandra文档。

参考资料

  • Apache Cassandra - Installing Cassandra

  • Apache Cassandra - Metrics

  • Apache Cassandra - Security - JMX Access

  • MX4J - HttpAdaptor

原文  http://www.cnblogs.com/mithrilon/p/12883830.html
正文到此结束
Loading...