我们正在尝试在标准 VPC 足迹(私有子网上的 cassandra 节点)内的 AWS/EC2 上运行 cassandra 集群。因为这是 AWS,所以 EC2 实例总是有可能在没有警告的情况下终止或重启。我一直在测试集群上模拟这种情况,并且我看到集群中的一些事情,我认为集群应该阻止。特别是如果节点重新启动,一些数据将暂时丢失,直到节点完成重新启动。如果节点终止,则似乎某些数据将永远丢失。
对于我的测试,我只是对一些键空间进行了一系列写入(使用 QUORUM 一致性),然后在关闭节点(通过重新启动或终止)时询问这些键空间的内容。我只是使用 cqlsh SELECT 来使用 ONE 一致性级别对集群进行键空间/列族询问。
请注意,即使我在执行 SELECT 时没有对集群执行任何写入操作,但在重新启动时会暂时消失,并且在终止期间可能会永久丢失。
我认为 Netflix Priam 可能会提供帮助,但遗憾的是,我上次检查时它在 VPC 中不起作用。
此外,因为我们使用的是临时存储实例,所以没有相当于“关闭”的功能,因此我无法在实例重启/终止期间运行任何脚本来执行nodetool decommission
或nodetool removenode
在实例消失之前运行任何脚本。Terminate 相当于将插头踢出墙外。
由于我使用的是 3 的复制因子和 quorum/write,这应该意味着所有数据都写入至少 2 个节点。因此,除非我完全误解了事情(这是可能的),否则丢失一个节点并不意味着当我使用一致性级别 ONE 进行读取时,我会丢失任何时间段内的任何数据。
问题
为什么复制因子为 3 的 6 节点集群不能工作?
我是否需要运行复制因子为 7 的 12 节点集群?不要费心告诉我这会解决问题,因为它不会。
我是否需要在写入时使用 ALL 的一致性级别,然后在读取时使用 ONE 或 QUORUM?
虚拟节点有什么不对劲的地方吗?不太可能
当节点终止以恢复丢失的数据时,除了 removenode 之外,我还需要运行 nodetool 命令吗?如前所述,当重新启动时,丢失的数据最终会重新出现。
是否有一些 cassandra 专家可以查看我下面的 cassandra.yaml 文件并让我走上救赎之路?
7/19 添加了更多信息
我不认为这是 QUORUM vs ONE vs ALL 的问题。我设置的测试在列族的初始填充之后不执行对键空间的写入。因此,数据有足够的时间(小时)按照复制因子的要求发送到所有节点。此外,测试数据集非常小(2 个列族,每个族大约 300-1000 个值)。所以换句话说,数据是完全静态的。
我看到的行为似乎与 ec2 实例不再在网络上有关。我这样说的原因是因为如果我登录到一个节点并且只是执行一个操作,cassandra stop
我看不到数据丢失。但是,如果我重新启动或终止,我开始在堆栈跟踪中获取以下内容。
CassandraHostRetryService - Downed Host Retry service started with queue size -1 and retry delay 10s
CassandraHostRetryService - Downed Host retry shutdown complete
CassandraHostRetryService - Downed Host retry shutdown hook called
Caused by: TimedOutException()
Caused by: TimedOutException()
因此,这似乎更像是一个网络通信问题,因为集群在加入集群后期望(例如 10.0.12.74)在网络上。如果该 ip 由于重新启动或终止而突然无法访问,则超时开始发生。
当我nodetool status
在所有三种情况下(cassandra stop
、重新启动或终止)执行操作时,节点的状态显示为 DN。这是你所期望的。最终nodetool status
将返回联合国cassandra start
或重新启动,但显然终止始终保持 DN。
我的配置详情
以下是我的配置的一些细节(cassandra.yaml 在这篇文章的底部):
节点在 VPC 的私有子网中运行。
带有 num_tokens 的 Cassandra 1.2.5:256(虚拟节点)。initial_token:(空白)。我真的希望这能行得通,因为我们所有的节点都在自动缩放组中运行,所以重新分配可以动态处理的想法很有吸引力。
EC2 m1.large 每个可用区中的一个种子节点和一个非种子节点。(所以集群中有 6 个节点)。
临时存储,而不是 EBS。
具有 NetworkTopologyStrategy 和所有键空间的 Ec2Snitch 的复制因子为 3。
非种子节点是 auto_bootstraped,种子节点不是。
示例 cassandra.yaml 文件
cluster_name: 'TestCluster'
num_tokens: 256
initial_token:
hinted_handoff_enabled: true
max_hint_window_in_ms: 10800000
hinted_handoff_throttle_in_kb: 1024
max_hints_delivery_threads: 2
authenticator: org.apache.cassandra.auth.AllowAllAuthenticator
authorizer: org.apache.cassandra.auth.AllowAllAuthorizer
partitioner: org.apache.cassandra.dht.Murmur3Partitioner
disk_failure_policy: stop
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: /opt/company/dbserver/caches
commitlog_sync: periodic
commitlog_sync_period_in_ms: 10000
commitlog_segment_size_in_mb: 32
seed_provider:
- class_name: org.apache.cassandra.locator.SimpleSeedProvider
parameters:
- seeds: "SEED_IP_LIST"
flush_largest_memtables_at: 0.75
reduce_cache_sizes_at: 0.85
reduce_cache_capacity_to: 0.6
concurrent_reads: 32
concurrent_writes: 8
memtable_flush_queue_size: 4
trickle_fsync: false
trickle_fsync_interval_in_kb: 10240
storage_port: 7000
ssl_storage_port: 7001
listen_address: LISTEN_ADDRESS
start_native_transport: false
native_transport_port: 9042
start_rpc: true
rpc_address: 0.0.0.0
rpc_port: 9160
rpc_keepalive: true
rpc_server_type: sync
thrift_framed_transport_size_in_mb: 15
thrift_max_message_length_in_mb: 16
incremental_backups: true
snapshot_before_compaction: false
auto_bootstrap: AUTO_BOOTSTRAP
column_index_size_in_kb: 64
in_memory_compaction_limit_in_mb: 64
multithreaded_compaction: false
compaction_throughput_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: Ec2Snitch
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
index_interval: 128
server_encryption_options:
internode_encryption: none
keystore: conf/.keystore
keystore_password: cassandra
truststore: conf/.truststore
truststore_password: cassandra
client_encryption_options:
enabled: false
keystore: conf/.keystore
keystore_password: cassandra
internode_compression: all