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控制台了:

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,用戶名和密碼留空,然后就可以連接了:

由於默認配置下使用的不是SSL連接,JConsole會有警告信息,選擇使用不安全連接就可以繼續了:

連接成功后,可以看到虛擬機的運行狀態以及其他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服務了:

除了地址需要改成遠程地址之后,還需要指定正確的用戶名和密碼。后面的操作就和上文中的例子一樣了。

在上面的日志信息中,可以看到還有很多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文檔。

參考資料


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM