cassandra 靠谱资料1

Cassandra心得笔记

发表于 2013/01/09 juluren

这儿个月断断续续的在摸Cassandra,目前有一些小心得,先记录下来免的忘掉。不过…不确定这些Memo有没有错,如果有错以后再来改吧…:)

注:下列的Memo以1.x版为主,旧的0.8.x版资料多数已被我移除。部份内容来自于TWJUG里,某大湿的经验谈

(血泪控诉)

======================================================================

无法分类项目

  1. NoSQL = Not Only SQL
  2. Cassandra的数据操作与管理比GAE上的Datastore辛苦很多
  3. 官方目前在开发JDBC driver for CQL。如果这东东成熟的话,我觉的会比Hector API还好用。不过Hector API也会持续的把CQL功能给整合进来。

======================================================================

数据结构项目

  1. 我觉的最重要的儿个keyworld如下

    Row key = Key = K

    Column name = Name = N

    Column value = Value = V

  2. 储存的数据中,除了Row key会自动建Index之外,Column value不自动建立Index;但是可以利用Secondary Index机制自行建立Column value的index。
  3. 在Column Family建立时,由里面的comparator参数值决定了Column name的数据型别;由里面的validation_class参数值决定了Row key、Column value的数据型别。
  4. 储存数据的排序是依Row key、Column name自动排序,排序的规则跟Column family建立时配置的comparator有关联,不是依Column value自动排序!!!

======================================================================

数据建置与维护

  1. 一个Cassandra系统一般会设置多个Node,每个Node会各有一个识别用的UUID来识别彼此,此UUID在Cassandra中被称 为Token。多个Token(或说多个Node)的排列方式在逻辑上是一个环状的结构被称为Token ring。每个Token有各自的势力范围(e.g. row1~3可存放在token1,row4~6可存放在token2),这个范围被称为Partition。势力范围的判断逻辑由 Partitioner来决定(在cassandra.yaml里配置),常用的有RandomPartitioner、 ByteOrderedPartitioner二种;如果希望Row key要依序排序,要设成ByteOrderedPartitioner。这个条列项目的明细说明可参考这份文件
  2. 在Keyspace建立时,除了指定RF(ReplicationFactor:每笔数据要存放到儿个节点)之外,必需指定存放数据节点的选择策略。一般常用策略有SimpleStrategy、NetworkTopologyStrategy,不同策略会导致数据分布方式有所不同,详细说明可参 考这份文件
  3. 当系统有多个节点时,记的要遵守下面这规则,确保存放数据的一致性

    W(每次成功写入数据存放节点的次数) + R(每次成功读取数据存方节点的次数) > RF(ReplicationFactor:每笔数据要存放到儿个节点)

  4. 当系统有多个节点时,较佳的资料存取策略有下述三种
    • write all and read one
    • write one and read all
    • write quorum and read quorum

      (quorum公式 = RF/2 + 1)

  5. 系统节点数不同,用的数据存取策略不同,我自己会用的方式如下
    • 一个节点:用什么策略的效果都一样。

      (只一个节点的话,还会想用Cassnadra吗…=_=?)

    • 二个节点:RF设成2,资料存取策略用「write all and read one」。这样设的好处是数据读取较快,有一个节点挂了时,Cassandra还是可被读取;缺点是只要一个节点挂了,数据就无法写入了。
    • 三个节点(含以上): RF设成3(或3以上),数据存取策略可用「write all and read one」或是「write quorum and read quorum」。「write all and read one」的优缺在二个节点里有提及,不在多述。使用「write quorum and read quorum」的好处是在少量节点挂掉时,系统还是可以正常的被读写。等到挂掉的节点恢复后,系统提供的「hinted handoff」机制会把数据回写到挂掉的节点。 
  6. Cassandra在执行写入会比读取来的快,写入时会先直接写到RAM里面,然后再backend的把数据flush至硬盘。读取时则是先到RAM里存放的索引数据里找出索引,再依找到的索引到硬盘里把相关数据取出来。

    因为这特性,所以「write all and read one」存取策略对于少量写入但是海量读取的Application,有很大的优势。

  7. 系统中最少要配置一个node为seed node。seed node有整个token ring的相关信息,该node在启动时不会去找整个token ring的信息。反之,非 seed node则是启动时会去跟seed node查询整个token ring的数据。
  8. 当有新的node要加入现行的系统中时,必需修改cassandra.yaml。

    将auto_bootstrap设成true(1.0版跟之后的版本已经将auto_bootstrap参数移除,这参数变成系统内部参数,在启动时由系统自动判断是否要启用此功能),
    seeds参数里需配置目前所有seed node的IP值。

    auto_bootstrap 设成true时,该node在第一次被启动时会从seed node抓取整个token ring的配置,并把属于自己partition的数据从其它node里转入。这个配置只在第一次启动时生效,之后再次启动时就不再做 auto_bootstrap动作。当auto_bootstrap设成true,而该node自身又扮演seed node角色时,auto_bootstrap配置会失效。

  9. 系统的每个node在第一次启动时,如果不在cassandra.yaml里的initial_token参数配置token值,系统会自动指派该值。但 是对于一开始就建置多个node的系统而言,自动指派的值不见的合适,可能会造成token ring里,各自负责的partition大小差异很大(e.g. 建置4个node,但各自占有整个token ring的partition却是50%,25%,13%,12%)。要算出合适的token值可参考这篇文章。
  10. 系统的token值一旦第一次启动后就无法在cassandra.yaml中再次修改,因为相关数据已经进了system keyspace的LocationInfo column family,这时如果要改只能用nodetool下指令的方式来改。
  11. 系统中每个node所占的partition大小差异很大时,可利用"nodetool…move…

    "指令来移动token,进而解决partition差异过大的问题。

    "nodetool…move…

    "指令的动作原理是「先把该node退出token ring,并把该node的数据分到其它node里面」,接着「再将该node里旧token值换成新的token值,并重新加入token ring」,在完成后「再到其它node把属于新token该拥有的资料取回」。整个过程对效能有很大影响,在执行时要考虑执行时机。

  12. 在整个系统架构中,数据写入的流程是"写到Commitlog –> 写到Memtable –> 写到SSTable";数据读出流程是"先读RowCache–>再读Memtable–>最后读SSTable"。 (from TWJUG)
  13. 每个Node的Partitioner配置,建议设成RandomPartitioner,这样数据分布在整个Ring里会比较平均,不会特别集中在特定儿个Node。(from TWJUG)
  14. Replication Strategy在cassandra.yaml里的endpoint_snitch参数中配置,一般用预设的SimpleSnitch。如果有多个 DataCenter时,有其它对应的参数值可供设置。(from TWJUG)
  15. 整个Ring里各Node的资料要维持一致性,分成写与读的二方可面的策略。实务建议是write quorum and read quorum,不建议write all and read one的原因是只要有一个Node挂掉这时就只剩下read功能正常而已。(from TWJUG)
  16. Consistency Repair功能中,分成写与读二方面的机制。

    写入方面是靠Hinted Handoff来保证数据一定成功写到所属各个Node。实务上,Hinted Handoff可能会出包(1.0以前的版本会出包,官方声称这问题在1.0后已修正),因为Hinted Handoff在某些机会下,有可能会写入"它认为没挂掉但事实上已挂掉的Node",造成数据流失。

    读取方面是靠Read Repair机制来确保所属各个Node的数据正确无误。在某些状况下,Read的动作会导致先Write再Read的情况(e.g. 要从Node A,B,C取回同一份数据,执行时发现B的数据异常取不回来,这时Read Repair发生作用,把A或C取得的数据写回至B,等整个修复完成后才会把Client端要取回的资料回传)。(from TWJUG)

======================================================================

Client端操作

  1. 目前操作Cassandra最方便的方式依序是

    CQL > Cassandra CLI > Hector API > Thrift API

    基 本上,除了CQL看来比较像是给人用的之外,其它的都不怎么好用。CQL目前还在快速演进中,功能不完整但可以期待。写Java code来叫用cassandra的话,目前大概就只能选择Hector API。如果要直接在Console下Command操作,则是选择Cassandra CLI。 

  2. 利用Secondary Index机制进行数据查询时,记的where condition里的column field最少要包含一个"=",否则查询会出错。

======================================================================

前人血泪控诉留下的相关经验(这一段超重要)

  1. 不要在非官方(Oracle) JVM上建置Cassnadra系统。(from TWJUG)
  2. 每个Node里的CommitLog跟SSTable最好放在不同的Disk里面。 (from TWJUG)
  3. JVM里的heap size最好别超过16GB,不然可能会发生悲剧,系统在进行某些忙录的运作时,可能整个当在那边。(from TWJUG)
  4. Client端进行批次操作时,要注意每个批量的大小,每个批量过大可能会让Server端发生timeout的问题,导致一直进行retry的动作。(from TWJUG)
  5. cassandra.yaml的partitioner参数配置不要用ByteOrderedPartitioner、OrderPreservingPartitioner。(from TWJUG)
  6. cassandra.yaml的initial_token参数一定要设,不要让系统自动产生。系统产生的token会让整个Ring里,每个Partition的大小差异很大。(from TWJUG)
  7. SuperColumn未来会被CompositeColumn取代,不要再用SuperColumn了。(from TWJUG)
  8. Client端利用程序存取数据时,程序代码里建议先实做写的动作再实做读的动作,这样可避免Client端发生读到旧数据的问题。(from TWJUG)
  9. Cassandra虽然在1.x版后支持windows系统,但是为了自己生命安全,请不要用它,还是乖乖的架在linux上吧,免的问题一大堆。(from TWJUG)

你可能感兴趣的:(cassandra 靠谱资料1)