更新说明:

本文编写时最新的Cassandra版本为2.2,最新的稳定版本为2.1.8

2016年6月23日,增加一篇译文,当下最新版本为3.7

最新的Cassandra 2.1 或者更高的版本支持3种压缩策略,各有优劣,在2.2的版本的说明文档中,有对这三种策略的详细说明,部分翻译如下。

文档链接:http://docs.datastax.com/en/cassandra/2.2/cassandra/dml/dmlHowDataMaintain.html?scroll=dmlHowDataWritten_unique_2__types-compaction

[TCS]

SizeTieredCompactionStrategy (STCS)

  • 推荐在写密集负载中使用
  • 优势:在写密集的负载中工作良好
  • 劣势:可能把旧数据数据保持太久。随着时间的推移,需要的内存数量不断增长。

实际使用中如果内存不是很充裕,容易因为SSTable合并过程占用过多内存,导致内存不足,其他节点的Message无法和当前节点交换,最终导致节点宕机。我们可能在cassandra-env.sh中配置了一些参数控制内存的使用,但是并不能限制数据压缩的时候产生的内存损耗。多数建议是关闭自动SSTable压缩,改用手动在空闲期间进行压缩。

压缩过程

当有(默认4个)SSTable的大小相似的时候,STCS便会启动。压缩过程将这些SSTable合并成一个大的SSTable。当大的SSTable积累了足够数量,同样的过程会再次发生,组合成更大的SSTable。在任何时候,一些不同大小的SSTable的存在都是暂时的。这种策略在写密集的负载中工作良好,当需要读数据的时候,需要尝试读取多个SSTable来找到一行中的所有的数据。策略无法保证同一行的数据被限制在一小部分的sstable中。同时可以预测删除的数据是不均匀的,因为SSTable的大小是触发压缩的条件,并且SSTable可能增长的不够快以便合并旧的数据。当最大的那些SSTable达到一定大小,合并需要的内存也会增长为同时容纳新的SSTable+ 旧的SStable,可能会超出一个典型节点的内存总量。

LeveledCompactionStrategy (LCS)

  • 推荐在读密集负载中使用
  • 优势:内存的需求容易预测。读操作的延迟可以预计。旧数据更快的被驱逐。
  • 劣势:更高的io消耗可能引起操作延时。

实际上一般是又读又写,我觉得多数常见web应用可以用这个压缩方式。

LCS意在解决一些STCS在读操作上的一些问题。当SSTable的体积增长到一个不大的体积(默认5MB),它被写入第0级,L0,并且马上和第一级合并,L1。 在每个从L1开始的级别, 单个级别中所有的SSTable都确保没有重复数据。因为没有数据重复,LCS有时候会分割SSTable,就像合并他们时候一样,以确保文件大小相同。每个级别都是上一个级别大小的10倍, 所以L1 将会是 L0 大小的10倍,而L2则是L0的100倍。当L1被填满时L2就会开始被填入。由于每个级别没有重复数据,所以一个读操作可以在查找少数SSTable的情况下高效的完成。在许多读操作中,最多需要读取1~2个SSTable。事实上,90%的读只需要读取1个SSTable。最差的情况下是每个级别读取一个SSTable(由于每个SSTable增长10倍体积,所以Level不会很多)。使用这个策略进行压缩时候,需要的内存并不多,需要SSTable的10倍大小(50MB?)。过时的数据将会更快的被驱逐, 所以删除的数据只会占据SSTable很小的一部分。 不过,LCS的压缩方式出发的更频繁,占据节点上更多的I/O。 在写密集的的负载环境中,使用这种策略的收益不足以弥补I/O操作带来的性能损失。在Cassandra 2.2 或者更高的版本中,当启动一台新的LCS节点时候,旁路压缩操作的优化已经被实施。原始数据被直接移动到正确的级别,因为之前没有任何数据。performance improvements have been implemented that bypass compaction operations when bootstrapping a new node using LCS into a cluster. The original data is directly moved to the correct level because there is no existing data, so no partition overlap per level is present. For more information, see Apache Cassandra 2.2 - Bootstrapping Performance Improvements for Leveled Compaction.

有关LCS的更多介绍:http://www.datastax.com/dev/blog/leveled-compaction-in-apache-cassandra

DateTieredCompactionStrategy (DTCS)

  • Cassandra 2.0以后的版本才支持这个压缩方式
  • 推荐使用在时间序列和需要生存时间管理的负载环境
  • 优势:专为时间序列设计
  • 劣势:非顺序插入的数据会导致错误。在DTCS的情况下,读修复必须关闭

DTCS和STCS很像,但是它不是基于SSTable的大小进行压缩的,DTCS通过判断SSTable的年龄(创建时间)进行压缩。可配置的时间窗口确保新旧数据不会被混淆的合并到同一个SSTable。事实上,使用TTL时间戳,DTCS经常将包含过期数据的整个SSTable逐出。如果时间序列的输出是稳定的,这个策略也会导致许多大小相似的SSTable。通过配置时间周期,SSTable会在一个确切的时间进行合并。如果一些SSTable 正好落在相同的时间区间内,SSTable仍然会合并为更大的table,就像STCS一样。另外,如果SSTable达到了配置的年龄将不会进行压缩,减少数据重复写入的次数。使用这种策略压缩的SSTable可以高效的读取"last hour's worth of data",非常快。有个问题就是这种策略导致过期数据不容易写入,比如一条记录要写入过期的时间。读修复容易导致插入过期数据,所以需要关闭读取修复。

For more information about compaction strategies, see When to Use Leveled Compaction and Leveled Compaction in Apache Cassandra. For DateTieredCompactionStrategy, see Date-Tiered Compaction in Cassandra or DateTieredCompactionStrategy: Compaction for Time Series Data.

更多关于DTCS http://www.datastax.com/dev/blog/datetieredcompactionstrategy

DTCS 的测试 http://jimplush.com/talk/2015/02/03/cassandras-datetieredcompaction-strategy-works-as-billed/

译一篇有关DTCS的问题的的文章

作者开发了TWCS以规避DTCS的部分问题,但是并没有全部被官方认同,不过正好帮助我认识DTCS的局限性

https://issues.apache.org/jira/browse/CASSANDRA-9666

DTCS 非常适合时序数据,但它的注意事项,使其难以在生产中的应用(一些典型的操作:bootstrap,removenode,repair 在max_sstable_age_days后不再合并,hints/read repair破坏了选择算法)(译:不知道指的是什么选择算法)。

我提出一种替代方案,TimeWindowCompactionStrategy,它牺牲了DTCS的分层特性来弥补DTCS在操作上的一些缺陷。我相信有必要提出一种替代方案而不是调整DTCS,因为他基本上移除了分层特性以便移除max_sstable_age_days - 结果有很大不同,即使大量的参考了DTCS。

特别的,比起为增长的体积创建许多窗口(译注:一个时间段),这个策略允许选择窗口的大小,使用STCS压缩第一个窗口,在这个窗口不是当前窗口的情况下,进一步将数据向下压缩成一个SSTABLE。窗口的大小是一个混合的单位(分钟,小时,天)和大小。这样操作者可以认为所有的在窗口中的数据都压缩在一起(比如你有个一个6小时的窗口,你每天会有4个sstable,每个SSTABLE 保存了大约6小时数据)

这个结果解决了许多DTCS的问题:

  1. 目前,DTCS的第一个窗口是按照一个选定的规则压缩的,偏爱创建时间更早的文件,但是忽略体积。在TWCS(原文作者自己编写的一个策略)中,第一个窗口数据将由更加成熟、快速的压缩方案STCS。所有的的STCS选项都可以用于TWCS配置第一个窗口的压缩行为。

HintedHandoff 可能导致旧数据被放到新的sstable,会导致轻微的性能损失(sstable将会覆盖一个很大的范围,但是旧的时间戳不会在压缩的时候影响sstable的选择标准)

ReadRepair 可能导致旧数据被放到新的sstable,会导致轻微的性能损失(sstable将会覆盖一个很大的范围,但是旧的时间戳不会在压缩的时候影响sstable的选择标准)

Small, old sstables resulting from streams of any kind will be swiftly and aggressively compacted with the other sstables matching their similar maxTimestamp, without causing sstables in neighboring windows to grow in size.

The configuration options are explicit and straightforward - the tuning parameters leave little room for error. The window is set in common, easily understandable terms such as “12 hours”, “1 Day”, “30 days”. The minute/hour/day options are granular enough for users keeping data for hours, and users keeping data for years.

There is no explicitly configurable max sstable age, though sstables will naturally stop compacting once new data is written in that window.

Streaming operations can create sstables with old timestamps, and they'll naturally be joined together with sstables in the same time bucket. This is true for bootstrap/repair/sstableloader/removenode.

It remains true that if old data and new data is written into the memtable at the same time, the resulting sstables will be treated as if they were new sstables, however, that no longer negatively impacts the compaction strategy’s selection criteria for older windows.

如何修改压缩策略

创建的时候:

    CREATE TABLE use_view  (
uid bigint PRIMARY KEY,
ids map<int, int>
) WITH compaction = { 'class': 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy'}

修改某个表的压缩策略:

    alter table use_view WITH compaction = { 'class': 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy'}

Cassandra 的压缩策略STCS,LCS 和 DTCS的更多相关文章

  1. 小程序代码包压缩 策略&方案

    微信小程序自推出以来,逐渐发展,目前正受到越来越多的青睐.其中很重要的一点得益于小程序的轻量级特性,每个小程序最多不超过2MB,招之即来挥之即去,相比于几十上百兆的APP,用户进入小程序,或者说,小程 ...

  2. Cassandra 有限分页策略

    瀑布式分页 如果你的应用只需要瀑布式的分页,那么,Cassandra可以很好的支持,不过记得要指定好排序顺序. CLUSTERING ORDER BY (add_time DESC); 常见的分页,跳 ...

  3. Android面试收集录15 Android Bitmap压缩策略

    一.为什么Bitmap需要高效加载? 现在的高清大图,动辄就要好几M,而Android对单个应用所施加的内存限制,只有小几十M,如16M,这导致加载Bitmap的时候很容易出现内存溢出.如下异常信息, ...

  4. 【原/转】ios指令集以及基于指令集的app包压缩策略

    iPhone指令集   本文所讲的内容都是围绕iPhone的CPU指令集(想了解ARM指令集的同学请点击这里),现在先说说不同型号的iPhone都使用的是什么指令集: ARMv8/ARM64 = iP ...

  5. 【翻译】驯服野兽:Scylla 如何利用控制理论来控制压实

    教程翻译自Seastar官方文档:https://www.scylladb.com/2018/06/12/scylla-leverages-control-theory/ 转载请注明出处:https: ...

  6. [译]Cassandra的数据读写与压缩

    本文翻译主要来自Datastax的cassandra1.2文档.http://www.datastax.com/documentation/cassandra/1.2/index.html.此外还有一 ...

  7. HBase 的MOB压缩分区策略介绍

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/zNZQhb07Nr/article/details/79832392 HBase应用场景很广泛.社区 ...

  8. cassandra 3.x官方文档(7)---内部原理之如何读写数据

    写在前面 cassandra3.x官方文档的非官方翻译.翻译内容水平全依赖本人英文水平和对cassandra的理解.所以强烈建议阅读英文版cassandra 3.x 官方文档.此文档一半是翻译,一半是 ...

  9. Cassandra基础2

    ========================================================= gossip协议1.点对点(peer to perr)的网络通信协议,节点间地位相同 ...

随机推荐

  1. java异常分类(运行时异常,可检查异常)

    NullPointerException:是运行时异常(RuntimeException),也叫非检查异常 所以我们抛出该类异常实例时,方法声明处无需添加throws来列举该类异常的抛出,编译器在编译 ...

  2. 【LOB】使用USER_LOBS视图获得当前用户包含LOB字段的表

    包含LOB类型字段的表往往需要特殊关照,如何快速的获得包含LOB对象的数据库表?使用DBA_LOBS.ALL_LOBS和USER_LOBS视图可以很方便地获得包含BLOB或CLOB字段的表. 简单看一 ...

  3. css margin-top设置html元素之间的距离

    css margin-top属性设置的是一个元素的顶端与另一个元素之间的距离.这个距离称为上外边距,本文章向大家介绍css margin-top属性的用法和实例,需要的朋友可以参考一下. css ma ...

  4. struts2页面上如何操作字符串

    <s:if test="prodName.length()>15"><s:property value='prodName.substring(0,15)' ...

  5. linux包转发开发

    28号晚上接到这个任务的, 看了点epoll, 29号上午安装Ubuntu 12.10的G++, 开始把内网的vm虚拟机文件, 复制到外网, 重新建立一个虚拟机再更新, 最后外网也没能安装得了g++. ...

  6. [ CodeVS冲杯之路 ] P1368

    不充钱,你怎么AC? 题目:http://codevs.cn/problem/1368/ 嗯……泡泡堂,很劲啊,其实就是个盗版的田忌赛马 http://www.cnblogs.com/hyfer/p/ ...

  7. Django中级篇之模板语言

    模板 一.引用变量 模版的创建过程,对于模版,其实就是读取模版(其中嵌套着模版标签),然后将 Model 中获取的数据插入到模版中,最后将信息返回给用户. {{ xxx }} 二.标签 用{%  %} ...

  8. c#中using System.Runtime.Serialization.Json;不能引用

    原因:生成项目对于的.net版本是2.0的.需要手动切换成4.0 操作步骤:右键项目,属性页面,下拉框选择最高版本.net 截图:

  9. mysql数据导入

    1.windows解压 2.修改文件名,例如a.txt 3.rz 导入到 linux \data\pcode sudo su -cd /data/pcode/rm -rf *.txt 4.合并到一个文 ...

  10. linux使用flock文件锁解决crontab冲突问题

    * * * * * flock -xn /dev/shm/redis.lock -c "/usr/local/bin/redis-server" 可以用flock命令,配合使用rs ...