【问题标题】:Cassandra nodes failing on heavy writesCassandra 节点在大量写入时失败
【发布时间】:2013-11-01 00:42:00
【问题描述】:

我是 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)、Name (Text)、Insert_User (Text) 和 Insert_TimeStamp (TimeStamp)。该代码只是尝试以 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 设置在这里(为了节省空间而删除了 cmets):

#Cassandra 存储配置 YAML 集群名称:“开发” 初始令牌: max_hint_window_in_ms: 10800000 # 3 小时 提示的_handoff_throttle_in_kb:1024 max_hints_delivery_threads:2 验证器:密码验证器 授权人:CassandraAuthorizer permissions_validity_in_ms: 2000 分区器:org.apache.cassandra.dht.Murmur3Partitioner 数据文件目录: - /var/lib/cassandra/数据 提交日志目录:/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:序列化缓存提供者 saved_caches_directory: /var/lib/cassandra/saved_caches commitlog_sync:定期 commitlog_sync_period_in_ms: 10000 commitlog_segment_size_in_mb:32 种子提供者: - 类名: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:假 涓流_fsync_interval_in_kb:10240 存储端口:7000 ssl_storage_port:7001 监听地址:本地主机 start_native_transport:真 native_transport_port: 9042 start_rpc: 真 rpc_address:本地主机 rpc_port:9160 rpc_keepalive: 真 rpc_server_type:同步 thrift_framed_transport_size_in_mb:15 增量备份:假 快照之前的压缩:假 自动快照:真 column_index_size_in_kb:64 in_memory_compaction_limit_in_mb:64 多线程压缩:假 compaction_throughput_mb_per_sec: 16 compaction_preheat_key_cache:真 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: 假 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 server_encryption_options: internode_encryption:无 密钥库:conf/.keystore keystore_password:卡桑德拉 信任库:conf/.truststore truststore_password:cassandra 客户端加密选项: 启用:假 密钥库:conf/.keystore keystore_password:卡桑德拉 internode_compression:全部 inter_dc_tcp_nodelay:真

这项工作的目标是让 Cassandra 节点保持稳定,即使这需要每个节点的写入速度较慢(当前的写入速度约为每秒 7,000 条记录)。在 Internet 上搜索 StackOverflow 和其他位置后,我还没有找到解决此问题的正确方法,如果有在高写入量环境中使用 Cassandra 经验的人提供任何反馈,我将不胜感激。

最好的,

汤姆

【问题讨论】:

    标签: c# linq cassandra


    【解决方案1】:

    日志是怎么说的?您是否看到此错误:堆已满 89.2615008651467%。您可能需要减少 memtable 和/或缓存大小。

    如果是这样,罪魁祸首可能是CASSANDRA-6107。问题是准备好的语句被缓存,但是可以缓存的查询数量限制太高并且没有考虑每个语句的大小(如果您执行批处理语句,它将比简单的选择高得多)这耗尽了节点的内存。此外,由于该语句被缓存,它不会被 GC 删除,从而导致 OOM 错误。

    【讨论】:

    • 我对内存表和缓存大小进行了许多不同的调整。仍然没有运气。问题是我正在编写的应用程序每天晚上需要大量写入。
    猜你喜欢
    • 2016-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-06
    • 2021-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多