[翻译]关于Cassandra中的删除和墓碑(二)

分布式删除的难题 考虑上面的情况,强一致性是必须的,让我们暂且忘掉墓碑这个东西,假设cassandra删除数据不使用墓碑。如果一次删除操作在一个节点上失败了(总共3个节点,副本为3, RF=3).整个删除操作仍然被认为成功的(因为有两个节点应答成功,使用CL.QUORUM一致性)。接下来如果读发生在该节点上就会变的不明确,因为结果返回是空,还是返回数据,没有办法确定哪一种是正确的。Cassandra总是任务返回数据是对的,那就会发生删除的数据又出现了的事情,这些数据可以叫"僵尸"或者"鬼",并且他们的表现是不可预见的 注意:这个问题没有完全解决,即便使用了墓碑,所以假设你的集群有删除操作的话我们还要有如下操作: Cassandra运维人员必须在每个gc_grace_seconds周期内对整个集群进行repair操作。 从一个Cassandra节点的视角看待删除 Cassandra使用一旦写入就不再改变的文件来存储数据,像前面描述,墓碑的目的就是为了解决从这样的系统中删除数据的困难的。 Cassanda的一个特种就是使用了一种日志结构合并树(LSM tree),然而大多数关系型数据库(RDBMS)是使用的B树(B-tree)。这样说你可能更容易理解:记住Cassandra写的时候总是往后追加数据,读的时候才会综合这些写入片段,选择每列的最大版本号去返回。 LSM Trees还有一个属性是数据写入文件中就不可以更改(这些文件在Cassandra中叫做SSTables)。正如最初讨论的那样,显然对于这样一个系统,删除只能通过一种特殊的写来实现。读的时候根据墓碑的时间戳,忽略小于这个时间戳之前插入的数据。

2017年3月20日 · 1 分钟

[翻译]关于Cassandra中的删除和墓碑(一)

从像apache cassandra这样的系统中,删除分布式主从复制的数据远比关系型数据库要复杂的多。当我们想到cassandra的数据是存在磁盘上的多个文件中,这个删除的过程变的超级有趣。在这样一个系统中,需要写入一个被称作墓碑(tombstone)的标记,用于记录一个删除操作,表示之前的值被删掉了。尽管你可能觉得这很不正常,或者难以理解(特别是当你意识到删除操作竟然是要占空间存储的),我们将用这篇博客,使用一些例子来解释这其中究竟发生了什么。 Cassandra:可用性和一致性的考虑 在我们深入细节之前,我们需要快速回顾一下Cassandra作为一个分布式系统是怎么工作的,特别是关于可用性和一致性。这对于我们等会解释分布式删除,以及一些潜在问题,非常有必要。 可用性:为了保证Cassandra可以复制数据,也就是说根据副本因子,存储的每一条数据都有多份拷贝。副本因子定义了每个keyspace(库的概念)在每个DC(数据中心)中的拷贝个数。通过配置,每个拷贝可以分布在不同的机架上,只要你有足够的机架,并且通过配置机架策略让系统考虑这些因素。有了这个,当任何一个节点(或者是一个机架,再说一遍,这个取决于你是否进行了配置)挂了,数据仍然可以通过其它副本进行读取。 一致性:为了确保读取数据的强一致性,我们必须遵循下面的原则: CL.READ = 读一致性. 从至少多个节点得到读响应,我们才承认它是一个成功的操作. CL.WRITE = 写一致性,同上. RF = 副本因子(个数) 要满足 CL.READ + CL.WRITE > RF,只有这样,我们才能保证至少有一个写入数据的节点被读到(译者注:好有道理) 通常的例子:我们考虑下面的设置: RF = 3 CL.READ = QUORUM = RF/2 + 1 = 2 CL.WRITE = QUORUM = RF/2 + 1 = 2 CL.READ + CL.WRITE > RF –> 4 > 3 这样的配置,就有很高的可用性,没有单点故障(SPOF),我们可以承担挂掉一个机器的风险,因为我们可以保证有一个写数据的节点可以读到,再加上最新者写入者胜出(LWW)算法(译者注:记录以写入时间戳最新的为准),就可以知道哪个节点的数据是正确的。 先把这种配置和做法记在脑子里,我们看一些执行删除的例子。

2017年3月18日 · 1 分钟

[翻译]Cassandra经常被问到的问题(三)

14、是不是单个seed意味着单点故障? 即便没有seed节点,集群也可以运行和重启,但是不能再往集群里增加节点。还是推荐在生产系统中配置多个种子节点。 15、为什么不可以在jconsole里调用某个jmx方法呢? 一些JMX操作的参数是个数组,而Jconsole并不支持数组型参数。对于那些不能用jconsole调用的操作(在jconsole里点击按钮无效)。有需要自己写一个JMX客户端去调用,或者使用一个支持数组的jmx监控工具。 16、为什么我会在日志文件里看到 “… messages dropped …“这样的信息? 这是cassandra在面对超出自己处理能力的请求时,为了保护自己做出的流控措施。 一个节点接收到其它节点发送过来的消息,但是在他们合适的超时时间内不能得到处理(具体参考 read_request_timeout, write_request_timeout等配置项)。就会被丢弃,而不是处理(因为接受用户请求的节点也就是协调节点不会再等这个响应返回) 对于写,这意味着它的请求不会被写入所有的副本,这个一致性将会被读修复、hints或者是人工修复等方式修复。因为这,一个写操作返回给客户端的结果就是超时的。 对于读,意味着一个读请求可能没有完成。负载流控是cassandra架构的一部分,如果这个问题一直持续下去,这标志着你的节点或者集群已经超载了。 17、Cassandra因为java.lang.OutOfMemoryError: Map failed挂掉了 如果cassandra挂掉的时候输出“Map failed”的消息,表示操作系统不允许java锁定更多的内存。在linux里,内存锁定是有限制的,你可以通过/proc//limits确认,并提高它(比如适应ulimit命令)。还有vm.max_map_cout参数。注意debian安装包会自动为你调整这些参数。 18、如果再同一时刻发生两次更新会发生什么? 更新顺序必须是可交换的,因为他们很有可能到达不同副本的顺序是不一样的。只要cassandra有一个确定的方法选出这个赢家(相同的时间戳),那么这在其它节点也是一样的,这是一个重要的实现细节。也就是说,对于相同时间戳的操作,Cassandra遵循以下两个原则:第一:删除要优先于更新和插入,第二:如果两个都是更新,那个在语法上比较大的更新会被选中。 19、为什么在加入一个新节点的时候,会有Stream failed错误? 两个可能性: GC可能导致的长时间暂停可能会扰乱传输进程 在后台执行的压缩会导致传输时间太长从而TCP连接断开。 对于第一种情况,建议在应用中经常的进行GC优化, 第二种情况,你需要设置系统的TCP keepalive参数短一些(linux中默认是很长的),尝试执行下面的语句: sudo /sbin/sysctl -w net.ipv4.tcp_keepalive_time=60 net.ipv4.tcp_keepalive_intvl=60 net.ipv4.tcp_keepalive_probes=5 如果要让这些配置永久有效,需要把他们加入到/etc/sysctl.conf文件中。 注意:GCE(Google的云服务吧)的防火墙经常切断TCP连接,当一个连接超过10分钟不活动的话。这种情况强烈推荐执行上述命令。

2017年3月11日 · 1 分钟

[翻译]Cassandra经常被问到的问题(二)

9 我可以通过批量提交加速我的大量写入吗? 不,使用批量提交只会带来延迟尖峰,使用异步的INSERT来代替,或者使用真正的“批量载入” 对同一个分区key的批量更新是一个例外,只要一个批量的大小保持在合理范围内,还是有好处的,但是要记住不要任何时候都盲目使用批量。 10、在Red Hat企业版(RHEL)中,节点无法加入到集群中。 查看SELinux是否开启了,把它关掉。 11、我怎么取消订阅apache cassandra邮件列表 发邮件到user-unsubscribe@cassandra.apache.org 12、为什么使用top命令看到cassandra使用了比java虚拟机限制的对内存还要多的内存? cassandra内部使用内存映射文件(mmap). 也就是锁,我们使用操作系统的虚拟内存系统把一定数量的磁盘文件映射到了cassandra进程的地址空间里。这将使用虚拟内存,也就是地址空间,这可以使用一些工具例如top命令发现,不过在64位操作系统中,虚拟地址空间是无限大的,所以你不需要担心这些。 那使用的内存的所代表的意义是什么呢?它是使用brc()或者mmap所实际占用的内存,问题的关键是,对于mmap的文件不一定会永久驻留在内存里。所以这些使用的内存不过是缓存而已,就像系统的IO会使用内核的page缓存一样。 一般的IO和mmap的差别就在于mmap引擎的内存是映射到某个进程上的,所以你用top命令可以看到该进程对应的虚拟内存大小。mmap比IO的一个好处是只要内存里有,你里面就能读到了,不会碰到page fault(读系统page缓存,内核可能需要做semi-context切换?),更多细节参考http://www.varnish-cache.org/trac/wiki/ArchitectNotes 13、种子节点是什么? 种子节点用于节点启动的时候发现整个集群。 如果你配置了你的节点指向几个节点作为种子,那么你集群中的节点会发送相比非种子节点较多的gossip信息到种子节点。换句话说:种子节点相当于gossip网络的集线器,每个节点通过种子节点可以很快知道其他节点的状态。 在一个节点新加入集群的时候,需要指定种子节点用于发现集群中其它节点,当你增加一个新节点到集群中的时候,你需要至少指定一个活着的种子节点可以连接,一旦一个节点加入这个集群,它学习到了其它节点,他在下次启动的时候就不需要种子节点了。 你可以任何时候设置任何一个节点为种子, 对于种子节点没有什么特殊的,只要你把它写入种子列表里,他就是一个种子节点。 种子是无法自启动的(bootstrap)(因为如果一个节点把自己加入了种子列表,那就是说他需要自己传输数据给自己),如果你需要这样,你可以先把这个节点当非种子节点启动,等启动以后再把它加入种子列表里。当然如果你是初始化一个新集群,没有任何数据,那你就不需要担心这个事情了。 提醒以下两点: 为每个Data center都选择大于两个节点作为种子节点 保持你所有节点种子列表是一样的。

2017年2月19日 · 1 分钟

[翻译]Cassandra经常被问到的问题(一)

1、为什么不可以设置listen_address为0.0.0.0(意思是监听所有地址)? Cassandra是一个基于gossip协议的分布式系统,监听地址是用来告诉其它节点来访问的,告诉别的节点说“连接我任何地址都可以”,是一个糟糕的想法,如果集群中不同的节点使用了不同方式的地址,悲剧的事情就要发生了。 如果你不想为你集群中的每个节点单独配置ip(非常可以理解),你可以不配,空着它,Cassandra将会使用InetAddress.getLocalHost()来选择地址,然后只要你或者你的运维团队保证这个是正确的(/etc/hosts/,dns 等等要配置对)。 一个例外是JMX,他默认监听的地址是0.0.0.0(这个是java的bug 6425769) 请看CASSANDRA-256 和 CASSANDRA-43获取这方面更多的细节。 2、cassandra用了哪些端口? 默认Cassandra使用7000作为集群通信端口(如果开启了SSL就是7001端口)。9042端口用于native协议的客户端连接。7199端口用于JMX,9160端口用于废弃的Thrift接口。内部节点通信以及native协议的端口在cassandra配置文件里可以配置。JMX端口可以在cassandra-env.sh配置(通过JVM的参数)。所有端口都是TCP的。 3、当往集群中增加新节点的时候,对于存在的数据发生了什么? 当一个新节点加入到集群,它将会自动连接集群中的其它节点,并且去复制正确的数据到本地,同样的增加、替换、移动、删除节点都是这样的。 4、我删除了数据,但是磁盘使用率没有变化,这是为什么? 写入到cassandra里的数据会被持久化到SSTable文件里,SSTable文件是不可改变的,也就是说当你执行删除的时候,数据不会从文件中被去除掉的。相反,一个标记(也叫tombstone)会被写入用于标记对应记录的新状态。不用担心,当数据和tombstone发生第一次compaction的时候,数据会被删除掉,相应的磁盘空间也被回收,你可以了解关于Compaction的更多细节。 5、为什么用nodetool ring只能看到一条记录? 即便所有节点输出的日志里可以看出,他们都发现彼此加入到了这个ring。 这个发生于你的所有节点都配了通用的token,不要这么做。 这经常发生于哪些使用VM部署cassandra的用户,(特别是使用Debian package,它会在安装完自动启动cassandra,所以会生成token并保存它。),安装好后就把VM整个克隆出另外的节点。 增很容易修复,只要把数据目录以及commitlog目录删除,然后保证每个节点是随机生成的token,再启动就可以了。 6、我可以修改一个正在运行中的集群中的keyspace的副本因子吗? 可以,但是修改后需要执行repair或者cleanup来改变已存数据的副本个数。 首先使用cqlsh修改目标keyspace的副本因子。 如果你是减少副本因子,你可以执行nodetool cleanup去删除多余的副本数据,对每个节点都要执行。 如果你是增加副本因子,你需要执行nodetool repair来保证数据的副本个数满足当前的配置。 Repair只要对每个副本集执行一次即可。这是个敏感的操作,这会影响集群的性能。强烈建议执行rolling repair,因为试图一次修复整个集群的话,那可能是个坑。 7 可以使用cassandra存储大的二进制字段吗? Cassandra并没有对存储大文件或者二进制,以及这样一个二进制数据被经常读,也就是整个发送到客户端的情况进行优化。因为存储小的二进制数据(小于1MB)应该不是问题。但是还是建议把大的二进制数据分隔成小块。 需要特别注意的是,任何大于16MB的值,将被Cassandra拒绝掉,这是由max_mutation_size_in_kb配置项决定的(这个配置项默认是commitlog_segment_size_in_mb的一半,commitlog_segment_size_in_mb默认是32M)。 8、Nodetool连接远程服务器的时候,提示“Connection refused to host: 127.0.1.1” ,这是为什么? nodetool依赖JMX,JMX依赖RMI。RMI在两端通信的时候会根据需要创建自己的listenners和connectors。通常,这些都是底层透明的,但是不正确的hostname解析,无论是在连接方还是被连接方,都会导致错乱和这样的拒绝异常。 如果你在使用DNS。确保两端机器的/etc/hosts文件是正确的。如果还是失败的,你可以尝试通过jvm选项-Djava.rmi.server.hostname=指定你要连接的远程机器名称给JMX接口,配置项大体在cassandra-env.sh文件的靠下的位置。

2016年12月3日 · 1 分钟

[翻译]有关cassandra的存储引擎

Cassandra使用一个类似于日志结构的结合树(Log-Structured Merge Tree)的存储结构,不像传统关系数据库那样使用B-Tree。 Cassandra会避免在写之前去读。 “写前读”(Read-before-write), 特别是在一个大的分布式系统里,会对读性能产生影响,还会带来其它问题,比如,两个客户端同时去读,其中一个去更新该行的A列,另外一个去更新该行的B列,就可能把对A列的更新覆盖掉。“写前读”,也会破坏cache,增加IO。 为了避免“写前读”的情况,cassandra的存储引擎会对即将要进行的插入、更新进行整理,只会按顺序,以追加的模式仅写入这一行更新的部分。 。 一个日志模式的存储引擎,为了避免数据相互覆盖,使用顺序IO去更新数据写入普通硬盘HDD或者固态硬盘SSD是必须的。 在HDD中,随机写比顺序写会导致大量的寻址操作,这个寻址操作的危害是相当大的。使用顺序IO,从而避免更多写入被放大和磁盘故障,Cassandra特别适合廉价的、大众消费的SSD。

2016年5月2日 · 1 分钟

[翻译]Cassandra的写过程

Cassandra的写操作包含几个过程。从开始实时写日志到最后进行压缩。 1、把数据写入commit log 2、数据写入内存表memtable 3、从memtable中刷新 4、存储到磁盘中的sstables里 5、压缩 写日志和memtable存储 当有一个写入发生,cassandra会把数据存到内存里叫memtable的数据结构里,也会写到磁盘的commitlog里,提供持久化存储。commitlog接受每个请求,并且持久化保存,甚至是断电。memtable是一种回写cache,cassandra通过key可以在memtbale里查询数据。memtable的大小是有限制的,当到达一个限制就会被刷新。 从memtable刷新数据。 当memtable的内存超过了配置的阈值,memtable里的数据包括索引,就会进入一个刷新到磁盘的队列里。你可以通过修改cassandra.yaml里的 memtable_heap_space_in_mb配置项来控制这个队列的大小。当要刷新的数据超过了队列大小,cassandra就会阻止写入直到下一个刷新成功。你可以使用nodetool flush 手动触发一个刷新,通常在重启节点之前,建议刷新一次memtable,这样可以减少重放commitlog的时间。为了刷新数据cassandra会吧memetables根据token排序,然后顺序写到磁盘上。 磁盘上数据存储到sstables中 对于在commitlog里的数据,当在memtable里的对应的数据被刷新到一个sstable中之后会被清除。 Memtables和SStables都是分表存储的,SStables是不可以改变的,当从memtbale中刷新到磁盘上后就不会再写入。因此一个分区可以通常会保存到多个sstable文件中。对于每个sstable,cassandra会创建如下结构化数据: 1、分区key索引:一个分区key的列表和对应的在data文件中的起始位置。 2、分区key汇总(在内存里):一个分区key索引的抽样 3、布隆过滤器 压缩 周期性的压缩是cassandra作为一个健康数据库所必须的,因为cassandra不会把数据插入或者更新到具体的位置。当插入或者更新发生了,并不会去覆盖原来的数据,而是重新写入一个新的时间戳版本的数据到另外一个sstable中。cassandra管理在磁盘上不断累积的sstable,就是使用压缩。 cassandra也不会去实际删除数据,因为sstable是不可以修改的。而是用墓碑的方式标记数据被删除了,墓碑存在一个可配置的周期,是表的一个参数 gc_grace_seconds。 在压缩的过程中,会有一个磁盘使用空间以及IO的临时飙升,因为老的和新的sstable会并存,这个图描述了压缩的过程: 压缩会根据分区key合并多个sstable中的数据,选择具有最新时间戳的进行存储。Cassandra可以高性能的合并数据,而不会产生随机IO,因为在sstable里的row都是根据分区key排序存储的。在删除了墓碑和要删除的数据,列和行数据后,压缩的过程会把这些sstable压缩成一个文件。老的sstable文件会在堆积到该文件上的查询请求结束后尽快的删除。这样老的sstable占用的磁盘空间又可以重复使用了。 cassandra2.1改进了压缩后的读性能,通过一种增量式的替换压缩过的sstables。而不是等到整个压缩完才去删除老的sstable。cassandra可以直接从新的sstable中读取,甚至在它完成写入之前。 当数据写到新的sstable,读请求就会访问新的sstable,在老的sstable中相应的数据不会再被访问,并且从系统的page cache中剔除掉。因此当缓存新的sstable的增量过程开始的时候,读取就不会从老的读,相应的cache也会消失。因此可以预见cassandra提供了一种高的性能甚至是在高负载下。 原文地址:https://docs.datastax.com/en/cassandra/2.1/cassandra/dml/dml_write_path_c.html

2016年4月24日 · 1 分钟

Cassandra解决单个磁盘损坏的情况

Cassandra一个节点的磁盘坏了,分两种情况,一种是节点还可以正常启动。另外一种是节点无法启动。 第一种情况:节点还可以正常启动 1、把坏的盘换掉,如果你没有新的盘去更换,你可以在cassandra.yaml里直接把坏的盘注释掉 2、启动cassandra,如果启动的过程中报错,说找不到keyspace之类的,那你应该使用第二种情况的解决方案。 3、使用nodetool repair修复该节点丢失的数据。 第二种情况:节点无法正常启动 1、把坏的盘换掉,如果你没有新的盘去更换,你可以在cassandra.yaml里直接把坏的盘注释掉 2、在正常的节点上执行: $ nodetool ring | grep ip_address_of_node | awk ’ {print $NF “,”}’ | xargs 从而获取到坏掉节点的tokens,把它们(用逗号分割)配置到cassandra.yaml的initial_token 选项中。 3、在cassandra.yaml设置配置项: auto_bootstrap: false 这一步官方文档漏掉了,参考 https://issues.apache.org/jira/browse/CASSANDRA-11365 4、删除你所有数据盘下面的system目录。 rm -fr /mnt1/cassandra/data/system rm -fr /mnt2/cassandra/data/system 。。。。 5、启动cassandra,如果启动的过程中报错,说schema不存在之类的属于正常情况,system库会自动重建,只要节点可以正常加入集群就算正常。 6、同样使用nodetool repair修复该节点丢失的数据。

2016年3月26日 · 1 分钟

elasticsearch如何安全重启节点(续)

之前分享的一篇文章介绍了如何滚动rolling重启elasticsearch集群。但是当数据量很大的时候,可能那种方式并不适合修改整个集群的配置。 如果你无法通过api更改集群属性,还是建议你把整个集群关闭,重启整个集群。 重启步骤如下: 1、关闭整个集群 curl -XPOST ‘http://IP:9200/_cluster/nodes/_shutdown’ 2、修改你要修改的配置项,或者是升级elasticsearch版本。 3、修改每个节点配置文件: 配置: gateway.expected_nodes: 10 gateway.recover_after_time: 5m gateway.recover_after_nodes: 8 minimum_master_nodes: 2 以上参考:http://zhaoyanblog.com/archives/745.html 配置:bootstrap.mlockall: true 以上参考:http://zhaoyanblog.com/archives/826.html 4、线启动master节点,再依次启动所有的其它节点。 5、查看集群状态,直到所有节点加入集群,变为green状态 curl ‘http://ip:9200/_cluster/health?pretty=true’ 这 因为第三步的配置,这个过程会很快,即便数据量大,顶多几分钟的事情。

2015年9月21日 · 1 分钟

Cassandra双中心节点要配置keepalive

在低流量的间隔,防火墙的设置会把长时间闲置的链接关闭,导致本地节点和其它datacenter的节点之间失去联系。链接闲置超时时间一般被网络管理员设置为60分钟。 所以Cassandra在创建双中心的时候,中间传输数据会经常超时,如果你不设置系统的keepalive的话。 配置系统的keepalive,首先通过 sysctl -A | grep net.ipv4 查看系统内核参数: net.ipv4.tcp_keepalive_time:链接闲置多久之后开始探测链接(秒),也可以理解为keepalive发送第一个请求的间隔时间。 net.ipv4.tcp_keepalive_probes:链接发送探测请求多少次之后认为链接失效 net.ipv4.tcp_keepalive_intvl:每次发送探测请求中间间隔多久(秒) 你可以使用以下命令临时更改系统内核参数(重启失效) sysctl -w net.ipv4.tcp_keepalive_time=60 net.ipv4.tcp_keepalive_probes=3 net.ipv4.tcp_keepalive_intvl=10 也可以编辑/etc/sysctl.conf 文件之后,使用sysctl -p 命令让配置永久生效。 这个命令把keepalive的超时时间设为了60秒,间隔10秒探测3次。这个设置可以在90s(60+10+10+10)后探测到死链接。这里不需要会产生担心额外的流量,因为这点流量是我不足道的,而且你长期保持这样的设置也应该不是问题。 参考:http://docs.datastax.com/en/cassandra/2.1/cassandra/troubleshooting/trblshootIdleFirewall.html

2015年9月16日 · 1 分钟

Elasticsearch的Best Practice:把bootstrap.mlockall设为true

elasticsearch中java的最小内存和最大内存,官方建议设置为一样的,这样可以由于内存调整造成的长GC发生。 当然内存大小不要超过32G, 参考http://zhaoyanblog.com/archives/744.html 其次elasticsearch还有一个重要的参数bootstrap.mlockall,这个参数的目的是当你无法关闭系统的swap的时候,建议把这个参数设为true。防止在内存不够用的时候,elasticsearch的内存被交换至交换区,导致性能骤降。 参考http://zhaoyanblog.com/archives/744.html 建议即便你关闭了系统的swap,也把bootstrap.mlockall设为true bootstrap.mlockall的作用就是在程序启动的时候先去获取足够大的内存,再加入集群接收请求。没有bootstrap.mlockall的话,elasticsearch一启动就会发现集群接入集群,接收请求,然后JVM一点点的获取系统内存,直到指定值。 如果你有足够大的内存还好,如果没有足够大的内存,因为了elasticsearch引用文件会,系统内存会大量用于系统cache(linux的内存管理机制)。 从程序启动直到JVM获取到指定大小的内存,可能由于系统cache释放缓慢,而导致这个过程非常长,这有可能使你的节点GC非常频繁,从而导致集群不稳定。 所以强烈建议把bootstrap.mlockall设为true,这个值设为true,可能会让节点启动的时候比较慢,但是保证了节点加入集群后的稳定性。

2015年9月12日 · 1 分钟

怎么设置nodetool使用用户名密码访问

cassandra的nodetool工具使用jdk的jmx和cassandra节点通信。 nodetool是集群的重要管理工具。 在cassandra2.0版本中,nodetool默认是允许远程访问,其不需要密码的。 在cassandra2.1版本中,nodetool默认是只允许本机访问,很不方便, 如果远程访问功能打开,又不安全,防止别人乱操作,好方法就是加上访问权限控制。 第一步:打开远程访问权限 编辑conf/cassandra-env.sh文件。 找到: LOCAL_JMX=yes 默认值监听localhost,只允许本机访问。 改为 LOCAL_JMX=no 表示远程也可以访问。 第二步:指定密码文件 同一文件,找到如下配置项: JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.authenticate=true" JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.password.file=/home/cassandra/jmxremote.password" 第三步:创建密码文件 vi /home/cassandra/jmxremote.password 输入 myusername mypassword 注意:修改文件权限只能本用户访问: chmod go-rwx /home/cassandra/jmxremote.password 否则启动的时候会报错 Error: Password file read access must be restricted: /home/cassandra/jmxremote.password 第四步:配置access文件 access权限控制权限,默认使用jdk目录下的: $JAVA_HOME/jre/lib/management/jmxremote.access 写入myusername有读写权限 myusername readwrite 该文件也可以通过-Dcom.sun.management.jmxremote.access.file选项指定。 重启cassandra之后,你需要这样使用nodetool: bin/nodetool -u myusername -pw mypassword status

2015年8月30日 · 1 分钟

从Cassandra 2.0升级到Cassandra 2.1

Cassandra 2.1相比于Cassandra2.0有很多性能提升以及bug修正。 有一点是我特别在意的是: Cassandra 2.1支持增量repair。使用Cassandra2.0的时候,repair整个周期每次都需要很长时间。 此外Cassandra 2.1 发展到2.1.9版,已经经历多个版本,日臻稳定,目前官方已经着手开发2.2.0版本。 根据官方建议,最好1年升级一次版本,防止和最新的版本跨度太大,难以升级到最新版本,所以是时候升级到2.1版本了。 下载最新的Cassandra2.1.9进行升级。 注意: 1、官方注明升级到2.1.x版本,你的当前版本必须是2.0.7之后的版本,否则是无法升级的。 2、你的客户端兼容新版本。 第一步:更改配置文件 把Cassandra 2.0的配置通过比对, 把你原来cassandra.yaml配置文件里的参数移植到新版本的cassandra.yaml配置文件中。 因为cassandra2.1增加了一些配置,也减少了一些配置。所以你不能直接复制过来。你只要把新版的配置文件中有的配置项,从老的配置文件中挪过来就可以了。 第二步:创建快照,防止升级失败 nodetool snapshot keyspace -t snapshot_20150828 创建快照。 如果你使用了JNA,快照是通过硬链接实现的,并不会增加磁盘空间,创建快照时间很短。 第三步:停节点 先执行bin/nodetool drain 关闭写入,同时把数据写入文件。 执行bin/nodetool stodaemon停掉本节点。 第四步: 启动新节点 bin/cassandra。 第五步:重复一到四步把集群所有机器都升级为新版本。 第六步:在所有节点执行升级sstable文件操作 后台执行 nohup bin/nodetool upgradesstables & 目前看,这个操作不会产生太大的负载 等所有节点操作完毕,至此升级完毕。

2015年8月28日 · 1 分钟

给cassandra提的一个问题单又被接受了

cassandra2.1版终于出了稳定版-cassandra2.1.6版。照例把之前的功能在新版本上跑一跑。但是仍然遇到一个问题: 创建一个表 CREATE TABLE test ( a int, b int, c int, d int, PRIMARY KEY (a, b, c) ); 根据a=1 and b<6查询结果是: select * from test where a=1 and b<6; a | b | c | d —+—+—+— 1 | 3 | 1 | 2 1 | 3 | 2 | 2 1 | 3 | 4 | 2 1 | 3 | 5 | 2 1 | 4 | 4 | 2 1 | 5 | 5 | 2 ...

2015年7月2日 · 2 分钟

cassandra多个数据中心实现异地容灾

cassandra是集群部署,多个节点,多个数据备份,一两个节点挂掉,一般不会有数据丢失。只要删除当掉的节点,对其它节点进行repair,数据都会自动均衡到完整的份数。 但是如果大面积节点掉电,或者机房着火那就肯定要丢失数据了,使用cassandra作为数据存储的业务,肯定是很大的业务,数据量超大的那种。机房容灾肯定是必不可少的。 cassandra提供多种多数据中心部署、机架敏感策略。这里介绍一种最普通的一种: GossipingPropertyFileSnitch GossipingPropertyFileSnitch策略支持简单的多个数据中心,和多机架。 第一步: 在cassandra.yaml配置文件中指定集群支持该策略: endpoint_snitch: GossipingPropertyFileSnitch 第二步: 在cassandra.yaml的seeds中把两个数据中心的种子节点都配上 seeds: “192.168.22.101,192.168.22.102,192.168.23.101,192.168.23.102” 第三步: 配置cassandra-rackdc.properties 每台机器都配置自己所属的数据中心名称和机架名称 dc=DC1 rack=RAC1 配置机架的目的是,防止整个机框掉电,数据丢失。cassandra可以尽量保证同一份数据的多个副本不存在于同一个机架上。 这就要求你的机架个数要大约等于你的数据副本个数,同时每个机架的节点个数尽量相同,否则会导致某些节点数据偏多,分布不均 第四步 创建keyspace使用NetworkTopologyStrategy策略,并且制定每个集群的份数。 CREATE KEYSPACE mykeyspace WITH replication = { ‘class’: ‘NetworkTopologyStrategy’, ‘DC1’: ‘3’, ‘DC2’: ‘3’ }; 第五步 客户端使用数据一致性策略,从QUORUM改为LOCAL_QUORUM。这样客户端会先从LOCAL数据中查询,LOCAL无法查询,再从REMOTE数据中心进行查询。 cassandra JAVA官方驱动,把默认首先连上的节点所属的数据中心视为LOCAL数据中心。所以你不要容灾数据中心节点IP配到了代码中。

2015年6月21日 · 1 分钟