一、简介
Cassandra是一个开源的列存储数据库,具有分布式,去中心化,灵活伸缩,高可用,错误容忍,可调的一致性。它的分布式结构基于Amazon的Dynamo,数据模型基于Google的bigtable.由facebook创建,现已捐献给Apache基金会。
性能
datastax的性能测试: [Apache Cassandra NoSQL Performance Benchmarks]
物理机建立了三个节点(机械硬盘)测试结果如下:
10w write/s, 5w read/s
cassandra-stress write n=10000000 -rate threads=64 -mode native cql3 user=cassandra password=cassandra -node ip1,ip2,ip3
cassandra-stress read n=10000000 -rate threads=64 -mode native cql3 user=cassandra password=cassandra -node ip1,ip2,ip3
二、适合的领域
- 大数据量(需要多节点部署)
- 大量的写、统计、分析
- 多数据中心
- 数据快速增长的应用
三、架构
3.1 Data Centers and Racks
- Rack
一个逻辑集合,有多个彼此临近node的组成。比如一个机架上的所有物理机器。
- Data Center
有多个Rack组成的逻辑集合。比如同一栋楼里互相连接的机器
3.2 Gossip and Failure Detection
Gossip是一种p2p协议,用于failure detection,跟踪其他节点的状态,每秒运行一次。
运用Phi Accrual Failure Detection
实现failure detection
计算出一个结果level of suspicion
,表示节点失败的可能性。
具有灵活性,同时也避免了传统heartbeat
的不可靠。应为可能只是短暂的网络拥塞,尤其是在公有云上。
3.3 Snitches
snitch定义了集群中每个节点相对其他节点的邻近度, 以此来确定从哪个节点读取和写入。
一般采用手动定义的模式,在cassandra.yaml
配置为endpoint_snitch: GossipingPropertyFileSnitch
同时在cassandra-rackdc.properties
配置当前节点的dc和rack,比如
dc=dc1
rack=rack2
3.4 Rings and Tokens
Cassandra表示由集群管理的数据作为一个环。环中的每个节点被分配一个或多个由token描述的数据范围,确定在环中的位置。token是用于标识每个分区的64位整数ID,范围是-2^63 -- 2^63-1
通过hash算法计算partition key
的hash值,以此确定存放在哪个节点
3.5 Virtual Nodes
早期cassandra版本给每个节点只分配了一个token范围,添加删除节点,需要手动重新配置token范围。一方面繁琐的操作,另一方面会导致大量的数据迁移。
在1.2版本介绍了virtual node
的概念简称vnode
,原先的token范围被缩减为多个更小的token范围。每个节点包含多个token范围。默认每个节点产生256个token范围(通过num_tokens调节),也就是256个vnode。在2.0以后默认开启。
在性能差的节点上,可以适当减少num_tokens的值org.apache.cassandra.dht.tokenallocator.ReplicationAwareTokenAllocator
用于计算节点的token范围
3.6 Partitioners
partitioners决定数据存放在哪个vnode上。它是一个hash函数,计算每行的partition key的hash值。
代码在org.apache.cassandra.dht
包里,目前主要用Murmur3Partitioner
DHT
即为distributed hash table
3.7 Replication Strategies
第一份复制存在对应的vnode中。其他复制的存放位置由replica strategy
(或叫replica placement strategy
)决定
主要有两种策略:
SimpleStrategy
将副本放置在环上的连续节点处,从分区器指示的节点开始。
NetworkTopologyStrategy
允许为每个数据中心指定不同的复制因子。在数据中心内,它将副本分配给不同的rack,以最大限度地提高可用性
3.8 Consistency Levels
根据CAP理论,一致性,可用性和分区容忍性不可兼得
cassandra通过设置读写时最少响应节点的数量,实现了可调的一致性。
可选的一致性级别:ANY, ONE, TWO,THREE, QUORUM, ALL
其中QUORUM,ALL是强一致性。
强一致性公式:R+W>N
R:读复制数, W:写复制数,N:复制因子
3.9 Queries and Coordinator Nodes
可以连接任一节点来执行读写操作
被连接的节点叫做Coordinator Nodes
,需要处理读写一致性。比如:写到多个节点,从多个节点读取
3.10 Memtables, SSTables, and Commit Log
当执行一个写操作时,数据被直接写到commit log
文件,并将设置commit log
中的dirty flag
为1。
然后将数据写到内存memtable
,每个memtable
对应一个表
当memtable
的大小达到一个限值后会被写入磁盘SSTable
,然后将commit log
中的dirty flag
设为0
2.1开始memtable
不在用jvm heap,而是 native memory
3.11 Caching
有三种cache
- key cache
缓存partiton keys到row index entries的映射,存在jvm heap
- row cache
缓存常用的row,存在off heap
- counter cache
提升counter性能,参见[Implementation of Counters]
3.12 Hinted Hando
一种写入高可用特性
当写入请求发给coordinator是,replica节点可能因为种种原因不可用(网络、硬件等),此时coordinator会临时保存写请求,等到replica节点重新上线时再写入。
默认保留两个小时
3.13 Lightweight Transactions and Paxos
check-and-set(insertIfNotExist)操作被称作linearizable consistency
通过Paxos来实现LWT,每个分区维持一个paxos状态
3.14 Tombstones
SStables文件是不可修改的。
删除数据被当做一个update,会被更新为tombstone。
在compact运行之前,它可以抑制原来的值。
设置中:Garbage Collection Grace Seconds
(GCGraceSeconds
),默认864,000,10天。
会清理超过这个时间的tombstones。
当节点不可用时间超过这个这个时间,会被替换
3.15 Bloom Filters
来源于发明家Burton Bloom
,是个快速的、非确定性算法,用于确定测试元素是否在集合中。以此降低不必要的磁盘读取。
可能得到一个false-positive
结果。
通过将数据集映射到bit array
上,一种特殊的缓存。
3.16 Compaction
SSTables是不可变的,通过compaction。重新生成一个新的SSTable文件(此文件中不包含不需要的数据,比如被删除的数据)
三种策略:
- SizeTieredCompactionStrategy (STCS)
默认的策略,写密集型
- LeveledCompactionStrategy (LCS)
读密集型
- DateTieredCompactionStrategy (DTCS)
用于基于时间或日期的数据
2.1开始还有anticompaction
特性,用于禁止compaction
3.17 Anti-Entropy, Repair, and Merkle Trees
cassandra使用Anti-Entropy
协议,这是一种用于修复复制集数据的gossip协议
有两种情况
- read repair
读取时发现有不是最新的数据。此时开始修复
- Anti-Entropy repair
通过nodetool手动运行修复
Merkle Trees
来源于Ralph Merkle
,也叫做hash tree
,是一种二叉树。每个父节点是它直接子节点的hash值
用于减少网络I/O
3.18 Staged Event-Driven Architecture (SEDA)
cassandra采用分阶段事件驱动架构,SEDA: An Architecture for Well-Conditioned, Scalable Internet Services
一个stage由事件队列
、事件处理器
和线程池
组成
controller
决定stage的调度和线程申请。主要代码在org.apache.cassandra.concurrent.StageManager
以下操作都是作为stage来执行的
- Read (local reads)
- Mutation (local writes)
- Gossip
- Request/response (interactions with other nodes)
- Anti-entropy (nodetool repair)
- Read repair
- Migration (making schema changes)
- Hinted handoff
3.19 System Keyspaces
- system_traces
-
system_schema
- keyspaces
- tables
- columns
存储kespace,table,column的定义
- materialized_views
存储可用的view
- functions
用户定义函数
- types
用户自定义类型
- triggers
每个表的触发配置
- aggregates
聚合定义
- system_auth
-
system
- local
- peers
存储节点信息 - available_ranges
- range_xfers
存储token范围 - materialized_ views_builds_in_progres
- built_materialized_views
跟踪view的构建 - paxos
存储paxos状态 - batchlog
存储 atomic batch操作的状态 - size_estimates
存储每个表的分区的估计数量,用于hadoop集成
四、集群配置
- cassandra.yaml
需要修改的
auto_bootstrap: false
cluster_name: 'Test Cluster'
authenticator: PasswordAuthenticator
authorizer: CassandraAuthorizer
seed_provider:
- class_name: org.apache.cassandra.locator.SimpleSeedProvider
parameters:
- seeds: "ip1,ip2" #至少两个,但不要全部节点都写上
listen_address: ip # 不要设置为0.0.0.0
rpc_address: 192.168.1.73 # 这个也会影响cql(9042)的监听
endpoint_snitch: GossipingPropertyFileSnitch