NoSQLのCassandraの大量データロードのチューニング(1ノードで)

◆ Live配信スケジュール ◆
サイオステクノロジーでは、Microsoft MVPの武井による「わかりみの深いシリーズ」など、定期的なLive配信を行っています。
⇒ 詳細スケジュールはこちらから
⇒ 見逃してしまった方はYoutubeチャンネルをご覧ください
【5/21開催】Azure OpenAI ServiceによるRAG実装ガイドを公開しました
生成AIを活用したユースケースで最も一番熱いと言われているRAGの実装ガイドを公開しました。そのガイドの紹介をおこなうイベントです!!
https://tech-lab.connpass.com/event/315703/

前回の検証の振り返り

前回のブログで、Cassandraへの大量データのロードと全件検索の性能をPostgreSQLと比較して検証しました。

1ノード構成ではありますが、この時のCassandra側の性能が、PostgreSQLに比べると圧倒的に遅いことがわかりました。

以下は前回のブログで検証した結果です。
CassandraもPostgreSQLもパラメータチューニングなしです。

100万件のロードの所要時間

  • PostgreSQL:約3秒
  • Cassandra:タイムアウト頻発、約5分30秒

100万件の全件カウント検索の所要時間

  • PostgreSQL:1秒未満
  • Cassandra:タイムアウト発生で検索できず。タイムアウトしないように設定して約30秒

今回は、大量データロード時のCassandraのタイムアウトを抑止して、処理時間を短縮した方法と検証結果を紹介します。
検索の方は、次回のブログで書きます。

100万件のロードのタイムアウトを解決し、ロード時間を短縮した方法

何度かロードを繰り返していると、そのうちに、5分30秒どころか、タイムアウト頻発で終わらなくなりました。

cqlsh:ks2> COPY emp(empno,ename,deptno) FROM 'sampledata1000000.csv' ;
Using 1 child processes

Starting copy of ks2.emp with columns [empno, ename, deptno].
Failed to import 10 rows: WriteTimeout - Error from server: code=1100 [Coordinator node timed out waiting for replica nodes' responses] message="Operation timed out - received only 0 responses." info={'received_responses': 0, 'required_responses': 1, 'consistency': 'ONE'},  will retry later, attempt 1 of 5
Failed to import 20 rows: WriteTimeout - Error from server: code=1100 [Coordinator node timed out waiting for replica nodes' responses] message="Operation timed out - received only 0 responses." info={'received_responses': 0, 'required_responses': 1, 'consistency': 'ONE'},  will retry later, attempt 1 of 5
Failed to import 20 rows: WriteTimeout - Error from server: code=1100 [Coordinator node timed out waiting f

vmstatを見ていると、スワップが頻発していることに気づきます。

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 1  1 225792  68404      0 173504 19320 9652 22108  9652 2546 6992 29 13  0 59  0
 3  3 223328  71264      0 172104 25288 11640 28716 11880 4443 11220 32 16  0 52  0
 1  1 225648  67032      0 173492 22780 11068 25432 11068 2804 3002  5  8  0 87  0
 1  1 225144  71016      0 172040 11200 1776 13332  1776 1744 1632  1  4  0 95  0

JVMの起動オプション「-Xms」を確認すると、ヒープサイズが496Mと設定されていることがわかりました。
スワップが発生していた原因は、jvmのヒープサイズのデフォルト値496Mに対して、OSのメモリ1GBが少なすぎたことでした。

CassandraのJVMヒープサイズデフォルト値の計算ロジック

max(min(1/2 ram, 1024 megabytes), min(1/4 ram, 32765 megabytes))

引用元:https://docs.datastax.com/en/dse/6.7/dse-admin/datastax_enterprise/operations/opsConHeapSize.html#opsConHeapSize__jvmoptions

そこで、OSのメモリを1GB→2GBに増やして再度ロードしてみました。

cqlsh:ks2> COPY emp(empno,ename,deptno) FROM 'sampledata1000000.csv' ;
Using 1 child processes

Starting copy of ks2.emp with columns [empno, ename, deptno].
Processed: 1000000 rows; Rate:    4398 rows/s; Avg. rate:    6141 rows/s
1000000 rows imported from 1 files in 2 minutes and 42.846 seconds (0 skipped).

2分42秒で終わりました。
スワップは発生しなくなり、タイムアウトも抑止できました。
Cassandra側のパラメータは何も変更していません。

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
15  0      0  85936    164 417256    0    0     0     0 1313  667 97  3  0  0  0
20  0      0  82372    164 421364    0    0     0     0 1256  632 97  3  0  0  0
 2  0      0  77576    164 425492    0    0     0     0 1302  717 98  2  0  0  0

PostgreSQLで同じことをすると約3秒で終わりました。
もっと早くできないでしょか?

Cassandraの書き込みアーキテクチャHow is data written?を参照し、書き込み処理を早くする方法として思いつくものを洗い出してみました。

  1. 書き込みのプロセス数を増やす
  2. メモリ領域(memtable)を増やして、ディスク(sstable)へのフラッシュ頻度を減らす
  3. ロード中にcommitlogへの書き込みを中止する
  4. GCの回数を減らす

vmstatではrunqueの数も多かったので、1.の方法を試すこととし、CPUを増やして複数プロセスで処理することでロード時間を短縮できないかを検証してみました。
2~4の方法は、次回以降で調査してみて、いい方法があれば検証してみます。

さて、copyコマンドを複数プロセスで実行する方法を調べたところ、

numprocesses

というオプションがありました。
これは使えそうです。
CPUを10個に増やして2プロセスで実行すると、処理速度はほぼ倍の1分25秒になりました。

cqlsh:ks2> COPY emp(empno,ename,deptno) FROM 'sampledata1000000.csv' with numprocesses=2;
Reading options from the command line: {'numprocesses': '2'}
Using 2 child processes

Starting copy of ks2.emp with columns [empno, ename, deptno].
Processed: 1000000 rows; Rate:   13562 rows/s; Avg. rate:   11650 rows/s
1000000 rows imported from 1 files in 1 minute and 25.840 seconds (0 skipped).

numprocessesの値を増やしてcopyコマンドを実行した結果です。

表 numprocesseの値1~9までの処理時間と処理行数

グラフ

CPU10個に対してプロセス数は7で処理性能が頭打ちとなりましたが、処理時間を20秒まで短縮できました。
PostgreSQLだと3秒で終わったので、かなり不満ですが。。。

それは置いといて、1ノードでもCPUを増やすと速度を向上させることができたことがわかりました。
ノードを増やすとどうなるのだろうか。。

アバター画像
About 髙岡 貴史 21 Articles
登山家兼投資家兼インフラ寄りのエンジニア。最近はDatastaxを中心としたデータ処理基盤に関心あり。
ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。


ご覧いただきありがとうございます。
ブログの最新情報はSNSでも発信しております。
ぜひTwitterのフォロー&Facebookページにいいねをお願い致します!



>> 雑誌等の執筆依頼を受付しております。
   ご希望の方はお気軽にお問い合わせください!

Be the first to comment

Leave a Reply

Your email address will not be published.


*


質問はこちら 閉じる