3

私は Cassandra を初めて使用し、書き込み負荷をテストしていますが、Cassandra の安定性に問題があります。まず、環境に関する情報を少し:

  • Windows (Windows 7 および 8、Server 2008 R2 および Server 2012 を搭載した PC でテスト済み)
  • Java 7 u 45 の使用 (この質問の執筆時点で入手可能な最新のもの)
  • カサンドラ 1.2.10
  • Cassandra C# 1.01 ドライバーを使用した Cassandra へのアクセス
  • クラスターのサイズに関係なく問題が発生します (クラスター内の 1 ノードから 6 ノードまでのテスト)。
  • データ用のディスクは SSD です。

私が作成しているアプリケーションは、Cassandra で知られている高度な書き込み (および読み取り) 機能を必要とする、非常に大きな情報のデータセットを処理します。

私が使用している例では、ID (GUID)、名前 (テキスト)、Insert_User (テキスト)、および Insert_TimeStamp (タイムスタンプ) の 4 つのフィールドを持つ「テスト」オブジェクトを作成します。このコードは、50,000 件のバッチで 100 万件のレコードを作成しようとするだけです。通常、150,000 ~ 200,000 レコードに達すると、書き込みプロセスは失敗します。ほとんどの場合、書き込みタイムアウト例外が発生します (タイムアウトは 20 秒に設定されています)。ヒープがオーバーフローすることもありますが、cassandra.yaml ファイルのキャッシュとフラッシュの設定を調整し、次の Java 構成設定でヒープを拡張することで、その問題を解決したようです。

-Xmx20G -Xms1G -Xss256K

私が使用しているコードは次のとおりです。

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Cassandra;
using Cassandra.Data.Linq;

namespace TestLinq3
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WindowWidth = 160;

            Stopwatch sw = new Stopwatch();
            sw.Start();
            Console.WriteLine("Started at " + System.DateTime.Now);

            var cluster = Cluster.Builder()
                        .AddContactPoint("127.0.0.1")
                        .WithCredentials("cassandra", "cassandra")
                        .Build();

            Metadata metadata = cluster.Metadata;

            Console.WriteLine("Starting process...");

            var session = cluster.Connect();
            session.CreateKeyspaceIfNotExists("test");
            session.ChangeKeyspace("test");

            Console.WriteLine("Connected to keyspace...");

            var table = session.GetTable<Test>();
            table.CreateIfNotExists();

            List<Test> testlist = new List<Test>();

            for (int j = 0; j < 20; j++)
            {
                Console.WriteLine("Running j loop " + j.ToString());

                var batch = session.CreateBatch();

                for (int i = 0; i < 50000; i++)
                {
                    testlist.Add(new Test { id = System.Guid.NewGuid(), name = "Name " + i, insertUser = "cassandra", insertTimeStamp = System.DateTimeOffset.UtcNow });
                }

                batch.Append(from t in testlist select table.Insert(t));

                try
                {
                    batch.Execute();
                    //Flush();
                }
                catch (WriteTimeoutException ex)
                {
                    Console.WriteLine("WriteTimeoutException hit.  Waiting 20 seconds...");
                    Console.WriteLine(ex.StackTrace);
                    System.Threading.Thread.Sleep(60000);
                }

                batch = null;

                Console.WriteLine("Time elapsed since start is " + sw.Elapsed.Hours.ToString("00")+":"+sw.Elapsed.Minutes.ToString("00")+":"+sw.Elapsed.Seconds.ToString("00"));
            }

            var results = (from rows in table where rows.name == "Name 333" select rows).Execute().Count();

            Console.WriteLine(results);

            sw.Stop();

            Console.WriteLine("Processing time was " + sw.Elapsed.Hours.ToString("00") + ":" + sw.Elapsed.Minutes.ToString("00") + ":" + sw.Elapsed.Seconds.ToString("00") + ":" + sw.Elapsed.Milliseconds.ToString("00") + ".");

            Console.ReadLine();
        }

        [AllowFiltering]
        [Table("test")]
        public class Test
        {
            [PartitionKey]
            [Column("id")]
            public Guid id;
            [SecondaryIndex]
            [Column("name")]
            public string name;
            [SecondaryIndex]
            [Column("insert_user")]
            public string insertUser;
            [SecondaryIndex]
            [Column("insert_timestamp")]
            public DateTimeOffset insertTimeStamp;
        }
    }
}

Cassandra.yaml の設定は次のとおりです (スペースを節約するためにコメントは削除されています)。

#Cassandra ストレージ構成 YAML
cluster_name: 'DEV'
initial_token:
max_hint_window_in_ms: 10800000 # 3 時間
Hinted_handoff_throttle_in_kb: 1024
max_hints_delivery_threads: 2
オーセンティケーター: PasswordAuthenticator
承認者: CassandraAuthorizer
permissions_validity_in_ms: 2000
パーティショナー: org.apache.cassandra.dht.Murmur3Partitioner
data_file_directories:
    - /var/lib/カサンドラ/データ
commitlog_directory: /var/lib/cassandra/commitlog
disk_failure_policy: 停止
key_cache_size_in_mb:
key_cache_save_period: 14400
row_cache_size_in_mb: 0
row_cache_save_period: 0
row_cache_provider: SerializingCacheProvider
saved_caches_directory: /var/lib/cassandra/saved_caches
commitlog_sync: 定期的
commitlog_sync_period_in_ms: 10000
commitlog_segment_size_in_mb: 32
シードプロバイダー:
    - class_name: org.apache.cassandra.locator.SimpleSeedProvider
        - シード: 「127.0.0.1」
flush_largest_memtables_at: 0.50
reduce_cache_sizes_at: 0.50
reduce_cache_capacity_to: 0.30
同時読み取り: 32
同時書き込み数: 32
memtable_total_space_in_mb: 4096
memtable_flush_writers: 8
memtable_flush_queue_size: 4
トリクル_fsync: false
トリクル_fsync_interval_in_kb: 10240
ストレージ_ポート: 7000
ssl_ストレージ_ポート: 7001
listen_address: ローカルホスト
start_native_transport: 真
ネイティブ_トランスポート_ポート: 9042
start_rpc: 真
rpc_address: ローカルホスト
rpc_port: 9160
rpc_keepalive: 真
rpc_server_type: 同期
thrift_framed_transport_size_in_mb: 15
incremental_backups: false
snapshot_before_compaction: false
auto_snapshot: 真
column_index_size_in_kb: 64
in_memory_compaction_limit_in_mb: 64
multithreaded_compaction: false
圧縮_スループット_mb_per_sec: 16
Compaction_preheat_key_cache: true
read_request_timeout_in_ms: 10000
range_request_timeout_in_ms: 10000
write_request_timeout_in_ms: 10000
truncate_request_timeout_in_ms: 60000
request_timeout_in_ms: 10000
cross_node_timeout: false
endpoint_snitch: SimpleSnitch
dynamic_snitch_update_interval_in_ms: 100
dynamic_snitch_reset_interval_in_ms: 600000
dynamic_snitch_badness_threshold: 0.1
request_scheduler: org.apache.cassandra.scheduler.NoScheduler
インデックス間隔: 128
サーバー暗号化オプション:
    ノード間の暗号化: なし
    キーストア: conf/.keystore
    keystore_password: カサンドラ
    トラストストア: conf/.truststore
    truststore_password: カサンドラ
client_encryption_options:
    有効: false
    キーストア: conf/.keystore
    keystore_password: カサンドラ
internode_compression: すべて
inter_dc_tcp_nodelay: 真

この取り組みの目標は、ノードごとの書き込みペースを遅くする必要がある場合でも、Cassandra ノードを安定させることです (現在の書き込み速度は 1 秒あたり約 7,000 レコードです)。StackOverflow やインターネット上の他の場所を検索した後、この問題の正しい修正が見つかりませんでした。大量の書き込み環境で Cassandra の経験をお持ちの方からのフィードバックをお待ちしております。

一番、

トム

4

1 に答える 1

0

ログには何と書かれていますか? 次のエラーが表示されますか: Heap is 89.2615008651467% full. memtable やキャッシュのサイズを減らす必要があるかもしれません。

もしそうなら、犯人はおそらくCASSANDRA-6107です。問題は、準備されたステートメントがキャッシュされていたが、キャッシュできるクエリの数の制限が高すぎて、各ステートメントのサイズを考慮していなかったことです (バッチステートメントを実行した場合、単純な選択よりもはるかに大きくなります)これはノードのメモリを使い果たしていました。また、ステートメントはキャッシュされているため、GC によって削除されず、OOM エラーが発生します。

于 2013-11-18T18:53:10.420 に答える