Cassandra 文件

版本

您正在檢視預發行版本的說明文件。

完整查詢記錄

Apache Cassandra 4.0 新增一項新的高性能功能,支援即時查詢記錄 (CASSANDRA-13983)。FQL 安全可用於生產環境,並可設定堆積記憶體和磁碟空間的限制,以防止記憶體不足錯誤。此功能對即時流量擷取和流量重播很有用。所提供的工具可用於偵錯查詢流量和移轉。也新增了新的 nodetool 選項,以啟用、停用或重設 FQL,以及一個新的工具來讀取和重播二進位記錄。完整查詢記錄 (FQL) 功能使用 Chronicle-Queue 來輪替查詢記錄。完整查詢記錄在剩餘頁面中將稱為記錄

FQL 的一些功能包括

  • 非同步單一執行緒記錄項目寫入磁碟,可降低對查詢延遲的影響。

  • 堆積記憶體使用量受到加權佇列限制,可設定最大加權值,並置於記錄執行緒之前。

  • 如果加權佇列已滿,則生產者可能會被封鎖,或範例可能會被捨棄。

  • 磁碟使用量受到可設定大小的限制,一旦達到限制,就會刪除舊的記錄區段。

  • 一個彈性的架構二進位格式 Chronicle-Wire,用於磁碟上序列化,可以略過未辨識的欄位,新增新的欄位,並省略舊的欄位。

  • 可以使用 JMX 工具、nodetool 來啟用、停用或重設(刪除磁碟資料)。

  • 可以在 cassandra.yaml 檔案中設定設定,或使用 nodetool 設定。

  • 推出新的 fqltool,目前可以將二進位記錄檔轉儲為可讀格式。其他選項包括 ReplayCompare

FQL 會記錄所有成功的 Cassandra 查詢語言 (CQL) 要求,包括修改資料和查詢的事件。雖然稽核記錄也會包含 CQL 要求,但 FQL 只會記錄 CQL 要求。這個差異表示 FQL 可用於重播或比較記錄檔,而稽核記錄無法做到。FQL 對於除錯、效能基準測試、測試和稽核 CQL 查詢很有用,而稽核記錄則對於合規很有用。

在效能測試中,FQL 在只有 WRITE 的工作負載中似乎沒有或幾乎沒有負擔,而在 MIXED 工作負載中則有輕微的負擔。

記錄的查詢資訊

查詢記錄檔包含

  • 呼叫的所有查詢

  • 呼叫它們的近似時間

  • 繫結萬用字元值所需的任何參數

  • 所有查詢選項

記錄器會在 CQL 查詢完成後寫入單一或批次 CQL 查詢,因此只會記錄成功完成的查詢。失敗或逾時的查詢不會記錄。記錄的資料會根據查詢類型而有所不同。

單一 CQL 查詢記錄項目包含

  • query - CQL 查詢文字

  • queryOptions - 與查詢呼叫相關聯的選項

  • queryState - 與查詢呼叫相關聯的時間戳記狀態

  • queryTimeMillis - 自查詢呼叫以來,自紀元以來的近似時間(毫秒)

批次 CQL 查詢記錄項目包含

  • queries - 查詢的 CQL 文字

  • queryOptions - 與查詢呼叫相關聯的選項

  • queryState - 與查詢呼叫相關聯的時間戳記狀態

  • batchTimeMillis - 自批次呼叫以來,自紀元以來的近似時間(毫秒)

  • type - 批次的類型

  • values - 要繫結為查詢參數的值

由於 FQL 由 Binlog 支援,因此效能和佔用空間是可預測的,對記錄記錄產生器的影響很小。效能安全可防止產生器過載記錄,使用加權佇列在記錄落後時捨棄記錄。單執行緒非同步寫入會產生記錄檔。Chronicle-Queue 提供了一種輕鬆的方法來滾動記錄檔。

記錄的記錄資訊

FQL 也會追蹤儲存的記錄檔資訊

  • 已新增的儲存記錄檔及其儲存影響。如果超過儲存限制,就會刪除這些記錄檔。

  • Chronicle-Queue 中已滾動的記錄檔

  • 已滾動的記錄檔中的位元組數

記錄順序

記錄器會遵循一連串定義良好的事件

  1. 撰寫記錄記錄的消費者執行緒已啟動。此動作只能執行一次。

  2. 消費者執行緒會提供記錄給記錄檔。如果記憶體內佇列已滿,記錄將會被捨棄,而提供會傳回 false 值。

  3. 如果已接受,記錄會輸入記錄檔。如果記憶體內佇列已滿,放置執行緒會被封鎖,直到有空間或中斷為止。

  4. 執行緒結束時會清除緩衝區。完成處理會再次檢查,以確保佇列中沒有落後者。

  5. 消費者執行緒已停止。可以呼叫多次。

使用 FQL

若要使用 FQL,必須完成兩個動作。必須使用 cassandra.yaml 檔案或 nodetool 設定 FQL,並使用 nodetool enablefullquerylog 啟用記錄。使用任一種方法,至少必須指定記錄目錄的路徑。兩個動作都是以每個節點為基礎完成。每個已啟用的節點都會產生完整的查詢記錄,因此每個節點上的記錄都會有該節點的查詢。

在 cassandra.yaml 中設定 FQL

cassandra.yaml 檔案可用於在使用 nodetool 啟用功能之前設定 FQL。

檔案包含下列可用於取消註解以供使用的選項

# default options for full query logging - these can be overridden from command line
# when executing nodetool enablefullquerylog
#full_query_logging_options:
   # log_dir:
   # roll_cycle: HOURLY
   # block: true
   # max_queue_weight: 268435456 # 256 MiB
   # max_log_size: 17179869184 # 16 GiB
   # archive command is "/path/to/script.sh %path" where %path is replaced with the file being rolled:
   # archive_command:
   # max_archive_retries: 10

log_dir

若要撰寫記錄,必須在 log_dir 中設定現有目錄。

目錄必須設定適當的權限,以允許讀取、寫入和執行。記錄會根據需要遞迴刪除目錄內容。請勿將連結放置在此目錄中以連結到檔案系統的其他區段。例如,log_dir: /tmp/cassandrafullquerylog

roll_cycle

roll_cycle 定義記錄區段滾動的頻率。支援的值為 HOURLY(預設值)、MINUTELYDAILY。例如:roll_cycle: DAILY

block

block 選項指定如果 FQL 落後,FQL 是否應封鎖寫入或捨棄記錄記錄。支援的布林值為 true(預設值)或 false。例如:block: false 以捨棄記錄

max_queue_weight

max_queue_weight 選項設定等待寫入檔案的記錄在記憶體內佇列中的最大權重,然後封鎖或捨棄。選項必須設定為正值。預設值為 268435456,或 256 MiB。例如,若要變更預設值:max_queue_weight: 134217728 # 128 MiB

max_log_size

max_log_size 選項設定滾動檔案保留在磁碟上並刪除最舊檔案前的最大大小。此選項必須設定為正值。預設值為 17179869184,或 16 GiB。例如,若要變更預設值:max_log_size: 34359738368 # 32 GiB

archive_command

archive_command 選項設定使用者定義的歸檔指令碼,以在滾動的日誌檔案上執行。未定義時,檔案會被刪除,預設值為 "",然後對應到 org.apache.cassandra.utils.binlog.DeletingArchiver。例如:archive_command: /usr/local/bin/archiveit.sh %path # %path 是正在滾動的檔案

max_archive_retries

max_archive_retries 選項設定失敗歸檔指令碼的最大重試次數。預設值為 10。例如:max_archive_retries: 10

在啟用此功能時,FQL 也可以使用 nodetool 設定,而且會覆寫 cassandra.yaml 檔案中設定的任何值,如下一節所述。

啟用 FQL

使用 nodetool enablefullquerylog 指令在每個節點上啟用 FQL。至少必須定義記錄目錄的路徑,如果 log_dir 未設定在 cassandra.yaml 檔案中。

nodetool enablefullquerylog 指令的語法具有所有可以在 cassandra.yaml 檔案中設定的選項。此外,nodetool 有選項設定要執行指令的主機和埠,以及指令需要驗證時的使用者名稱和密碼。

  nodetool [(-h <host> | --host <host>)] [(-p <port> | --port <port>)]
 [(-pp | --print-port)] [(-pw <password> | --password <password>)]
 [(-pwf <passwordFilePath> | --password-file <passwordFilePath>)]
 [(-u <username> | --username <username>)] enablefullquerylog
 [--archive-command <archive_command>] [--blocking]
 [--max-archive-retries <archive_retries>]
 [--max-log-size <max_log_size>] [--max-queue-weight <max_queue_weight>]
 [--path <path>] [--roll-cycle <roll_cycle>]

 OPTIONS
   --archive-command <archive_command>
  Command that will handle archiving rolled full query log files.
  Format is "/path/to/script.sh %path" where %path will be replaced
  with the file to archive

   --blocking
  If the queue is full whether to block producers or drop samples.

   -h <host>, --host <host>
  Node hostname or ip address

   --max-archive-retries <archive_retries>
  Max number of archive retries.

   --max-log-size <max_log_size>
  How many bytes of log data to store before dropping segments. Might
  not be respected if a log file hasn't rolled so it can be deleted.

   --max-queue-weight <max_queue_weight>
  Maximum number of bytes of query data to queue to disk before
  blocking or dropping samples.

   -p <port>, --port <port>
  Remote jmx agent port number

   --path <path>
  Path to store the full query log at. Will have it's contents
  recursively deleted.

   -pp, --print-port
  Operate in 4.0 mode with hosts disambiguated by port number

   -pw <password>, --password <password>
  Remote jmx agent password

   -pwf <passwordFilePath>, --password-file <passwordFilePath>
  Path to the JMX password file

   --roll-cycle <roll_cycle>
  How often to roll the log file (MINUTELY, HOURLY, DAILY).

   -u <username>, --username <username>
  Remote jmx agent username

若要啟用 FQL,請在叢集中您要啟用記錄的每個節點上執行下列指令

$ nodetool enablefullquerylog --path /tmp/cassandrafullquerylog

停用或重設 FQL

使用 nodetool disablefullquerylog 停用記錄。使用 nodetool resetfullquerylog 停止 FQL 並清除已設定目錄中的日誌檔案。重要:使用 nodetool resetfullquerylog 會刪除日誌檔案!除非您需要刪除所有日誌檔案,否則請勿使用此指令。

fqltool

fqltool 指令用於檢視 (傾印)、重播或比較日誌。fqltool dump 會將二進位日誌檔案轉換成人類可讀的格式;只有日誌目錄必須提供為指令列選項。

fqltool replay (CASSANDRA-14618) 啟用日誌重播。此指令可從不同的機器或叢集執行,以進行測試、偵錯或效能基準測試。此指令也可拿來重新建立已刪除的資料庫物件。使用 fqltool replay 記錄並比較不同版本的 Cassandra 或不同叢集的生產流量。另一種用途是從多部機器收集日誌,並按記錄的時間戳順序「依序」重播。

fqltool replay 的語法為

  fqltool replay [--keyspace <keyspace>] [--results <results>]
 [--store-queries <store_queries>] --target <target>... [--] <path1>
 [<path2>...<pathN>]

 OPTIONS
   --keyspace <keyspace>
  Only replay queries against this keyspace and queries without
  keyspace set.

   --results <results>
  Where to store the results of the queries, this should be a
  directory. Leave this option out to avoid storing results.

   --store-queries <store_queries>
  Path to store the queries executed. Stores queries in the same order
  as the result sets are in the result files. Requires --results

   --target <target>
  Hosts to replay the logs to, can be repeated to replay to more
  hosts.

   --
  This option can be used to separate command-line options from the
  list of argument, (useful when arguments might be mistaken for
  command-line options

   <path1> [<path2>...<pathN>]
  Paths containing the FQ logs to replay.

fqltool compare (CASSANDRA-14619) 比較 fqltool replay 所產生的結果檔案。此指令使用 fqltool replay 記錄的執行結果,並比較日誌,輸出任何差異(可能是所有查詢)。它也會將每列儲存為一個獨立的編年文件,以避免在比較時從記憶體中讀取整個結果。

fqltool compare 的語法為

   fqltool compare --queries <queries> [--] <path1> [<path2>...<pathN>]

 OPTIONS
   --queries <queries>
  Directory to read the queries from. It is produced by the fqltool
  replay --store-queries option.

   --
  This option can be used to separate command-line options from the
  list of argument, (useful when arguments might be mistaken for
  command-line options

   <path1> [<path2>...<pathN>]
  Directories containing result files to compare.

比較會設定下列標記

  • 標記查詢集的開頭

  version: int16
  type: column_definitions
  column_count: int32;
  column_definition: text, text
  column_definition: text, text
  ....
  • 標記失敗的查詢集

  version: int16
  type: query_failed
  message: text
  • 標記列集

  version: int16
  type: row
  row_column_count: int32
  column: bytes
  • 標記結果集的結尾

  version: int16
  type: end_resultset

範例

  1. 要示範 FQL,請先在叢集中的節點上設定並啟用 FQL

$ nodetool enablefullquerylog --path /tmp/cassandrafullquerylog
  1. 現在使用 cqlsh 建立一個示範鍵空間和表格,並插入一些資料

 cqlsh> CREATE KEYSPACE querylogkeyspace
   ... WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};
 cqlsh> USE querylogkeyspace;
 cqlsh:querylogkeyspace> CREATE TABLE t (
 ...id int,
 ...k int,
 ...v text,
 ...PRIMARY KEY (id)
 ... );
 cqlsh:querylogkeyspace> INSERT INTO t (id, k, v) VALUES (0, 0, 'val0');
 cqlsh:querylogkeyspace> INSERT INTO t (id, k, v) VALUES (0, 1, 'val1');
  1. 然後檢查資料是否已插入

 cqlsh:querylogkeyspace> SELECT * FROM t;

 id | k | v
 ----+---+------
  0 | 1 | val1

 (1 rows)
  1. 使用 fqltool dump 指令檢視日誌。

$ fqltool dump /tmp/cassandrafullquerylog

此指令會傳回日誌的可讀版本。以下是此示範中指令的日誌部分範例

WARN  [main] 2019-08-02 03:07:53,635 Slf4jExceptionHandler.java:42 - Using Pauser.sleepy() as not enough processors, have 2, needs 8+
      Type: single-query
      Query start time: 1564708322030
      Protocol version: 4
      Generated timestamp:-9223372036854775808
      Generated nowInSeconds:1564708322
      Query: SELECT * FROM system.peers
      Values:

      Type: single-query
      Query start time: 1564708322054
      Protocol version: 4
      Generated timestamp:-9223372036854775808
      Generated nowInSeconds:1564708322
      Query: SELECT * FROM system.local WHERE key='local'
      Values:

      Type: single-query
      Query start time: 1564708322109
      Protocol version: 4
      Generated timestamp:-9223372036854775808
      Generated nowInSeconds:1564708322
      Query: SELECT * FROM system_schema.keyspaces
      Values:

      Type: single-query
      Query start time: 1564708322116
      Protocol version: 4
      Generated timestamp:-9223372036854775808
      Generated nowInSeconds:1564708322
      Query: SELECT * FROM system_schema.tables
      Values:

      Type: single-query
      Query start time: 1564708322139
      Protocol version: 4
      Generated timestamp:-9223372036854775808
      Generated nowInSeconds:1564708322
      Query: SELECT * FROM system_schema.columns
      Values:

      Type: single-query
      Query start time: 1564708322142
      Protocol version: 4
      Generated timestamp:-9223372036854775808
      Generated nowInSeconds:1564708322
      Query: SELECT * FROM system_schema.functions
      Values:

      Type: single-query
      Query start time: 1564708322141
      Protocol version: 4
      Generated timestamp:-9223372036854775808
      Generated nowInSeconds:1564708322
      Query: SELECT * FROM system_schema.aggregates
      Values:

      Type: single-query
      Query start time: 1564708322143
      Protocol version: 4
      Generated timestamp:-9223372036854775808
      Generated nowInSeconds:1564708322
      Query: SELECT * FROM system_schema.types
      Values:

      Type: single-query
      Query start time: 1564708322144
      Protocol version: 4
      Generated timestamp:-9223372036854775808
      Generated nowInSeconds:1564708322
      Query: SELECT * FROM system_schema.indexes
      Values:

      Type: single-query
      Query start time: 1564708322145
      Protocol version: 4
      Generated timestamp:-9223372036854775808
      Generated nowInSeconds:1564708322
      Query: SELECT * FROM system_schema.views
      Values:

      Type: single-query
      Query start time: 1564708345408
      Protocol version: 4
      Generated timestamp:-9223372036854775808
      Generated nowInSeconds:-2147483648
      Query: CREATE KEYSPACE querylogkeyspace
      WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};
      Values:

      Type: single-query
      Query start time: 1564708360873
      Protocol version: 4
      Generated timestamp:-9223372036854775808
      Generated nowInSeconds:-2147483648
      Query: USE querylogkeyspace;
      Values:

      Type: single-query
      Query start time: 1564708360874
      Protocol version: 4
      Generated timestamp:-9223372036854775808
      Generated nowInSeconds:-2147483648
      Query: USE "querylogkeyspace"
      Values:

      Type: single-query
      Query start time: 1564708378837
      Protocol version: 4
      Generated timestamp:-9223372036854775808
      Generated nowInSeconds:-2147483648
      Query: CREATE TABLE t (
          id int,
          k int,
          v text,
          PRIMARY KEY (id)
      );
      Values:

      Type: single-query
      Query start time: 1564708379247
      Protocol version: 4
      Generated timestamp:-9223372036854775808
      Generated nowInSeconds:1564708379
      Query: SELECT * FROM system_schema.tables WHERE keyspace_name = 'querylogkeyspace' AND table_name = 't'
      Values:

      Type: single-query
      Query start time: 1564708397144
      Protocol version: 4
      Generated timestamp:-9223372036854775808
      Generated nowInSeconds:1564708397
      Query: INSERT INTO t (id, k, v) VALUES (0, 0, 'val0');
      Values:

      Type: single-query
      Query start time: 1564708434782
      Protocol version: 4
      Generated timestamp:-9223372036854775808
      Generated nowInSeconds:1564708434
      Query: SELECT * FROM t;
      Values:
  1. 要示範 fqltool replay,請先刪除鍵空間。

cqlsh:querylogkeyspace> DROP KEYSPACE querylogkeyspace;
  1. 現在執行 fqltool replay,並分別在 --results--store-queries 中指定要儲存查詢結果的目錄和執行的查詢清單

$ fqltool replay \
--keyspace querylogkeyspace --results /cassandra/fql/logs/results/replay \
--store-queries /cassandra/fql/logs/queries/replay \
-- target 3.91.56.164 \
/tmp/cassandrafullquerylog

--results--store-queries 目錄是選用的,但如果設定了 --store-queries,則也必須設定 --results--target 指定要重播日誌的節點。

  1. 使用 DESCRIBE KEYSPACES 指令檢查鍵空間是否已重播並再次存在

 cqlsh:querylogkeyspace> DESC KEYSPACES;

 system_schema  system  system_distributed  system_virtual_schema
 system_auth    querylogkeyspace  system_traces  system_views