运维之道 version 0.1 淘宝 江枫

36
运运运运 version 0.1 淘淘 淘淘 http://www.NinGoo.net http://twitter.com/NinGoo

description

运维之道 version 0.1 淘宝 江枫 http://www.NinGoo.net http://twitter.com/NinGoo. Agenda. 基本概念 体系架构 参数配置 备份恢复 限制 监控 参考. 基本概念. Gossip Memtable / SSTable Compaction Commitlog Consistency level Hinted Handoff Anti Entropy Read Repair. Gossip. 去中心化,一致性 hash , P2P 协议 - PowerPoint PPT Presentation

Transcript of 运维之道 version 0.1 淘宝 江枫

Page 1: 运维之道 version 0.1 淘宝 江枫

运维之道version 0.1淘宝 江枫

http://www.NinGoo.nethttp://twitter.com/NinGoo

Page 2: 运维之道 version 0.1 淘宝 江枫

Agenda

• 基本概念• 体系架构• 参数配置• 备份恢复• 限制• 监控• 参考

Page 3: 运维之道 version 0.1 淘宝 江枫

基本概念• Gossip• Memtable/SSTable• Compaction• Commitlog• Consistency level• Hinted Handoff• Anti Entropy• Read Repair

Page 4: 运维之道 version 0.1 淘宝 江枫

Gossip

• 去中心化,一致性 hash , P2P 协议• Gossip 协议通过 endPointStateMap 的摘要 digest同步节点状态信息数据。一个节点自身的状态只能由自己修改,其他节点的状态只能通过同步更新。• Map 中每一个 EndpointStat 包括:– HeartbeatStat : Generation( 节点重启后递增 )/

Version Number– ApplicationStat :应用状态(每个对象标识一种状态) /Version Number

Page 5: 运维之道 version 0.1 淘宝 江枫

Gossip

• endPointStateMapEndPointState 10.0.0.1 HeartBeatState: generation 1259909635, version 325 ApplicationState "load-information": 5.2, generation 1259909635, version 45 ApplicationState "bootstrapping": bxLpassF3XD8Kyks, generation 1259909635, version 56 EndPointState 10.0.0.2 HeartBeatState: generation 1259911052, version 61 ApplicationState "load-information": 2.7, generation 1259911052, version 2 ApplicationState "bootstrapping": AujDMftpyUvebtnn, generation 1259911052, version 31

Gossip Digest for endpoint 10.0.0.2:10.0.0.2:1259911052:61 (IP:Generation:Max Version)一般情况下 HeartbeatState 中的 Version 都会是 endpointstat 中最大 Max Version ,但这不是一个“死规定”。

Page 6: 运维之道 version 0.1 淘宝 江枫

Gossip

Page 7: 运维之道 version 0.1 淘宝 江枫

Gossip每秒运行一次( Gossiper.java 的 start 方法),按照以下规则向其他节点发送同步消息:• 随机取一个当前活着的节点,并向它发送同步请求( doGossipToLiveMember )• 向随机一台不可达的机器发送同步请求( doGossipToUnreachableMember )• 如果第一步中所选择的节点不是 seed ,或者当前活着的节点数少于 seed 数,则向随意一台 seed 发送同步请求,以避免出现信息孤岛( doGossipToSeed )也就是说,一个节点发起一轮 Gossip ,最多请求三个节点。整个集群的信息达到同步的时间大概是 log(N) 。

Page 8: 运维之道 version 0.1 淘宝 江枫

Memtable/SSTable• 出自 Google Bigtable 设计的存储模型• 数据先写入内存中的 Memtable• 写入关键路径上不需要持有任何锁• Memtable 达到条件 ( 大小, key 的数量,时间间隔等 ) 后刷新到磁盘,保存为 SSTable• SSTable 不可修改• 同一个 CF 的多个 SSTable 可以合并 (Compaction) 以优化读操作• 通过布隆过滤算法 (Bloom Filter) 减少对不可能包含查询

key 的 SSTable 的读取。• 将随机写转变为顺序写,提升系统写性能。

Page 9: 运维之道 version 0.1 淘宝 江枫

Memtable/SSTable

• SSTable 包含对应的三种文件– Datafile按照 Key 排序顺序保存的数据文件– Indexfile保存每个 Key 在 Datafile 中的位置偏移– Filterfile保存 BloomFilter 的 Key 查找树

Page 10: 运维之道 version 0.1 淘宝 江枫

Compaction

• 一个 CF 可能有很多 SSTable ,系统会将多个 SSTable合并排序后保存为一个新的 SSTable ,称之为Compaction 。

• 超过 4 个 SSTable 后可能触发 Compaction 。• Major Comaction :合并 CF 的所有 SSTable 为一个新的 SSTable ,同时执行垃圾数据 ( 已标记删除的数据 tombstone) 清理。• Minor Compaction :只合并大小差不多的

SSTable 。• 可通过 nodetool compact 命令手动触发。

Page 11: 运维之道 version 0.1 淘宝 江枫

Commitlog• 数据写入 Memtable 前需要由 CommitLogExecutorService 线程先写 Commitlog• CommitlogHeader 记录了 CF 的脏标志位和该 CF 的恢复起始偏移位置。• CommitlogSegment 记录了变更的 RowMutation 信息。• Commitlog 刷新有两种机制:

– Batch :当 CommitlogSegment 刷新到磁盘后,插入 Memtable 操作才可继续。并且需要等待 CommitLogSyncBatchWindowInMS 毫秒内的其他写操作一起批量刷日志到磁盘。可以类比为 Oracle 的batch/wait 模式。

– Periodic :每隔 CommitLogSyncPeriodInMS 毫秒性刷新CommitlogSegment ,不阻塞数据写操作,可以类比为 Oracle 的batch/nowait 模式。

Page 12: 运维之道 version 0.1 淘宝 江枫

Commitlog

• SSTable 持久后不可变更,故 Commitlog 只用于Memtable 的恢复,相当于 Oracle 的 Instance Recovery 。 Cassandra 不需要做Media Recover

• 当节点异常重启后,将根据 SSTable 和 Commitlog进行实例恢复,在内存中重新恢复出宕机前的Memtable 。

• 当一个 Commitlog 文件对应的所有 CF 的 Memtable都刷新到磁盘后,该 Commitlog 就不再需要,系统会自动清除。

Page 13: 运维之道 version 0.1 淘宝 江枫

ConsistencyLevel• Write

Level Behavior

ZEROEnsure nothing. A write happens asynchronously in background. Until CASSANDRA-685 is fixed: If too many of these queue up, buffers will explode and bad things will happen.

ANY (Requires 0.6) Ensure that the write has been written to at least 1 node, including hinted recipients.

ONE Ensure that the write has been written to at least 1 node's commit log and memory table before responding to the client.

QUORUM Ensure that the write has been written to <ReplicationFactor> / 2 + 1 nodes before responding to the client.

ALL Ensure that the write is written to all <ReplicationFactor> nodes before responding to the client. Any unresponsive nodes will fail the operation.

Page 14: 运维之道 version 0.1 淘宝 江枫

ConsistencyLevel• ReadLevel Behavior

ONE

Will return the record returned by the first node to respond. A consistency check is always done in a background thread to fix any consistency issues when ConsistencyLevel.ONE is used. This means subsequent calls will have correct data even if the initial read gets an older value. (This is called read repair.)

QUORUMWill query all nodes and return the record with the most recent timestamp once it has at least a majority of replicas reported. Again, the remaining replicas will be checked in the background.

ALLWill query all nodes and return the record with the most recent timestamp once all nodes have replied. Any unresponsive nodes will fail the operation.

Page 15: 运维之道 version 0.1 淘宝 江枫

Hinted Handoff• Key A 按照规则首要写入节点为 N1 ,复制到 N2• 假如 N1宕机,如果写入 N2 能满足 ConsistencyLevel 要求,则 Key A 对应的 RowMutation 将封装一个带 hint 信息的头部(包含了目标为 N1 的信息),然后随机写入一个节点

N3 ,此副本不可读。同时正常复制一份数据到 N2 ,此副本可以提供读。如果写 N2 不满足写一致性要求,则写会失败。• N1 恢复后,原本应该写入 N1 的带 hint头的信息将重新写回 N1 。• HintedHandoff 是实现最终一致性的一个优化措施,可以减少最终一致的时间窗口。

Page 16: 运维之道 version 0.1 淘宝 江枫

Anti Entropy• 数据的最终一致性由 AntiEntropy (逆熵)所生成的

MerkleTrees 对比来发现数据复制的不一致,通过org.apache.cassandra.streaming来进行完整的一致性修复。该动作可以由 Nodetool 触发,也可以由系统自动触发。

• Merkle Tree 是一种 Hash Tree ,叶子节点是 Key 的 hash值,父节点是所有子节点值的 hash值,通过判断父节点的异同可以知道所有子节点的异同。• 通过判断 root 的异同可以快速判断所有叶子节点数据的异同。

Page 17: 运维之道 version 0.1 淘宝 江枫

Read Repair• 读取 Key A 的数据时,系统会读取 Key A 的所有数据副本,如果发现有不一致,则进行一致性修复。• 如果读一致性要求为 ONE ,会立即返回离客户端最近的一份数据副本。然后会在后台执行 Read Repair 。这意味着第一次读取到的数据可能不是最新的数据。• 如果读一致性要求为 QUORUM ,则会在读取超过半数的一致性的副本后返回一份副本给客户端,剩余节点的一致性检查和修复则在后台执行。• 如果读一致性要求高 (ALL) ,则只有 Read Repair完成后才能返回一致性的一份数据副本给客户端。• 该机制有利于减少最终一致的时间窗口。

Page 18: 运维之道 version 0.1 淘宝 江枫

体系架构• 数据分布• 数据复制• 接口

Page 19: 运维之道 version 0.1 淘宝 江枫

数据分布• RandomPartitioner基于 MD5 的随机 Hash分布。 MD5 的 hash空间为 2^127-1 ,每个节点的 InitialToken 可以按节点数量 N进行平均分配,如第 i 个节点可以设置为

i*(2^127-1)/N• OrderPreservingPartitioner基于 Key值 (UTF-8) 的范围分布• CollatingOrderPreservingPartitioner基于 Key值 ( 不同语言环境排序 ) 的范围分布

Page 20: 运维之道 version 0.1 淘宝 江枫

数据复制• DatacenterShardStategy如果 replication factor 为 N ,则 (N-1)%2 的副本复制到不同数据中心。所有副本在两个数据中心均衡分布• RackAwareStrategy一个副本复制到不同数据中心,其他副本复制到同数据中心的不同机架。异地机房只保有一个副本,主要用于容灾• RackUnAwareStrategy不考虑复制节点的物理位置,一般是 hash环右边的

N-1 个节点

Page 21: 运维之道 version 0.1 淘宝 江枫

接口• 两种编程接口– Thrift2007年由 Facebook开源给 Apache ,目前发展缓慢。需要生成不同语言的接口代码– AvroHadoop 的一个子项, Cassandra正在往这个接口进行迁移。这是一个动态序列化库,无须生成静态接口代码类似接口的还有 Google 的 Protocol Buffer

Page 22: 运维之道 version 0.1 淘宝 江枫

参数配置• 主要配置文件 storage-conf.xml

– ClusterName :集群名,所有节点统一– AutoBootstrap :作为新节点加入集群时,设置 true开始初始化– HintedHandoffEnabled :启用 Hinted Handoff特性– Keyspaces: 数据模型相关 keyspace 和 column family 设置– ReplicaPlacementStrategy: 数据副本复制策略(基于数据中心分布 / 机架分布)– ReplicationFactor: 数据副本复制份数,一般建议设置为 3 份– EndPointSnitch: 集群节点对应物理机器分布策略,据此路由不同的数据副本。– Partitioner: 数据分布策略。随机分布 or 有序分布– InitialToken: 初始化 Token ,具体 key 的第一份副本分布到哪个节点

Page 23: 运维之道 version 0.1 淘宝 江枫

参数配置• 主要配置文件 storage-conf.xml

– CommitLogDirectory: Commitlog 文件存放路径– DataFileDirectory : 数据文件存放路径,可以指定多个路径– Seeds: 种子节点列表,当初始化完成后可以设置为种子节点,新节点加入集群时,需要从种子节点获取需要的信息。– RpcTimeoutInMillis: 等待远程节点返回消息的超时设置– CommitLogRotationThresholdInMB: commitlog 文件大小,超过则进行切换– ListenAddress/ StoragePort: 集群内部通讯监听 IP 和端口– ThriftAddress/ ThriftPort: Thrift 监听 IP 和端口,用于响应客户端请求– DiskAccessMode: 磁盘访问模式。 64 位系统建议设置为 mmap ,或者

auto(64 位时等效于 mmap)– RowWarningThresholdInMB: 对超长的压缩行进行告警。如果压缩行不能完全放入内存中, Cassandra 会崩溃,所以需要根据内存设置告警阀值。

Page 24: 运维之道 version 0.1 淘宝 江枫

参数配置• 主要配置文件 conf/storage-conf.xml

– SlicedBufferSizeInKB: 读取连续列的缓存大小– FlushDataBufferSizeInMB: 刷新 Memtable 到磁盘数据文件的缓存大小– FlushIndexBufferSizeInMB: 刷新 Memtable 到磁盘索引文件的缓存大小– ColumnIndexSizeInKB: 当一行长度超过该值时,添加一个列偏移索引– MemtableThroughputInMB: Memtable 大小– MemtableFlushAfterMinutes: N分钟后强制刷新 Memtable 到磁盘– ConcurrentReads: 并发读请求,建议设置为 CPU核数的两倍– ConcurrentWrites: Cassandra 写性能更好,因此并发写请求可以设置更高,例如 CPU核数的 8倍– CommitLogSync: Commitlog 刷新到磁盘的方式, batch or periodic– GCGraceSeconds: 清理带有删除标记的垃圾数据的间隔时间。如果节点宕机时间超过这个间隔,则节点会永久失效,只能重新进行初始化后才能加入到集群。默认为 10天。

Page 25: 运维之道 version 0.1 淘宝 江枫

参数配置• 日志配置文件 conf/log4j.properties

– log4j.appender.R.File=/var/log/cassandra/system.log 日志文件位置– log4j.appender.file.maxFileSize=20MB 日志文件大小

Page 26: 运维之道 version 0.1 淘宝 江枫

参数配置• jvm 配置 bin/ cassandra.in.sh

JVM_OPTS=" \ -ea \ -Xms256M \ -Xmx1G \ -XX:+UseParNewGC \ -XX:+UseConcMarkSweepGC \ -XX:+CMSParallelRemarkEnabled \ -XX:SurvivorRatio=8 \ -XX:MaxTenuringThreshold=1 \ -XX:+HeapDumpOnOutOfMemoryError \ -Dcom.sun.management.jmxremote.port=8080 \ -Dcom.sun.management.jmxremote.ssl=false \ -Dcom.sun.management.jmxremote.authenticate=false"

Page 27: 运维之道 version 0.1 淘宝 江枫

备份恢复• Snapshot

–利用 nodetool 的 snapshot 命令可以生成 SSTable 的一个快照。–在生成 snapshot 前,先会执行一次 Memtable切换,将最新的数据保存为 SSTable 。–复制 snapshot即可对节点的数据进行物理备份。– Snapshot实际上是 SSTable 文件的一个 Hard link 。

Page 28: 运维之道 version 0.1 淘宝 江枫

备份恢复• Export/Import通过 sstable2json 可以将数据导出为 json格式的文件,相当于逻辑备份。通过 json2sstable 则可以将 json格式的文件导入为 SSTable 。

Page 29: 运维之道 version 0.1 淘宝 江枫

限制• Keyspace/CF无法动态增删, 0.7 以后的版本有计划支持动态增删。• 由于 Compaction 时对整行数据反序列化,所以一行数据必须要能够全部存放进内存中。

https://issues.apache.org/jira/browse/CASSANDRA-16 • 一行数据的长度不能超过 2^31-1字节,因为行数据序列化时用一个整数表示其长度同时序列化到磁盘中。• Super columnfamilies 中的 sub column没有索引,因此在反序列化一个 sub column 时需要反序列化 super column 中的所有 sub column 。 因此需要避免设计使用大量的 sub

column 。 https://issues.apache.org/jira/browse/CASSANDRA-598

Page 30: 运维之道 version 0.1 淘宝 江枫

限制• Thrift 不支持流( streaming) ,读写请求的数据都需要存放在内存中,因此大对象可能需要切分后存取。

http://issues.apache.org/jira/browse/CASSANDRA-265 • Thrift端口收到非协议标准的随机数据可能导致 Cassandra崩溃。因此对 Thrift 的探测如 telnet 等操作可能导致节点挂掉 http://issues.apache.org/jira/browse/CASSANDRA-475

http://issues.apache.org/jira/browse/THRIFT-601

Page 31: 运维之道 version 0.1 淘宝 江枫

监控• Nodetoolnodetool –h localhost –p 8080 tpstats

Page 32: 运维之道 version 0.1 淘宝 江枫

监控• Nodetoolnodetool –h localhost –p 8080 cfstats

Page 33: 运维之道 version 0.1 淘宝 江枫

监控• jconsole jmx地址: service:jmx:rmi:///jndi/rmi://localhost:8080/jmxrmi

Page 34: 运维之道 version 0.1 淘宝 江枫

监控• Nagioshttp://www.mahalo.com/how-to-monitor-cassandra-with-nagios

Page 35: 运维之道 version 0.1 淘宝 江枫

监控• Cassandra web consolehttp://github.com/suguru/cassandra-webconsole/downloads

Page 36: 运维之道 version 0.1 淘宝 江枫

参考• http://wiki.apache.org/cassandra• http://io.typepad.com/glossary.html • http://spyced.blogspot.com/• http://perspectives.mvdirona.com/2009/02/07/FacebookCassandraAr

chitectureAndDesign.aspx• http://nosql.mypopescu.com/tagged/cassandra• http://www.cs.cornell.edu/home/rvr/papers/flowgossip.pdf • http://www.ruohai.org/?p=13• http://www.ningoo.net/html/2010/cassandra_token.html • http://www.dbthink.com/?tag=cassandra• http://java.sun.com/developer/technicalArticles/J2SE/jconsole.html• http://cassandra.apache.org/

*部分链接需要翻墙访问